Skip to content

Commit dec652f

Browse files
author
v01dxyz
committed
[LoopUnroll] pre-commit test for LoopPeel SCEV invalidation
Warning this test passes only with asserts disabled. Otherwise the following assertion failure occurs: Assertion `isAvailableAtLoopEntry(Operands[i], L) && "SCEVAddRecExpr operand is not available at loop entry!"' failed.
1 parent d82945c commit dec652f

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
; RUN: opt < %s -S -passes='print<scalar-evolution>,loop-unroll<peeling;full-unroll-max=0>,print<scalar-evolution>' 2>&1 | FileCheck %s
2+
;
3+
; This test ensures that (extractvalue 0 (with-overflow-inst op0, op1))
4+
; is invalidated by LoopPeel when the operands of with-overflow-inst
5+
; are changed.
6+
;
7+
; In the following case, LoopPeel modifies the CFG into another one
8+
; with %bb7 not dominating %bb2 and %bb3 although %extractvalue is
9+
; still the step for the %bb3 loop. %call has been modified and uses
10+
; different operands but the SCEV value for %extractvalue has not been
11+
; invalidated and still refers to %load in its SCEV operands
12+
; (SCEV(%extractvalue) := -2 + -2 * %load).
13+
;
14+
; When LoopUnroll tries to compute the SCEV for the %bb3 Phi, the
15+
; stale data for %extractvalue is used whereas %load is not available
16+
; in %bb3 which is wrong.
17+
;
18+
; for more details and nice pictures: https://github.com/llvm/llvm-project/issues/97586
19+
;
20+
; Although the reason for the bug was in forgetValue, it is still relevant to
21+
; test if LoopPeel invalidates %extractvalue after changing %call.
22+
;
23+
; forgetValue only walks the users, so calling it on the IV Phis does not
24+
; invalidate %extractvalue (thus forgetLoop does not invalidate it too).
25+
; It has to be done by LoopPeel itself.
26+
27+
28+
define void @loop_peeling_smul_with_overflow() {
29+
; before loop-unroll
30+
; CHECK: Classifying expressions for: @loop_peeling_smul_with_overflow
31+
; CHECK: %extractvalue = extractvalue { i32, i1 } %call, 0
32+
; CHECK-NEXT: --> (-2 + (-2 * %load))
33+
; CHECK: %phi4 = phi i32 [ %add, %bb3 ], [ 0, %bb2 ]
34+
; CHECK-NEXT: --> {0,+,(-2 + (-2 * %load))}<nuw><nsw><%bb3>
35+
; after loop-unroll
36+
; CHECK: Classifying expressions for: @loop_peeling_smul_with_overflow
37+
; CHECK: %extractvalue = extractvalue { i32, i1 } %call, 0
38+
; CHECK-NEXT: --> (-2 + (-2 * %load))
39+
; CHECK: %phi4 = phi i32 [ %add, %bb3 ], [ 0, %bb2 ]
40+
; CHECK-NEXT: --> {0,+,(-2 + (-2 * %load))}<nuw><nsw><%bb3>
41+
;
42+
bb:
43+
br label %bb1
44+
45+
bb1: ; preds = %bb3, %bb
46+
%phi = phi i32 [ 0, %bb ], [ %phi4, %bb3 ]
47+
br label %bb5
48+
49+
bb2: ; preds = %bb7
50+
%call = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %add8, i32 -2)
51+
%extractvalue = extractvalue { i32, i1 } %call, 0
52+
br label %bb3
53+
54+
bb3: ; preds = %bb3, %bb2
55+
%phi4 = phi i32 [ %add, %bb3 ], [ 0, %bb2 ]
56+
%add = add i32 %extractvalue, %phi4
57+
br i1 false, label %bb3, label %bb1
58+
59+
bb5: ; preds = %bb7, %bb1
60+
%phi6 = phi i32 [ 1, %bb1 ], [ 0, %bb7 ]
61+
%icmp = icmp eq i32 %phi, 0
62+
br i1 %icmp, label %bb9, label %bb7
63+
64+
bb7: ; preds = %bb5
65+
%load = load i32, ptr addrspace(1) null, align 4
66+
%add8 = add i32 %load, 1
67+
br i1 false, label %bb2, label %bb5
68+
69+
bb9: ; preds = %bb5
70+
ret void
71+
}
72+
73+
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
74+
declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32) #0
75+
76+
attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

0 commit comments

Comments
 (0)