[llvm] r373847 - [InstCombine] don't assume 'inbounds' for bitcast pointer to GEP transform (PR43501)

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 6 06:08:08 PDT 2019


Author: spatel
Date: Sun Oct  6 06:08:08 2019
New Revision: 373847

URL: http://llvm.org/viewvc/llvm-project?rev=373847&view=rev
Log:
[InstCombine] don't assume 'inbounds' for bitcast pointer to GEP transform (PR43501)

https://bugs.llvm.org/show_bug.cgi?id=43501
We can't declare a GEP 'inbounds' in general. But we may salvage that information if
we have known dereferenceable bytes on the source pointer.

Differential Revision: https://reviews.llvm.org/D68244

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
    llvm/trunk/test/Transforms/InstCombine/addrspacecast.ll
    llvm/trunk/test/Transforms/InstCombine/cast.ll
    llvm/trunk/test/Transforms/InstCombine/load-bitcast-vec.ll
    llvm/trunk/test/Transforms/InstCombine/memset.ll
    llvm/trunk/test/Transforms/InstCombine/unpack-fca.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=373847&r1=373846&r2=373847&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Sun Oct  6 06:08:08 2019
@@ -2338,8 +2338,15 @@ Instruction *InstCombiner::visitBitCast(
     // If we found a path from the src to dest, create the getelementptr now.
     if (SrcElTy == DstElTy) {
       SmallVector<Value *, 8> Idxs(NumZeros + 1, Builder.getInt32(0));
-      return GetElementPtrInst::CreateInBounds(SrcPTy->getElementType(), Src,
-                                               Idxs);
+      GetElementPtrInst *GEP =
+          GetElementPtrInst::Create(SrcPTy->getElementType(), Src, Idxs);
+
+      // If the source pointer is dereferenceable, then assume it points to an
+      // allocated object and apply "inbounds" to the GEP.
+      bool CanBeNull;
+      if (Src->getPointerDereferenceableBytes(DL, CanBeNull))
+        GEP->setIsInBounds();
+      return GEP;
     }
   }
 

