[PATCH] D108107: [LoopFlatten] Fix overflow check
Rosie Sumpter via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 16 07:34:42 PDT 2021
RosieSumpter updated this revision to Diff 366624.
RosieSumpter added a comment.
Changed the check to see if the GEP is used by a load/store instruction
and, if so, isGuaranteedToExecuteForEveryIteration is used with the instruction and
inner loop to determine if the GEP dominates the latch.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D108107/new/
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,17 +496,23 @@
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() &&
- V->getType()->getIntegerBitWidth() >=
- DL.getPointerTypeSizeInBits(GEP->getType())) {
- LLVM_DEBUG(
- dbgs() << "use of linear IV would be UB if overflow occurred: ";
- GEP->dump());
- return OverflowResult::NeverOverflows;
+ for (Value *GEPUser : U->users()) {
+ bool GEPDominatesLatch = false;
+ if (isa<LoadInst>(GEPUser) || isa<StoreInst>(GEPUser))
+ GEPDominatesLatch = isGuaranteedToExecuteForEveryIteration(
+ cast<Instruction>(GEPUser), FI.InnerLoop);
+ // 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(
+ dbgs() << "use of linear IV would be UB if overflow occurred: ";
+ GEP->dump());
+ return OverflowResult::NeverOverflows;
+ }
}
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D108107.366624.patch
Type: text/x-patch
Size: 3837 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210816/65c4d967/attachment.bin>
More information about the llvm-commits
mailing list