[PATCH] D108107: [LoopFlatten] Fix overflow check

Rosie Sumpter via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 16 01:21:57 PDT 2021


RosieSumpter created this revision.
RosieSumpter added reviewers: dmgreen, SjoerdMeijer.
Herald added a subscriber: hiraditya.
RosieSumpter requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Amended the GEP check in checkOverflow to ensure that the GEP
dominates the loop latch. If the GEP doesn't dominate the latch
then it is not necessarily calculated on each loop iteration, so
the assumption that the GEP will overflow (and be UB) before the
IV no longer holds.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D108107

Files:
  llvm/lib/Transforms/Scalar/LoopFlatten.cpp
  llvm/test/Transforms/LoopFlatten/loop-flatten-negative.ll


Index: llvm/test/Transforms/LoopFlatten/loop-flatten-negative.ll
===================================================================
--- llvm/test/Transforms/LoopFlatten/loop-flatten-negative.ll
+++ llvm/test/Transforms/LoopFlatten/loop-flatten-negative.ll
@@ -786,6 +786,54 @@
   ret void
 } 
 
+; GEP doesn't dominate the loop latch so can't guarantee N*M won't overflow.
+ at first = global i32 1, align 4
+ at a = external global [0 x i8], align 1
+define void @overflow(i32 %lim, i8* %a) {
+entry:
+  %cmp17.not = icmp eq i32 %lim, 0
+  br i1 %cmp17.not, label %for.cond.cleanup, label %for.cond1.preheader.preheader
+
+for.cond1.preheader.preheader:
+  br label %for.cond1.preheader
+
+for.cond1.preheader:
+  %i.018 = phi i32 [ %inc6, %for.cond.cleanup3 ], [ 0, %for.cond1.preheader.preheader ]
+  %mul = mul i32 %i.018, 100000
+  br label %for.body4
+
+for.cond.cleanup.loopexit:
+  br label %for.cond.cleanup
+
+for.cond.cleanup:
+  ret void
+
+for.cond.cleanup3:
+  %inc6 = add i32 %i.018, 1
+  %cmp = icmp ult i32 %inc6, %lim
+  br i1 %cmp, label %for.cond1.preheader, label %for.cond.cleanup.loopexit
+
+for.body4:
+  %j.016 = phi i32 [ 0, %for.cond1.preheader ], [ %inc, %if.end ]
+  %add = add i32 %j.016, %mul
+  %0 = load i32, i32* @first, align 4
+  %tobool.not = icmp eq i32 %0, 0
+  br i1 %tobool.not, label %if.end, label %if.then
+
+if.then:
+  %arrayidx = getelementptr inbounds [0 x i8], [0 x i8]* @a, i32 0, i32 %add
+  %1 = load i8, i8* %arrayidx, align 1
+  tail call void asm sideeffect "", "r"(i8 %1)
+  store i32 0, i32* @first, align 4
+  br label %if.end
+
+if.end:
+  tail call void asm sideeffect "", "r"(i32 %add)
+  %inc = add nuw nsw i32 %j.016, 1
+  %cmp2 = icmp ult i32 %j.016, 99999
+  br i1 %cmp2, label %for.body4, label %for.cond.cleanup3
+}
+
 declare void @objc_enumerationMutation(i8*)
 declare dso_local void @f(i32*)
 declare dso_local void @g(...)
Index: llvm/lib/Transforms/Scalar/LoopFlatten.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/LoopFlatten.cpp
+++ llvm/lib/Transforms/Scalar/LoopFlatten.cpp
@@ -496,11 +496,13 @@
   for (Value *V : FI.LinearIVUses) {
     for (Value *U : V->users()) {
       if (auto *GEP = dyn_cast<GetElementPtrInst>(U)) {
-        // The IV is used as the operand of a GEP, and the IV is at least as
-        // wide as the address space of the GEP. In this case, the GEP would
-        // wrap around the address space before the IV increment wraps, which
-        // would be UB.
-        if (GEP->isInBounds() &&
+        bool GEPDominatesLatch =
+            DT->dominates(GEP->getParent(), FI.InnerLoop->getLoopLatch());
+        // The IV is used as the operand of a GEP which dominates the loop
+        // latch, and the IV is at least as wide as the address space of the
+        // GEP. In this case, the GEP would wrap around the address space before
+        // the IV increment wraps, which would be UB.
+        if (GEPDominatesLatch && GEP->isInBounds() &&
             V->getType()->getIntegerBitWidth() >=
                 DL.getPointerTypeSizeInBits(GEP->getType())) {
           LLVM_DEBUG(


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D108107.366566.patch
Type: text/x-patch
Size: 3142 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210816/8e392159/attachment.bin>


More information about the llvm-commits mailing list