[PATCH] D38337: Check for overflows when calculating the offset in GetGEPCost.

Justin Lebar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 27 16:14:05 PDT 2017


jlebar updated this revision to Diff 116899.
jlebar marked an inline comment as done.
jlebar added a comment.

Call sextOrTrunc instead of assuming the offset constant has the same width as the pointer.


https://reviews.llvm.org/D38337

Files:
  llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
  llvm/test/Analysis/CostModel/X86/gep.ll


Index: llvm/test/Analysis/CostModel/X86/gep.ll
===================================================================
--- llvm/test/Analysis/CostModel/X86/gep.ll
+++ llvm/test/Analysis/CostModel/X86/gep.ll
@@ -35,6 +35,17 @@
 ;CHECK: cost of 0 for instruction: {{.*}} getelementptr inbounds <4 x double>, <4 x double>*
   %a12 = getelementptr inbounds <4 x double>, <4 x double>* undef, i32 0
 
+  ; Check that we handle outlandishly large GEPs properly.  This is unlikely to
+  ; be a valid pointer, but LLVM still generates GEPs like this sometimes in
+  ; dead code.
+  ;
+  ; This GEP has index INT64_MAX, which is cost 1.
+;CHECK: cost of 1 for instruction: {{.*}} getelementptr inbounds i8, i8*
+  %giant_gep0 = getelementptr inbounds i8, i8* undef, i64 9223372036854775807
+
+  ; This GEP index wraps around to -1, which is cost 0.
+;CHECK: cost of 0 for instruction: {{.*}} getelementptr inbounds i8, i8*
+  %giant_gep1 = getelementptr inbounds i8, i8* undef, i128 295147905179352825855
 
   ret void
 }
Index: llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
===================================================================
--- llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -674,7 +674,9 @@
       BaseGV = dyn_cast<GlobalValue>(Ptr->stripPointerCasts());
     }
     bool HasBaseReg = (BaseGV == nullptr);
-    int64_t BaseOffset = 0;
+
+    auto PtrSizeBits = DL.getPointerTypeSizeInBits(Ptr->getType());
+    APInt BaseOffset(PtrSizeBits, 0);
     int64_t Scale = 0;
 
     auto GTI = gep_type_begin(PointeeType, Operands);
@@ -700,9 +702,10 @@
         BaseOffset += DL.getStructLayout(STy)->getElementOffset(Field);
       } else {
         int64_t ElementSize = DL.getTypeAllocSize(GTI.getIndexedType());
-        if (ConstIdx)
-          BaseOffset += ConstIdx->getSExtValue() * ElementSize;
-        else {
+        if (ConstIdx) {
+          BaseOffset +=
+              ConstIdx->getValue().sextOrTrunc(PtrSizeBits) * ElementSize;
+        } else {
           // Needs scale register.
           if (Scale != 0)
             // No addressing mode takes two scale registers.
@@ -716,8 +719,9 @@
     unsigned AS =
         (Ptr == nullptr ? 0 : Ptr->getType()->getPointerAddressSpace());
     if (static_cast<T *>(this)->isLegalAddressingMode(
-            TargetType, const_cast<GlobalValue *>(BaseGV), BaseOffset,
-            HasBaseReg, Scale, AS))
+            TargetType, const_cast<GlobalValue *>(BaseGV),
+            static_cast<int64_t>(BaseOffset.getLimitedValue()), HasBaseReg,
+            Scale, AS))
       return TTI::TCC_Free;
     return TTI::TCC_Basic;
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D38337.116899.patch
Type: text/x-patch
Size: 2666 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170927/e7acd4e8/attachment.bin>


More information about the llvm-commits mailing list