[llvm] r215467 - Allwo bitcast + struct GEP transform to work with addrspacecast
Matt Arsenault
Matthew.Arsenault at amd.com
Tue Aug 12 12:46:14 PDT 2014
Author: arsenm
Date: Tue Aug 12 14:46:13 2014
New Revision: 215467
URL: http://llvm.org/viewvc/llvm-project?rev=215467&view=rev
Log:
Allwo bitcast + struct GEP transform to work with addrspacecast
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/trunk/test/Transforms/InstCombine/cast.ll
llvm/trunk/test/Transforms/InstCombine/getelementptr.ll
Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=215467&r1=215466&r2=215467&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Tue Aug 12 14:46:13 2014
@@ -1667,6 +1667,18 @@ Instruction *InstCombiner::visitGetEleme
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<AddrSpaceCastInst>(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<BitCastInst>(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::visitGetEleme
if (BitCastInst *BCI = dyn_cast<BitCastInst>(PtrOp)) {
Value *Operand = BCI->getOperand(0);
PointerType *OpType = cast<PointerType>(Operand->getType());
- unsigned OffsetBits = DL->getPointerTypeSizeInBits(OpType);
+ unsigned OffsetBits = DL->getPointerTypeSizeInBits(GEP.getType());
APInt Offset(OffsetBits, 0);
if (!isa<BitCastInst>(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::visitGetEleme
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::visitGetEleme
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());
}
}
Modified: llvm/trunk/test/Transforms/InstCombine/cast.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/cast.ll?rev=215467&r1=215466&r2=215467&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/cast.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/cast.ll Tue Aug 12 14:46:13 2014
@@ -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 ; <i8> [#uses=1]
%Z = zext i8 %Y to i32 ; <i32> [#uses=1]
Modified: llvm/trunk/test/Transforms/InstCombine/getelementptr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/getelementptr.ll?rev=215467&r1=215466&r2=215467&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/getelementptr.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/getelementptr.ll Tue Aug 12 14:46:13 2014
@@ -580,6 +580,16 @@ define i32 addrspace(1)* @test33_array_s
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:
More information about the llvm-commits
mailing list