Skip to content

Commit bec7181

Browse files
committed
[SCEVExpander] Don't use recursive expansion for ptr IV inc
Similar to the non-ptr case, directly create the getelementptr instruction. Going through expandAddToGEP() no longer makes sense with opaque pointers, where generating the necessary instruction is trivial. This avoids recursive expansion of (the SCEV of) StepV while the IR is in an inconsistent state, in particular with an incomplete IV phi node, which utilities may not be prepared to deal with. Fixes #80954.
1 parent e60c4b6 commit bec7181

File tree

2 files changed

+70
-1
lines changed

2 files changed

+70
-1
lines changed

llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,8 @@ Value *SCEVExpander::expandIVInc(PHINode *PN, Value *StepV, const Loop *L,
795795
Value *IncV;
796796
// If the PHI is a pointer, use a GEP, otherwise use an add or sub.
797797
if (PN->getType()->isPointerTy()) {
798-
IncV = expandAddToGEP(SE.getSCEV(StepV), PN);
798+
// TODO: Change name to IVName.iv.next.
799+
IncV = Builder.CreatePtrAdd(PN, StepV, "scevgep");
799800
} else {
800801
IncV = useSubtract ?
801802
Builder.CreateSub(PN, StepV, Twine(IVName) + ".iv.next") :
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2+
; RUN: opt -S -passes=loop-idiom < %s | FileCheck %s
3+
4+
; Make sure this does not assert in SCEVExpander.
5+
6+
define void @test(ptr %p, i8 %arg, i64 %arg1, i32 %arg2) {
7+
; CHECK-LABEL: define void @test(
8+
; CHECK-SAME: ptr [[P:%.*]], i8 [[ARG:%.*]], i64 [[ARG1:%.*]], i32 [[ARG2:%.*]]) {
9+
; CHECK-NEXT: entry:
10+
; CHECK-NEXT: [[SEXT:%.*]] = sext i8 [[ARG]] to i64
11+
; CHECK-NEXT: [[ADD:%.*]] = add i64 [[ARG1]], -1
12+
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[ARG2]] to i64
13+
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[ARG1]], [[TMP0]]
14+
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], [[SEXT]]
15+
; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[TMP2]], -1
16+
; CHECK-NEXT: [[TMP4:%.*]] = shl i64 [[TMP3]], 2
17+
; CHECK-NEXT: br label [[LOOP:%.*]]
18+
; CHECK: loop:
19+
; CHECK-NEXT: [[LOOP_IDIOM_IV:%.*]] = phi ptr [ [[SCEVGEP:%.*]], [[LATCH:%.*]] ], [ [[P]], [[ENTRY:%.*]] ]
20+
; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ [[INDVAR_NEXT:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
21+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[IV_NEXT:%.*]], [[LATCH]] ]
22+
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[ARG2]], [[ENTRY]] ], [ [[ADD9:%.*]], [[LATCH]] ]
23+
; CHECK-NEXT: [[TMP5:%.*]] = shl i64 [[INDVAR]], 2
24+
; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[TMP4]], [[TMP5]]
25+
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[LOOP_IDIOM_IV]], i8 0, i64 0, i1 false)
26+
; CHECK-NEXT: br label [[LOOP2:%.*]]
27+
; CHECK: loop2:
28+
; CHECK-NEXT: [[IV2:%.*]] = phi i64 [ [[IV2_NEXT:%.*]], [[LOOP2]] ], [ 0, [[LOOP]] ]
29+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [4 x i8], ptr [[P]], i64 [[IV]], i64 [[IV2]]
30+
; CHECK-NEXT: [[IV2_NEXT]] = add i64 [[IV2]], 1
31+
; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i64 [[IV2_NEXT]], 0
32+
; CHECK-NEXT: br i1 [[ICMP]], label [[LATCH]], label [[LOOP2]]
33+
; CHECK: latch:
34+
; CHECK-NEXT: [[ADD9]] = add nsw i32 [[PHI]], 1
35+
; CHECK-NEXT: [[SEXT10:%.*]] = sext i32 [[PHI]] to i64
36+
; CHECK-NEXT: [[ADD11:%.*]] = add i64 [[ADD]], [[SEXT10]]
37+
; CHECK-NEXT: [[ADD12:%.*]] = add i64 [[ADD11]], [[SEXT]]
38+
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[ADD12]], [[IV]]
39+
; CHECK-NEXT: [[INDVAR_NEXT]] = add i64 [[INDVAR]], 1
40+
; CHECK-NEXT: [[SCEVGEP]] = getelementptr i8, ptr [[LOOP_IDIOM_IV]], i64 [[TMP6]]
41+
; CHECK-NEXT: br label [[LOOP]]
42+
;
43+
entry:
44+
%sext = sext i8 %arg to i64
45+
%add = add i64 %arg1, -1
46+
br label %loop
47+
48+
loop:
49+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
50+
%phi = phi i32 [ %arg2, %entry ], [ %add9, %latch ]
51+
br label %loop2
52+
53+
loop2:
54+
%iv2 = phi i64 [ %iv2.next, %loop2 ], [ 0, %loop ]
55+
%gep = getelementptr [4 x i8], ptr %p, i64 %iv, i64 %iv2
56+
store i8 0, ptr %gep, align 1
57+
%iv2.next = add i64 %iv2, 1
58+
%icmp = icmp eq i64 %iv2.next, 0
59+
br i1 %icmp, label %latch, label %loop2
60+
61+
latch:
62+
%add9 = add nsw i32 %phi, 1
63+
%sext10 = sext i32 %phi to i64
64+
%add11 = add i64 %add, %sext10
65+
%add12 = add i64 %add11, %sext
66+
%iv.next = add i64 %add12, %iv
67+
br label %loop
68+
}

0 commit comments

Comments
 (0)