Skip to content

Commit 161bfa5

Browse files
committed
[LoopFlattening] Check for extra uses on Mul
Similar to D138404, we were not guarding against extra uses of the Mul. In most cases other checks would catch the issue due to unsupported instructions in the outer loop, but certain non-canonical loop forms could still get through. Fixes llvm#59339 Differential Revision: https://reviews.llvm.org/D141114
1 parent 8cc9530 commit 161bfa5

File tree

2 files changed

+15
-9
lines changed

2 files changed

+15
-9
lines changed

llvm/lib/Transforms/Scalar/LoopFlatten.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,15 @@ struct FlattenInfo {
215215
LLVM_DEBUG(dbgs() << "Matched multiplication: "; MatchedMul->dump());
216216
LLVM_DEBUG(dbgs() << "Matched iteration count: "; MatchedItCount->dump());
217217

218+
// The mul should not have any other uses. Widening may leave trivially dead
219+
// uses, which can be ignored.
220+
if (count_if(MatchedMul->users(), [](User *U) {
221+
return !isInstructionTriviallyDead(cast<Instruction>(U));
222+
}) > 1) {
223+
LLVM_DEBUG(dbgs() << "Multiply has more than one use\n");
224+
return false;
225+
}
226+
218227
// Look through extends if the IV has been widened. Don't look through
219228
// extends if we already looked through a trunc.
220229
if (Widened && IsAdd &&

llvm/test/Transforms/LoopFlatten/pr59339.ll

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
22
; RUN: opt < %s -S -opaque-pointers -passes='loop(loop-flatten),verify' -verify-loop-info -verify-dom-info -verify-scev | FileCheck %s
33

4-
; FIXME: This incorrectly triggers, thus resulting in a miscompilation.
5-
; The problem is that there is a linear use of the induction variable, i*3+j,
6-
; but only the part i*3 is used for indexing.
4+
; Check that the mul does not have extra uses.
75

86
define void @test0(ptr %arg, ptr %arg1) {
97
; CHECK-LABEL: @test0(
108
; CHECK-NEXT: bb:
11-
; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 3, 2
129
; CHECK-NEXT: br label [[DOTPREHEADER:%.*]]
1310
; CHECK: .preheader:
1411
; CHECK-NEXT: [[I:%.*]] = phi i64 [ 0, [[BB:%.*]] ], [ [[I5:%.*]], [[BB4:%.*]] ]
@@ -17,17 +14,17 @@ define void @test0(ptr %arg, ptr %arg1) {
1714
; CHECK-NEXT: br label [[BB7:%.*]]
1815
; CHECK: bb4:
1916
; CHECK-NEXT: [[I5]] = add i64 [[I]], 1
20-
; CHECK-NEXT: [[I6:%.*]] = icmp slt i64 [[I5]], [[FLATTEN_TRIPCOUNT]]
17+
; CHECK-NEXT: [[I6:%.*]] = icmp slt i64 [[I5]], 2
2118
; CHECK-NEXT: br i1 [[I6]], label [[DOTPREHEADER]], label [[BB14:%.*]]
2219
; CHECK: bb7:
23-
; CHECK-NEXT: [[I8:%.*]] = phi i64 [ 0, [[DOTPREHEADER]] ]
20+
; CHECK-NEXT: [[I8:%.*]] = phi i64 [ 0, [[DOTPREHEADER]] ], [ [[I12:%.*]], [[BB7]] ]
2421
; CHECK-NEXT: [[I9:%.*]] = load i16, ptr [[I3]], align 2
2522
; CHECK-NEXT: [[I10:%.*]] = add i64 [[I8]], [[I2]]
26-
; CHECK-NEXT: [[I11:%.*]] = getelementptr i16, ptr [[ARG:%.*]], i64 [[I]]
23+
; CHECK-NEXT: [[I11:%.*]] = getelementptr i16, ptr [[ARG:%.*]], i64 [[I10]]
2724
; CHECK-NEXT: store i16 [[I9]], ptr [[I11]], align 2
28-
; CHECK-NEXT: [[I12:%.*]] = add nuw nsw i64 [[I8]], 1
25+
; CHECK-NEXT: [[I12]] = add nuw nsw i64 [[I8]], 1
2926
; CHECK-NEXT: [[I13:%.*]] = icmp ult i64 [[I12]], 3
30-
; CHECK-NEXT: br label [[BB4]]
27+
; CHECK-NEXT: br i1 [[I13]], label [[BB7]], label [[BB4]]
3128
; CHECK: bb14:
3229
; CHECK-NEXT: ret void
3330
;

0 commit comments

Comments
 (0)