Do more addrspacecast transforms that happen for bitcast.

Makes addrspacecast (gep) do addrspacecast (gep) instead.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201376 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Matt Arsenault 2014-02-14 00:49:12 +00:00
parent 0f2e653317
commit f222ebe86c
3 changed files with 82 additions and 8 deletions

View File

@ -1220,9 +1220,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
if (!StrippedPtrTy) if (!StrippedPtrTy)
return 0; return 0;
if (StrippedPtr != PtrOp && if (StrippedPtr != PtrOp) {
StrippedPtrTy->getAddressSpace() == GEP.getPointerAddressSpace()) {
bool HasZeroPointerIndex = false; bool HasZeroPointerIndex = false;
if (ConstantInt *C = dyn_cast<ConstantInt>(GEP.getOperand(1))) if (ConstantInt *C = dyn_cast<ConstantInt>(GEP.getOperand(1)))
HasZeroPointerIndex = C->isZero(); HasZeroPointerIndex = C->isZero();
@ -1276,8 +1274,11 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
Value *NewGEP = GEP.isInBounds() ? Value *NewGEP = GEP.isInBounds() ?
Builder->CreateInBoundsGEP(StrippedPtr, Idx, GEP.getName()) : Builder->CreateInBoundsGEP(StrippedPtr, Idx, GEP.getName()) :
Builder->CreateGEP(StrippedPtr, Idx, GEP.getName()); Builder->CreateGEP(StrippedPtr, Idx, GEP.getName());
// V and GEP are both pointer types --> BitCast // V and GEP are both pointer types --> BitCast
if (StrippedPtrTy->getAddressSpace() == GEP.getPointerAddressSpace())
return new BitCastInst(NewGEP, GEP.getType()); return new BitCastInst(NewGEP, GEP.getType());
return new AddrSpaceCastInst(NewGEP, GEP.getType());
} }
// Transform things like: // Transform things like:
@ -1307,8 +1308,11 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
Value *NewGEP = GEP.isInBounds() && NSW ? Value *NewGEP = GEP.isInBounds() && NSW ?
Builder->CreateInBoundsGEP(StrippedPtr, NewIdx, GEP.getName()) : Builder->CreateInBoundsGEP(StrippedPtr, NewIdx, GEP.getName()) :
Builder->CreateGEP(StrippedPtr, NewIdx, GEP.getName()); Builder->CreateGEP(StrippedPtr, NewIdx, GEP.getName());
// The NewGEP must be pointer typed, so must the old one -> BitCast // The NewGEP must be pointer typed, so must the old one -> BitCast
if (StrippedPtrTy->getAddressSpace() == GEP.getPointerAddressSpace())
return new BitCastInst(NewGEP, GEP.getType()); return new BitCastInst(NewGEP, GEP.getType());
return new AddrSpaceCastInst(NewGEP, GEP.getType());
} }
} }
} }
@ -1348,7 +1352,9 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
Builder->CreateInBoundsGEP(StrippedPtr, Off, GEP.getName()) : Builder->CreateInBoundsGEP(StrippedPtr, Off, GEP.getName()) :
Builder->CreateGEP(StrippedPtr, Off, GEP.getName()); Builder->CreateGEP(StrippedPtr, Off, GEP.getName());
// The NewGEP must be pointer typed, so must the old one -> BitCast // The NewGEP must be pointer typed, so must the old one -> BitCast
if (StrippedPtrTy->getAddressSpace() == GEP.getPointerAddressSpace())
return new BitCastInst(NewGEP, GEP.getType()); return new BitCastInst(NewGEP, GEP.getType());
return new AddrSpaceCastInst(NewGEP, GEP.getType());
} }
} }
} }

View File

