summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-08-30 20:38:21 +0000
committerChris Lattner <sabre@nondot.org>2009-08-30 20:38:21 +0000
commit73913f4cd3e86275e5b6cf55a1c8ed3c38c71516 (patch)
tree2b4990781a042af3d6eed7bf88e738e685163122
parentc2f2cf896e3c5ca269eaf0621965d6e3378cc625 (diff)
downloadbcm5719-llvm-73913f4cd3e86275e5b6cf55a1c8ed3c38c71516.tar.gz
bcm5719-llvm-73913f4cd3e86275e5b6cf55a1c8ed3c38c71516.zip
Fix PR4748: don't fold gep(bitcast(x)) into bitcast(gep) when x
is itself a bitcast. Since we have gep(bitcast(bitcast(y))) in this case, just wait for the two bitcasts to get zapped. This prevents instcombine from confusing some aliasing stuff, and allows it to directly eliminate the load in the testcase. llvm-svn: 80508
-rw-r--r--llvm/lib/Transforms/Scalar/InstructionCombining.cpp7
-rw-r--r--llvm/test/Transforms/InstCombine/getelementptr-2.ll21
2 files changed, 28 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
index a02aa5dff8b..1bfce5dfcbd 100644
--- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -10896,6 +10896,13 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
if (Value *X = getBitCastOperand(PtrOp)) {
assert(isa<PointerType>(X->getType()) && "Must be cast from pointer");
+ // If the input bitcast is actually "bitcast(bitcast(x))", then we don't
+ // want to change the gep until the bitcasts are eliminated.
+ if (getBitCastOperand(X)) {
+ Worklist.AddValue(PtrOp);
+ return 0;
+ }
+
// Transform: GEP (bitcast [10 x i8]* X to [0 x i8]*), i32 0, ...
// into : GEP [10 x i8]* X, i32 0, ...
//
diff --git a/llvm/test/Transforms/InstCombine/getelementptr-2.ll b/llvm/test/Transforms/InstCombine/getelementptr-2.ll
new file mode 100644
index 00000000000..4cffbcd4bcd
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/getelementptr-2.ll
@@ -0,0 +1,21 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep load
+; PR4748
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i386-apple-darwin9"
+ %struct.B = type { double }
+ %struct.A = type { %struct.B, i32, i32 }
+
+define i32 @_Z4funcv(%struct.A* %a) {
+entry:
+ %g3 = getelementptr %struct.A* %a, i32 0, i32 1
+ store i32 10, i32* %g3, align 4
+
+ %g4 = getelementptr %struct.A* %a, i32 0, i32 0
+
+ %new_a = bitcast %struct.B* %g4 to %struct.A*
+
+ %g5 = getelementptr %struct.A* %new_a, i32 0, i32 1
+ %a_a = load i32* %g5, align 4
+ ret i32 %a_a
+}
+
OpenPOWER on IntegriCloud