summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Analysis/InstructionSimplify.h7
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp29
-rw-r--r--llvm/test/Transforms/EarlyCSE/AArch64/intrinsics.ll2
-rw-r--r--llvm/test/Transforms/GVN/pr14166.ll4
-rw-r--r--llvm/test/Transforms/InstSimplify/cast.ll27
5 files changed, 65 insertions, 4 deletions
diff --git a/llvm/include/llvm/Analysis/InstructionSimplify.h b/llvm/include/llvm/Analysis/InstructionSimplify.h
index 410fa4165a9..06d7d80da07 100644
--- a/llvm/include/llvm/Analysis/InstructionSimplify.h
+++ b/llvm/include/llvm/Analysis/InstructionSimplify.h
@@ -245,6 +245,13 @@ namespace llvm {
AssumptionCache *AC = nullptr,
const Instruction *CxtI = nullptr);
+ /// Given operands for an BitCastInst, fold the result or return null.
+ Value *SimplifyBitCastInst(Value *Op, Type *Ty, const DataLayout &DL,
+ const TargetLibraryInfo *TLI = nullptr,
+ const DominatorTree *DT = nullptr,
+ AssumptionCache *AC = nullptr,
+ const Instruction *CxtI = nullptr);
+
//=== Helper functions for higher up the class hierarchy.
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 981fb976c02..8fde9c7281d 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -70,6 +70,7 @@ static Value *SimplifyCmpInst(unsigned, Value *, Value *, const Query &,
static Value *SimplifyOrInst(Value *, Value *, const Query &, unsigned);
static Value *SimplifyXorInst(Value *, Value *, const Query &, unsigned);
static Value *SimplifyTruncInst(Value *, Type *, const Query &, unsigned);
+static Value *SimplifyBitCastInst(Value *, Type *, const Query &, unsigned);
/// For a boolean type, or a vector of boolean type, return false, or
/// a vector with every element false, as appropriate for the type.
@@ -3810,6 +3811,30 @@ Value *llvm::SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout &DL,
RecursionLimit);
}
+static Value *SimplifyBitCastInst(Value *Op, Type *Ty, const Query &Q, unsigned) {
+ if (auto *C = dyn_cast<Constant>(Op))
+ return ConstantFoldCastOperand(Instruction::BitCast, C, Ty, Q.DL);
+
+ // bitcast x -> x
+ if (Op->getType() == Ty)
+ return Op;
+
+ // bitcast(bitcast x) -> x
+ if (auto *BC = dyn_cast<BitCastInst>(Op))
+ if (BC->getOperand(0)->getType() == Ty)
+ return BC->getOperand(0);
+
+ return nullptr;
+}
+
+Value *llvm::SimplifyBitCastInst(Value *Op, Type *Ty, const DataLayout &DL,
+ const TargetLibraryInfo *TLI,
+ const DominatorTree *DT, AssumptionCache *AC,
+ const Instruction *CxtI) {
+ return ::SimplifyBitCastInst(Op, Ty, Query(DL, TLI, DT, AC, CxtI),
+ RecursionLimit);
+}
+
//=== Helper functions for higher up the class hierarchy.
/// Given operands for a BinaryOperator, see if we can fold the result.
@@ -4280,6 +4305,10 @@ Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout &DL,
Result =
SimplifyTruncInst(I->getOperand(0), I->getType(), DL, TLI, DT, AC, I);
break;
+ case Instruction::BitCast:
+ Result =
+ SimplifyBitCastInst(I->getOperand(0), I->getType(), DL, TLI, DT, AC, I);
+ break;
}
// In general, it is possible for computeKnownBits to determine all bits in a
diff --git a/llvm/test/Transforms/EarlyCSE/AArch64/intrinsics.ll b/llvm/test/Transforms/EarlyCSE/AArch64/intrinsics.ll
index d166ff1e109..a75a6dc2107 100644
--- a/llvm/test/Transforms/EarlyCSE/AArch64/intrinsics.ll
+++ b/llvm/test/Transforms/EarlyCSE/AArch64/intrinsics.ll
@@ -40,7 +40,7 @@ entry:
; Check that the first @llvm.aarch64.neon.st2 is optimized away by Early CSE.
; CHECK-LABEL: @test_cse2
; CHECK-NOT: call void @llvm.aarch64.neon.st2.v4i32.p0i8(<4 x i32> %3, <4 x i32> %3, i8* %0)
-; CHECK: call void @llvm.aarch64.neon.st2.v4i32.p0i8(<4 x i32> %3, <4 x i32> %4, i8* %0)
+; CHECK: call void @llvm.aarch64.neon.st2.v4i32.p0i8(<4 x i32> %s.coerce.fca.0.extract, <4 x i32> %s.coerce.fca.1.extract, i8* %0)
%s.coerce.fca.0.extract = extractvalue [2 x <4 x i32>] %s.coerce, 0
%s.coerce.fca.1.extract = extractvalue [2 x <4 x i32>] %s.coerce, 1
br label %for.cond
diff --git a/llvm/test/Transforms/GVN/pr14166.ll b/llvm/test/Transforms/GVN/pr14166.ll
index ec1b1717f06..2e77496a2e4 100644
--- a/llvm/test/Transforms/GVN/pr14166.ll
+++ b/llvm/test/Transforms/GVN/pr14166.ll
@@ -18,9 +18,7 @@ define <2 x i32> @test1() {
; CHECK: %v4 = bitcast <2 x i32>* %v1 to <2 x i8*>*
; CHECK: store <2 x i8*> %v3, <2 x i8*>* %v4
; CHECK: %1 = ptrtoint <2 x i8*> %v3 to <2 x i32>
-; CHECK: %2 = bitcast <2 x i32> %1 to i64
-; CHECK: %3 = bitcast i64 %2 to <2 x i32>
-; CHECK: ret <2 x i32> %3
+; CHECK: ret <2 x i32> %1
}
declare void @anything(<2 x i32>*)
diff --git a/llvm/test/Transforms/InstSimplify/cast.ll b/llvm/test/Transforms/InstSimplify/cast.ll
new file mode 100644
index 00000000000..a656854478d
--- /dev/null
+++ b/llvm/test/Transforms/InstSimplify/cast.ll
@@ -0,0 +1,27 @@
+; RUN: opt -S -instsimplify < %s | FileCheck %s
+
+define i1 @test1(i1 %V) {
+entry:
+ %Z = zext i1 %V to i32
+ %T = trunc i32 %Z to i1
+ ret i1 %T
+; CHECK-LABEL: define i1 @test1(
+; CHECK: ret i1 %V
+}
+
+define i8* @test2(i8* %V) {
+entry:
+ %BC1 = bitcast i8* %V to i32*
+ %BC2 = bitcast i32* %BC1 to i8*
+ ret i8* %BC2
+; CHECK-LABEL: define i8* @test2(
+; CHECK: ret i8* %V
+}
+
+define i8* @test3(i8* %V) {
+entry:
+ %BC = bitcast i8* %V to i8*
+ ret i8* %BC
+; CHECK-LABEL: define i8* @test3(
+; CHECK: ret i8* %V
+}
OpenPOWER on IntegriCloud