From 00139e51c90d3592b2fcbae0418ea4fef736e2b3 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Tue, 12 Aug 2014 19:46:13 +0000 Subject: [PATCH] Allwo bitcast + struct GEP transform to work with addrspacecast git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215467 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstructionCombining.cpp | 23 ++++++++++++++++--- test/Transforms/InstCombine/cast.ll | 18 +++++++++++++++ test/Transforms/InstCombine/getelementptr.ll | 10 ++++++++ 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp index d3648e2d050..e079eee7d2c 100644 --- a/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1667,6 +1667,18 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { if (!DL) return nullptr; + // addrspacecast between types is canonicalized as a bitcast, then an + // addrspacecast. To take advantage of the below bitcast + struct GEP, look + // through the addrspacecast. + if (AddrSpaceCastInst *ASC = dyn_cast(PtrOp)) { + // X = bitcast A addrspace(1)* to B addrspace(1)* + // Y = addrspacecast A addrspace(1)* to B addrspace(2)* + // Z = gep Y, <...constant indices...> + // Into an addrspacecasted GEP of the struct. + if (BitCastInst *BC = dyn_cast(ASC->getOperand(0))) + PtrOp = BC; + } + /// See if we can simplify: /// X = bitcast A* to B* /// Y = gep X, <...constant indices...> @@ -1675,11 +1687,10 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { if (BitCastInst *BCI = dyn_cast(PtrOp)) { Value *Operand = BCI->getOperand(0); PointerType *OpType = cast(Operand->getType()); - unsigned OffsetBits = DL->getPointerTypeSizeInBits(OpType); + unsigned OffsetBits = DL->getPointerTypeSizeInBits(GEP.getType()); APInt Offset(OffsetBits, 0); if (!isa(Operand) && - GEP.accumulateConstantOffset(*DL, Offset) && - StrippedPtrTy->getAddressSpace() == GEP.getPointerAddressSpace()) { + GEP.accumulateConstantOffset(*DL, Offset)) { // If this GEP instruction doesn't move the pointer, just replace the GEP // with a bitcast of the real input to the dest type. @@ -1697,6 +1708,9 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { return &GEP; } } + + if (Operand->getType()->getPointerAddressSpace() != GEP.getAddressSpace()) + return new AddrSpaceCastInst(Operand, GEP.getType()); return new BitCastInst(Operand, GEP.getType()); } @@ -1712,6 +1726,9 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { if (NGEP->getType() == GEP.getType()) return ReplaceInstUsesWith(GEP, NGEP); NGEP->takeName(&GEP); + + if (NGEP->getType()->getPointerAddressSpace() != GEP.getAddressSpace()) + return new AddrSpaceCastInst(NGEP, GEP.getType()); return new BitCastInst(NGEP, GEP.getType()); } } diff --git a/test/Transforms/InstCombine/cast.ll b/test/Transforms/InstCombine/cast.ll index 0cbfbb071bb..86e9f3f5335 100644 --- a/test/Transforms/InstCombine/cast.ll +++ b/test/Transforms/InstCombine/cast.ll @@ -354,6 +354,24 @@ define i32* @test41(i32* %tmp1) { ; CHECK: ret i32* %tmp1 } +define i32 addrspace(1)* @test41_addrspacecast_smaller(i32* %tmp1) { + %tmp64 = addrspacecast i32* %tmp1 to { i32 } addrspace(1)* + %tmp65 = getelementptr { i32 } addrspace(1)* %tmp64, i32 0, i32 0 + ret i32 addrspace(1)* %tmp65 +; CHECK-LABEL: @test41_addrspacecast_smaller( +; CHECK: addrspacecast i32* %tmp1 to i32 addrspace(1)* +; CHECK-NEXT: ret i32 addrspace(1)* +} + +define i32* @test41_addrspacecast_larger(i32 addrspace(1)* %tmp1) { + %tmp64 = addrspacecast i32 addrspace(1)* %tmp1 to { i32 }* + %tmp65 = getelementptr { i32 }* %tmp64, i32 0, i32 0 + ret i32* %tmp65 +; CHECK-LABEL: @test41_addrspacecast_larger( +; CHECK: addrspacecast i32 addrspace(1)* %tmp1 to i32* +; CHECK-NEXT: ret i32* +} + define i32 @test42(i32 %X) { %Y = trunc i32 %X to i8 ; [#uses=1] %Z = zext i8 %Y to i32 ; [#uses=1] diff --git a/test/Transforms/InstCombine/getelementptr.ll b/test/Transforms/InstCombine/getelementptr.ll index 3240c6d2a4d..da91ada0805 100644 --- a/test/Transforms/InstCombine/getelementptr.ll +++ b/test/Transforms/InstCombine/getelementptr.ll @@ -580,6 +580,16 @@ define i32 addrspace(1)* @test33_array_struct_as1([10 x %struct.Key] addrspace(1 ret i32 addrspace(1)* %C } +define i32 addrspace(1)* @test33_addrspacecast(%struct.Key* %A) { +; CHECK-LABEL: @test33_addrspacecast( +; CHECK: %C = getelementptr %struct.Key* %A, i64 0, i32 0, i32 1 +; CHECK-NEXT: addrspacecast i32* %C to i32 addrspace(1)* +; CHECK-NEXT: ret + %B = addrspacecast %struct.Key* %A to %struct.anon addrspace(1)* + %C = getelementptr %struct.anon addrspace(1)* %B, i32 0, i32 2 + ret i32 addrspace(1)* %C +} + %T2 = type { i8*, i8 } define i8* @test34(i8* %Val, i64 %V) nounwind { entry: -- 2.34.1