From 2de2319124a74b2afff8a0cb1a272dc00b98e273 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 30 Aug 2009 20:38:21 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80508 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/InstructionCombining.cpp | 7 +++++++ .../Transforms/InstCombine/getelementptr-2.ll | 21 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 test/Transforms/InstCombine/getelementptr-2.ll diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index a02aa5dff8b..1bfce5dfcbd 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -10896,6 +10896,13 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { if (Value *X = getBitCastOperand(PtrOp)) { assert(isa(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/test/Transforms/InstCombine/getelementptr-2.ll b/test/Transforms/InstCombine/getelementptr-2.ll new file mode 100644 index 00000000000..4cffbcd4bcd --- /dev/null +++ b/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 +} + -- 2.34.1