@ -1,6 +1,6 @@
; Tests to make sure elimination of casts is working correctly ; Tests to make sure elimination of casts is working correctly
; RUN: opt < %s -instcombine -S | FileCheck %s ; RUN: opt < %s -instcombine -S | FileCheck %s
target datalayout = "E-p:64:64:64-p1:32:32:32-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n8:16:32:64" target datalayout = "E-p:64:64:64-p1:32:32:32-p2:64:64:64-p3:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n8:16:32:64"
@inbuf = external global [32832 x i8] ; <[32832 x i8]*> [#uses=1] @inbuf = external global [32832 x i8] ; <[32832 x i8]*> [#uses=1]
@ -708,6 +708,34 @@ define %s @test68(%s *%p, i64 %i) {
; CHECK-NEXT: ret %s ; CHECK-NEXT: ret %s
} }
; addrspacecasts should be eliminated.
define %s @test68_addrspacecast(%s* %p, i64 %i) {
; CHECK-LABEL: @test68_addrspacecast(
; CHECK-NEXT: getelementptr %s*
; CHECK-NEXT: load %s*
; CHECK-NEXT: ret %s
%o = mul i64 %i, 12
%q = addrspacecast %s* %p to i8 addrspace(2)*
%pp = getelementptr inbounds i8 addrspace(2)* %q, i64 %o
%r = addrspacecast i8 addrspace(2)* %pp to %s*
%l = load %s* %r
ret %s %l
}
define %s @test68_addrspacecast_2(%s* %p, i64 %i) {
; CHECK-LABEL: @test68_addrspacecast_2(
; CHECK-NEXT: getelementptr %s* %p
; CHECK-NEXT: addrspacecast
; CHECK-NEXT: load %s addrspace(1)*
; CHECK-NEXT: ret %s
%o = mul i64 %i, 12
%q = addrspacecast %s* %p to i8 addrspace(2)*
%pp = getelementptr inbounds i8 addrspace(2)* %q, i64 %o
%r = addrspacecast i8 addrspace(2)* %pp to %s addrspace(1)*
%l = load %s addrspace(1)* %r
ret %s %l
}
define %s @test68_as1(%s addrspace(1)* %p, i32 %i) { define %s @test68_as1(%s addrspace(1)* %p, i32 %i) {
; CHECK-LABEL: @test68_as1( ; CHECK-LABEL: @test68_as1(
%o = mul i32 %i, 12 %o = mul i32 %i, 12
@ -903,6 +931,33 @@ define double @test80([100 x double]* %p, i32 %i) {
; CHECK-NEXT: ret double ; CHECK-NEXT: ret double
} }
define double @test80_addrspacecast([100 x double] addrspace(1)* %p, i32 %i) {
; CHECK-LABEL: @test80_addrspacecast(
; CHECK-NEXT: getelementptr [100 x double] addrspace(1)* %p
; CHECK-NEXT: load double addrspace(1)*
; CHECK-NEXT: ret double
%tmp = mul nsw i32 %i, 8
%q = addrspacecast [100 x double] addrspace(1)* %p to i8 addrspace(2)*
%pp = getelementptr i8 addrspace(2)* %q, i32 %tmp
%r = addrspacecast i8 addrspace(2)* %pp to double addrspace(1)*
%l = load double addrspace(1)* %r
ret double %l
}
define double @test80_addrspacecast_2([100 x double] addrspace(1)* %p, i32 %i) {
; CHECK-LABEL: @test80_addrspacecast_2(
; CHECK-NEXT: getelementptr [100 x double] addrspace(1)*
; CHECK-NEXT: addrspacecast double addrspace(1)*
; CHECK-NEXT: load double addrspace(3)*
; CHECK-NEXT: ret double
%tmp = mul nsw i32 %i, 8
%q = addrspacecast [100 x double] addrspace(1)* %p to i8 addrspace(2)*
%pp = getelementptr i8 addrspace(2)* %q, i32 %tmp
%r = addrspacecast i8 addrspace(2)* %pp to double addrspace(3)*
%l = load double addrspace(3)* %r
ret double %l
}
define double @test80_as1([100 x double] addrspace(1)* %p, i16 %i) { define double @test80_as1([100 x double] addrspace(1)* %p, i16 %i) {
; CHECK-LABEL: @test80_as1( ; CHECK-LABEL: @test80_as1(
%tmp = mul nsw i16 %i, 8 %tmp = mul nsw i16 %i, 8

View File

@ -1,6 +1,6 @@
; RUN: opt < %s -instcombine -S | FileCheck %s ; RUN: opt < %s -instcombine -S | FileCheck %s
target datalayout = "e-p:64:64-p1:16:16-p2:32:32:32" target datalayout = "e-p:64:64-p1:16:16-p2:32:32:32-p3:64:64:64"
%intstruct = type { i32 } %intstruct = type { i32 }
%pair = type { i32, i32 } %pair = type { i32, i32 }
@ -728,6 +728,19 @@ define i64 @test_gep_bitcast_array_same_size_element([100 x double]* %arr, i64 %
ret i64 %x ret i64 %x
} }
; gep should be done in the original address space.
define i64 @test_gep_bitcast_array_same_size_element_addrspacecast([100 x double]* %arr, i64 %N) {
; CHECK-LABEL: @test_gep_bitcast_array_same_size_element_addrspacecast(
; CHECK: getelementptr [100 x double]* %arr, i64 0, i64 %V
; CHECK-NEXT: %t = addrspacecast double*
; CHECK: load i64 addrspace(3)* %t
%cast = addrspacecast [100 x double]* %arr to i64 addrspace(3)*
%V = mul i64 %N, 8
%t = getelementptr i64 addrspace(3)* %cast, i64 %V
%x = load i64 addrspace(3)* %t
ret i64 %x
}
; The element size of the array is different the element size of the pointer ; The element size of the array is different the element size of the pointer
define i8 @test_gep_bitcast_array_different_size_element([100 x double]* %arr, i64 %N) { define i8 @test_gep_bitcast_array_different_size_element([100 x double]* %arr, i64 %N) {
; CHECK-LABEL: @test_gep_bitcast_array_different_size_element( ; CHECK-LABEL: @test_gep_bitcast_array_different_size_element(