mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-24 21:14:56 +00:00
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
This commit is contained in:
parent
3c57820bbb
commit
00139e51c9
@ -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<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::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
||||
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::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());
|
||||
}
|
||||
}
|
||||
|
@ -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]
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user