[llvm] r275251 - [ConstantFolding] Don't treat negative GEP offsets as positive

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 12 22:16:16 PDT 2016


Author: majnemer
Date: Wed Jul 13 00:16:16 2016
New Revision: 275251

URL: http://llvm.org/viewvc/llvm-project?rev=275251&view=rev
Log:
[ConstantFolding] Don't treat negative GEP offsets as positive

GEP offsets are signed, don't treat them as huge positive numbers.

Modified:
    llvm/trunk/lib/Analysis/ConstantFolding.cpp
    llvm/trunk/test/Transforms/InstCombine/getelementptr.ll

Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=275251&r1=275250&r2=275251&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original)
+++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Wed Jul 13 00:16:16 2016
@@ -845,15 +845,18 @@ Constant *SymbolicallyEvaluateGEP(const
 
       // Determine which element of the array the offset points into.
       APInt ElemSize(BitWidth, DL.getTypeAllocSize(Ty));
-      if (ElemSize == 0)
+      if (ElemSize == 0) {
         // The element size is 0. This may be [0 x Ty]*, so just use a zero
         // index for this level and proceed to the next level to see if it can
         // accommodate the offset.
         NewIdxs.push_back(ConstantInt::get(IntPtrTy, 0));
-      else {
+      } else if (ElemSize.isAllOnesValue()) {
+        // Avoid signed overflow.
+        break;
+      } else {
         // The element size is non-zero divide the offset by the element
         // size (rounding down), to compute the index at this level.
-        APInt NewIdx = Offset.udiv(ElemSize);
+        APInt NewIdx = Offset.sdiv(ElemSize);
         Offset -= NewIdx * ElemSize;
         NewIdxs.push_back(ConstantInt::get(IntPtrTy, NewIdx));
       }
@@ -864,7 +867,7 @@ Constant *SymbolicallyEvaluateGEP(const
       // operand likely went through casts that are necessary to make the GEP
       // sensible.
       const StructLayout &SL = *DL.getStructLayout(STy);
-      if (Offset.uge(SL.getSizeInBytes()))
+      if (Offset.isNegative() || Offset.uge(SL.getSizeInBytes()))
         break;
 
       // Determine which field of the struct the offset points into. The

Modified: llvm/trunk/test/Transforms/InstCombine/getelementptr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/getelementptr.ll?rev=275251&r1=275250&r2=275251&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/getelementptr.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/getelementptr.ll Wed Jul 13 00:16:16 2016
@@ -624,15 +624,11 @@ define i32 @test35() nounwind {
 ; CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @"\01LC8", i64 0, i64 0), i8* getelementptr inbounds (%t0, %t0* @s, i64 0, i32 1, i64 0)) [[NUW:#[0-9]+]]
 }
 
-; Instcombine should constant-fold the GEP so that indices that have
-; static array extents are within bounds of those array extents.
-; In the below, -1 is not in the range [0,11). After the transformation,
-; the same address is computed, but 3 is in the range of [0,11).
-
+; Don't treat signed offsets as unsigned.
 define i8* @test36() nounwind {
   ret i8* getelementptr ([11 x i8], [11 x i8]* @array, i32 0, i64 -1)
 ; CHECK-LABEL: @test36(
-; CHECK: ret i8* getelementptr ([11 x i8], [11 x i8]* @array, i64 1676976733973595601, i64 4)
+; CHECK: ret i8* getelementptr ([11 x i8], [11 x i8]* @array, i64 0, i64 -1)
 }
 
 ; Instcombine shouldn't assume that gep(A,0,1) != gep(A,1,0).




More information about the llvm-commits mailing list