From f222ebe86c944fc0f13afbb619bfa69880893f7a Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Fri, 14 Feb 2014 00:49:12 +0000 Subject: [PATCH] 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 --- .../InstCombine/InstructionCombining.cpp | 18 ++++-- test/Transforms/InstCombine/cast.ll | 57 ++++++++++++++++++- test/Transforms/InstCombine/getelementptr.ll | 15 ++++- 3 files changed, 82 insertions(+), 8 deletions(-) diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp index 04c1499220c..e4365d691f7 100644 --- a/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1220,9 +1220,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { if (!StrippedPtrTy) return 0; - if (StrippedPtr != PtrOp && - StrippedPtrTy->getAddressSpace() == GEP.getPointerAddressSpace()) { - + if (StrippedPtr != PtrOp) { bool HasZeroPointerIndex = false; if (ConstantInt *C = dyn_cast(GEP.getOperand(1))) HasZeroPointerIndex = C->isZero(); @@ -1276,8 +1274,11 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { Value *NewGEP = GEP.isInBounds() ? Builder->CreateInBoundsGEP(StrippedPtr, Idx, GEP.getName()) : Builder->CreateGEP(StrippedPtr, Idx, GEP.getName()); + // V and GEP are both pointer types --> BitCast - return new BitCastInst(NewGEP, GEP.getType()); + if (StrippedPtrTy->getAddressSpace() == GEP.getPointerAddressSpace()) + return new BitCastInst(NewGEP, GEP.getType()); + return new AddrSpaceCastInst(NewGEP, GEP.getType()); } // Transform things like: @@ -1307,8 +1308,11 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { Value *NewGEP = GEP.isInBounds() && NSW ? Builder->CreateInBoundsGEP(StrippedPtr, NewIdx, GEP.getName()) : Builder->CreateGEP(StrippedPtr, NewIdx, GEP.getName()); + // The NewGEP must be pointer typed, so must the old one -> BitCast - return new BitCastInst(NewGEP, GEP.getType()); + if (StrippedPtrTy->getAddressSpace() == GEP.getPointerAddressSpace()) + 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->CreateGEP(StrippedPtr, Off, GEP.getName()); // The NewGEP must be pointer typed, so must the old one -> BitCast - return new BitCastInst(NewGEP, GEP.getType()); + if (StrippedPtrTy->getAddressSpace() == GEP.getPointerAddressSpace()) + return new BitCastInst(NewGEP, GEP.getType()); + return new AddrSpaceCastInst(NewGEP, GEP.getType()); } } } diff --git a/test/Transforms/InstCombine/cast.ll b/test/Transforms/InstCombine/cast.ll index cac0ec10916..4fab92f2c11 100644 --- a/test/Transforms/InstCombine/cast.ll +++ b/test/Transforms/InstCombine/cast.ll @@ -1,6 +1,6 @@ ; Tests to make sure elimination of casts is working correctly ; 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] @@ -708,6 +708,34 @@ define %s @test68(%s *%p, i64 %i) { ; 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) { ; CHECK-LABEL: @test68_as1( %o = mul i32 %i, 12 @@ -903,6 +931,33 @@ define double @test80([100 x double]* %p, i32 %i) { ; 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) { ; CHECK-LABEL: @test80_as1( %tmp = mul nsw i16 %i, 8 diff --git a/test/Transforms/InstCombine/getelementptr.ll b/test/Transforms/InstCombine/getelementptr.ll index 394cfa74c78..ef0cb29fd88 100644 --- a/test/Transforms/InstCombine/getelementptr.ll +++ b/test/Transforms/InstCombine/getelementptr.ll @@ -1,6 +1,6 @@ ; 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 } %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 } +; 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 define i8 @test_gep_bitcast_array_different_size_element([100 x double]* %arr, i64 %N) { ; CHECK-LABEL: @test_gep_bitcast_array_different_size_element(