Modified: llvm/trunk/test/Transforms/InstCombine/addrspacecast.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/addrspacecast.ll?rev=373847&r1=373846&r2=373847&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/addrspacecast.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/addrspacecast.ll Sun Oct  6 06:08:08 2019
@@ -104,7 +104,7 @@ define <4 x float addrspace(2)*> @combin
 
 define i32 @canonicalize_addrspacecast([16 x i32] addrspace(1)* %arr) {
 ; CHECK-LABEL: @canonicalize_addrspacecast(
-; CHECK-NEXT: getelementptr inbounds [16 x i32], [16 x i32] addrspace(1)* %arr, i32 0, i32 0
+; CHECK-NEXT: getelementptr [16 x i32], [16 x i32] addrspace(1)* %arr, i32 0, i32 0
 ; CHECK-NEXT: addrspacecast i32 addrspace(1)* %{{[a-zA-Z0-9]+}} to i32*
 ; CHECK-NEXT: load i32, i32*
 ; CHECK-NEXT: ret i32

Modified: llvm/trunk/test/Transforms/InstCombine/cast.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/cast.ll?rev=373847&r1=373846&r2=373847&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/cast.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/cast.ll Sun Oct  6 06:08:08 2019
@@ -293,7 +293,7 @@ define i32 @test26(float %F) {
 
 define [4 x float]* @test27([9 x [4 x float]]* %A) {
 ; CHECK-LABEL: @test27(
-; CHECK-NEXT:    [[C:%.*]] = getelementptr inbounds [9 x [4 x float]], [9 x [4 x float]]* [[A:%.*]], i64 0, i64 0
+; CHECK-NEXT:    [[C:%.*]] = getelementptr [9 x [4 x float]], [9 x [4 x float]]* [[A:%.*]], i64 0, i64 0
 ; CHECK-NEXT:    ret [4 x float]* [[C]]
 ;
   %c = bitcast [9 x [4 x float]]* %A to [4 x float]*
@@ -302,7 +302,7 @@ define [4 x float]* @test27([9 x [4 x fl
 
 define float* @test28([4 x float]* %A) {
 ; CHECK-LABEL: @test28(
-; CHECK-NEXT:    [[C:%.*]] = getelementptr inbounds [4 x float], [4 x float]* [[A:%.*]], i64 0, i64 0
+; CHECK-NEXT:    [[C:%.*]] = getelementptr [4 x float], [4 x float]* [[A:%.*]], i64 0, i64 0
 ; CHECK-NEXT:    ret float* [[C]]
 ;
   %c = bitcast [4 x float]* %A to float*

Modified: llvm/trunk/test/Transforms/InstCombine/load-bitcast-vec.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/load-bitcast-vec.ll?rev=373847&r1=373846&r2=373847&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/load-bitcast-vec.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/load-bitcast-vec.ll Sun Oct  6 06:08:08 2019
@@ -67,6 +67,41 @@ define float @matching_scalar_small_dere
   ret float %r
 }
 
+define float @matching_scalar_smallest_deref(<4 x float>* dereferenceable(1) %p) {
+; CHECK-LABEL: @matching_scalar_smallest_deref(
+; CHECK-NEXT:    [[BC:%.*]] = getelementptr inbounds <4 x float>, <4 x float>* [[P:%.*]], i64 0, i64 0
+; CHECK-NEXT:    [[R:%.*]] = load float, float* [[BC]], align 16
+; CHECK-NEXT:    ret float [[R]]
+;
+  %bc = bitcast <4 x float>* %p to float*
+  %r = load float, float* %bc, align 16
+  ret float %r
+}
+
+define float @matching_scalar_smallest_deref_or_null(<4 x float>* dereferenceable_or_null(1) %p) {
+; CHECK-LABEL: @matching_scalar_smallest_deref_or_null(
+; CHECK-NEXT:    [[BC:%.*]] = getelementptr inbounds <4 x float>, <4 x float>* [[P:%.*]], i64 0, i64 0
+; CHECK-NEXT:    [[R:%.*]] = load float, float* [[BC]], align 16
+; CHECK-NEXT:    ret float [[R]]
+;
+  %bc = bitcast <4 x float>* %p to float*
+  %r = load float, float* %bc, align 16
+  ret float %r
+}
+
+; TODO: Is a null pointer inbounds in any address space?
+
+define float @matching_scalar_smallest_deref_or_null_addrspace(<4 x float> addrspace(4)* dereferenceable_or_null(1) %p) {
+; CHECK-LABEL: @matching_scalar_smallest_deref_or_null_addrspace(
+; CHECK-NEXT:    [[BC:%.*]] = getelementptr inbounds <4 x float>, <4 x float> addrspace(4)* [[P:%.*]], i64 0, i64 0
+; CHECK-NEXT:    [[R:%.*]] = load float, float addrspace(4)* [[BC]], align 16
+; CHECK-NEXT:    ret float [[R]]
+;
+  %bc = bitcast <4 x float> addrspace(4)* %p to float addrspace(4)*
+  %r = load float, float addrspace(4)* %bc, align 16
+  ret float %r
+}
+
 define float @matching_scalar_volatile(<4 x float>* dereferenceable(16) %p) {
 ; CHECK-LABEL: @matching_scalar_volatile(
 ; CHECK-NEXT:    [[BC:%.*]] = getelementptr inbounds <4 x float>, <4 x float>* [[P:%.*]], i64 0, i64 0

Modified: llvm/trunk/test/Transforms/InstCombine/memset.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/memset.ll?rev=373847&r1=373846&r2=373847&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/memset.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/memset.ll Sun Oct  6 06:08:08 2019
@@ -3,7 +3,7 @@
 
 define i32 @test([1024 x i8]* %target) {
 ; CHECK-LABEL: @test(
-; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[TARGET:%.*]], i64 0, i64 0
+; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr [1024 x i8], [1024 x i8]* [[TARGET:%.*]], i64 0, i64 0
 ; CHECK-NEXT:    store i8 1, i8* [[TMP1]], align 1
 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast [1024 x i8]* [[TARGET]] to i16*
 ; CHECK-NEXT:    store i16 257, i16* [[TMP2]], align 2

Modified: llvm/trunk/test/Transforms/InstCombine/unpack-fca.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/unpack-fca.ll?rev=373847&r1=373846&r2=373847&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/unpack-fca.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/unpack-fca.ll Sun Oct  6 06:08:08 2019
@@ -13,7 +13,7 @@ declare i32 @A.foo(%A* nocapture %this)
 
 define void @storeA(%A* %a.ptr) {
 ; CHECK-LABEL: storeA
-; CHECK-NEXT: [[GEP:%[a-z0-9\.]+]] = getelementptr inbounds %A, %A* %a.ptr, i64 0, i32 0
+; CHECK-NEXT: [[GEP:%[a-z0-9\.]+]] = getelementptr %A, %A* %a.ptr, i64 0, i32 0
 ; CHECK-NEXT: store %A__vtbl* @A__vtblZ, %A__vtbl** [[GEP]], align 8
 ; CHECK-NEXT: ret void
   store %A { %A__vtbl* @A__vtblZ }, %A* %a.ptr, align 8
@@ -33,7 +33,7 @@ define void @storeB(%B* %b.ptr) {
 
 define void @storeStructOfA({ %A }* %sa.ptr) {
 ; CHECK-LABEL: storeStructOfA
-; CHECK-NEXT: [[GEP:%[a-z0-9\.]+]] = getelementptr inbounds { %A }, { %A }* %sa.ptr, i64 0, i32 0, i32 0
+; CHECK-NEXT: [[GEP:%[a-z0-9\.]+]] = getelementptr { %A }, { %A }* %sa.ptr, i64 0, i32 0, i32 0
 ; CHECK-NEXT: store %A__vtbl* @A__vtblZ, %A__vtbl** [[GEP]], align 8
 ; CHECK-NEXT: ret void
   store { %A } { %A { %A__vtbl* @A__vtblZ } }, { %A }* %sa.ptr, align 8
@@ -42,7 +42,7 @@ define void @storeStructOfA({ %A }* %sa.
 
 define void @storeArrayOfA([1 x %A]* %aa.ptr) {
 ; CHECK-LABEL: storeArrayOfA
-; CHECK-NEXT: [[GEP:%[a-z0-9\.]+]] = getelementptr inbounds [1 x %A], [1 x %A]* %aa.ptr, i64 0, i64 0, i32 0
+; CHECK-NEXT: [[GEP:%[a-z0-9\.]+]] = getelementptr [1 x %A], [1 x %A]* %aa.ptr, i64 0, i64 0, i32 0
 ; CHECK-NEXT: store %A__vtbl* @A__vtblZ, %A__vtbl** [[GEP]], align 8
 ; CHECK-NEXT: ret void
   store [1 x %A] [%A { %A__vtbl* @A__vtblZ }], [1 x %A]* %aa.ptr, align 8
@@ -60,7 +60,7 @@ define void @storeLargeArrayOfA([2000 x
 
 define void @storeStructOfArrayOfA({ [1 x %A] }* %saa.ptr) {
 ; CHECK-LABEL: storeStructOfArrayOfA
-; CHECK-NEXT: [[GEP:%[a-z0-9\.]+]] = getelementptr inbounds { [1 x %A] }, { [1 x %A] }* %saa.ptr, i64 0, i32 0, i64 0, i32 0
+; CHECK-NEXT: [[GEP:%[a-z0-9\.]+]] = getelementptr { [1 x %A] }, { [1 x %A] }* %saa.ptr, i64 0, i32 0, i64 0, i32 0
 ; CHECK-NEXT: store %A__vtbl* @A__vtblZ, %A__vtbl** [[GEP]], align 8
 ; CHECK-NEXT: ret void
   store { [1 x %A] } { [1 x %A] [%A { %A__vtbl* @A__vtblZ }] }, { [1 x %A] }* %saa.ptr, align 8
@@ -90,7 +90,7 @@ define void @storeArrayOfB([2 x %B]* %ab
 
 define %A @loadA(%A* %a.ptr) {
 ; CHECK-LABEL: loadA
-; CHECK-NEXT: [[GEP:%[a-z0-9\.]+]] = getelementptr inbounds %A, %A* %a.ptr, i64 0, i32 0
+; CHECK-NEXT: [[GEP:%[a-z0-9\.]+]] = getelementptr %A, %A* %a.ptr, i64 0, i32 0
 ; CHECK-NEXT: [[LOAD:%[a-z0-9\.]+]] = load %A__vtbl*, %A__vtbl** [[GEP]], align 8
 ; CHECK-NEXT: [[IV:%[a-z0-9\.]+]] = insertvalue %A undef, %A__vtbl* [[LOAD]], 0
 ; CHECK-NEXT: ret %A [[IV]]
@@ -113,7 +113,7 @@ define %B @loadB(%B* %b.ptr) {
 
 define { %A } @loadStructOfA({ %A }* %sa.ptr) {
 ; CHECK-LABEL: loadStructOfA
-; CHECK-NEXT: [[GEP:%[a-z0-9\.]+]] = getelementptr inbounds { %A }, { %A }* %sa.ptr, i64 0, i32 0, i32 0
+; CHECK-NEXT: [[GEP:%[a-z0-9\.]+]] = getelementptr { %A }, { %A }* %sa.ptr, i64 0, i32 0, i32 0
 ; CHECK-NEXT: [[LOAD:%[a-z0-9\.]+]] = load %A__vtbl*, %A__vtbl** [[GEP]], align 8
 ; CHECK-NEXT: [[IV1:%[a-z0-9\.]+]] = insertvalue %A undef, %A__vtbl* [[LOAD]], 0
 ; CHECK-NEXT: [[IV2:%[a-z0-9\.]+]] = insertvalue { %A } undef, %A [[IV1]], 0
@@ -124,7 +124,7 @@ define { %A } @loadStructOfA({ %A }* %sa
 
 define [1 x %A] @loadArrayOfA([1 x %A]* %aa.ptr) {
 ; CHECK-LABEL: loadArrayOfA
-; CHECK-NEXT: [[GEP:%[a-z0-9\.]+]] = getelementptr inbounds [1 x %A], [1 x %A]* %aa.ptr, i64 0, i64 0, i32 0
+; CHECK-NEXT: [[GEP:%[a-z0-9\.]+]] = getelementptr [1 x %A], [1 x %A]* %aa.ptr, i64 0, i64 0, i32 0
 ; CHECK-NEXT: [[LOAD:%[a-z0-9\.]+]] = load %A__vtbl*, %A__vtbl** [[GEP]], align 8
 ; CHECK-NEXT: [[IV1:%[a-z0-9\.]+]] = insertvalue %A undef, %A__vtbl* [[LOAD]], 0
 ; CHECK-NEXT: [[IV2:%[a-z0-9\.]+]] = insertvalue [1 x %A] undef, %A [[IV1]], 0
@@ -135,7 +135,7 @@ define [1 x %A] @loadArrayOfA([1 x %A]*
 
 define { [1 x %A] } @loadStructOfArrayOfA({ [1 x %A] }* %saa.ptr) {
 ; CHECK-LABEL: loadStructOfArrayOfA
-; CHECK-NEXT: [[GEP:%[a-z0-9\.]+]] = getelementptr inbounds { [1 x %A] }, { [1 x %A] }* %saa.ptr, i64 0, i32 0, i64 0, i32 0
+; CHECK-NEXT: [[GEP:%[a-z0-9\.]+]] = getelementptr { [1 x %A] }, { [1 x %A] }* %saa.ptr, i64 0, i32 0, i64 0, i32 0
 ; CHECK-NEXT: [[LOAD:%[a-z0-9\.]+]] = load %A__vtbl*, %A__vtbl** [[GEP]], align 8
 ; CHECK-NEXT: [[IV1:%[a-z0-9\.]+]] = insertvalue %A undef, %A__vtbl* [[LOAD]], 0
 ; CHECK-NEXT: [[IV2:%[a-z0-9\.]+]] = insertvalue [1 x %A] undef, %A [[IV1]], 0
@@ -147,7 +147,7 @@ define { [1 x %A] } @loadStructOfArrayOf
 
 define { %A } @structOfA({ %A }* %sa.ptr) {
 ; CHECK-LABEL: structOfA
-; CHECK-NEXT: [[GEP:%[a-z0-9\.]+]] = getelementptr inbounds { %A }, { %A }* %sa.ptr, i64 0, i32 0, i32 0
+; CHECK-NEXT: [[GEP:%[a-z0-9\.]+]] = getelementptr { %A }, { %A }* %sa.ptr, i64 0, i32 0, i32 0
 ; CHECK-NEXT: store %A__vtbl* @A__vtblZ, %A__vtbl** [[GEP]], align 8
 ; CHECK-NEXT: ret { %A } { %A { %A__vtbl* @A__vtblZ } }
   store { %A } { %A { %A__vtbl* @A__vtblZ } }, { %A }* %sa.ptr, align 8




More information about the llvm-commits mailing list