Skip to content

Commit 45a2214

Browse files
committed
[SCEV] Add tests for folding multiply/divide by constants.
Add extra test coverage for follow-up to #156730.
1 parent ea0f6e6 commit 45a2214

File tree

1 file changed

+187
-0
lines changed

1 file changed

+187
-0
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -passes='print<scalar-evolution>' -disable-output %s 2>&1 | FileCheck %s
3+
4+
declare void @use(ptr)
5+
6+
define void @udiv4_and_udiv2_mul_4(i1 %c, ptr %A) {
7+
; CHECK-LABEL: 'udiv4_and_udiv2_mul_4'
8+
; CHECK-NEXT: Classifying expressions for: @udiv4_and_udiv2_mul_4
9+
; CHECK-NEXT: %start = select i1 %c, i32 512, i32 0
10+
; CHECK-NEXT: --> %start U: [0,513) S: [0,513)
11+
; CHECK-NEXT: %div.2 = lshr i32 %start, 1
12+
; CHECK-NEXT: --> (%start /u 2) U: [0,257) S: [0,257)
13+
; CHECK-NEXT: %div.4 = lshr i32 %start, 2
14+
; CHECK-NEXT: --> (%start /u 4) U: [0,129) S: [0,129)
15+
; CHECK-NEXT: %iv.start = zext i32 %div.4 to i64
16+
; CHECK-NEXT: --> ((zext i32 %start to i64) /u 4) U: [0,129) S: [0,129)
17+
; CHECK-NEXT: %wide.trip.count = zext i32 %div.2 to i64
18+
; CHECK-NEXT: --> ((zext i32 %start to i64) /u 2) U: [0,257) S: [0,257)
19+
; CHECK-NEXT: %iv = phi i64 [ %iv.start, %entry ], [ %iv.next, %loop ]
20+
; CHECK-NEXT: --> {((zext i32 %start to i64) /u 4),+,1}<%loop> U: full-set S: full-set Exits: ((zext i32 %start to i64) /u 2) LoopDispositions: { %loop: Computable }
21+
; CHECK-NEXT: %gep = getelementptr i32, ptr %A, i64 %iv
22+
; CHECK-NEXT: --> {((zext i32 %start to i64) + %A),+,4}<%loop> U: full-set S: full-set Exits: ((zext i32 %start to i64) + (4 * ((zext i32 %start to i64) /u 2))<nuw><nsw> + (-4 * ((zext i32 %start to i64) /u 4))<nsw> + %A) LoopDispositions: { %loop: Computable }
23+
; CHECK-NEXT: %iv.next = add i64 %iv, 1
24+
; CHECK-NEXT: --> {(1 + ((zext i32 %start to i64) /u 4))<nuw><nsw>,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((zext i32 %start to i64) /u 2))<nuw><nsw> LoopDispositions: { %loop: Computable }
25+
; CHECK-NEXT: Determining loop execution counts for: @udiv4_and_udiv2_mul_4
26+
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * ((zext i32 %start to i64) /u 4))<nsw> + ((zext i32 %start to i64) /u 2))
27+
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1
28+
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * ((zext i32 %start to i64) /u 4))<nsw> + ((zext i32 %start to i64) /u 2))
29+
; CHECK-NEXT: Loop %loop: Trip multiple is 1
30+
;
31+
entry:
32+
%start = select i1 %c, i32 512, i32 0
33+
%div.2 = lshr i32 %start, 1
34+
%div.4 = lshr i32 %start, 2
35+
%iv.start = zext i32 %div.4 to i64
36+
%wide.trip.count = zext i32 %div.2 to i64
37+
br label %loop
38+
39+
loop:
40+
%iv = phi i64 [ %iv.start, %entry ], [ %iv.next, %loop ]
41+
%gep = getelementptr i32, ptr %A, i64 %iv
42+
call void @use(ptr %gep)
43+
%iv.next = add i64 %iv, 1
44+
%ec = icmp eq i64 %iv, %wide.trip.count
45+
br i1 %ec, label %exit, label %loop
46+
47+
exit:
48+
ret void
49+
}
50+
51+
define void @udiv4_and_udiv2_mul_1(i1 %c, ptr %A) {
52+
; CHECK-LABEL: 'udiv4_and_udiv2_mul_1'
53+
; CHECK-NEXT: Classifying expressions for: @udiv4_and_udiv2_mul_1
54+
; CHECK-NEXT: %start = select i1 %c, i32 512, i32 0
55+
; CHECK-NEXT: --> %start U: [0,513) S: [0,513)
56+
; CHECK-NEXT: %div.2 = lshr i32 %start, 1
57+
; CHECK-NEXT: --> (%start /u 2) U: [0,257) S: [0,257)
58+
; CHECK-NEXT: %div.4 = lshr i32 %start, 2
59+
; CHECK-NEXT: --> (%start /u 4) U: [0,129) S: [0,129)
60+
; CHECK-NEXT: %iv.start = zext i32 %div.4 to i64
61+
; CHECK-NEXT: --> ((zext i32 %start to i64) /u 4) U: [0,129) S: [0,129)
62+
; CHECK-NEXT: %wide.trip.count = zext i32 %div.2 to i64
63+
; CHECK-NEXT: --> ((zext i32 %start to i64) /u 2) U: [0,257) S: [0,257)
64+
; CHECK-NEXT: %iv = phi i64 [ %iv.start, %entry ], [ %iv.next, %loop ]
65+
; CHECK-NEXT: --> {((zext i32 %start to i64) /u 4),+,1}<%loop> U: full-set S: full-set Exits: ((zext i32 %start to i64) /u 2) LoopDispositions: { %loop: Computable }
66+
; CHECK-NEXT: %gep = getelementptr i8, ptr %A, i64 %iv
67+
; CHECK-NEXT: --> {(((zext i32 %start to i64) /u 4) + %A),+,1}<%loop> U: full-set S: full-set Exits: (((zext i32 %start to i64) /u 2) + %A) LoopDispositions: { %loop: Computable }
68+
; CHECK-NEXT: %iv.next = add i64 %iv, 1
69+
; CHECK-NEXT: --> {(1 + ((zext i32 %start to i64) /u 4))<nuw><nsw>,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((zext i32 %start to i64) /u 2))<nuw><nsw> LoopDispositions: { %loop: Computable }
70+
; CHECK-NEXT: Determining loop execution counts for: @udiv4_and_udiv2_mul_1
71+
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * ((zext i32 %start to i64) /u 4))<nsw> + ((zext i32 %start to i64) /u 2))
72+
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1
73+
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * ((zext i32 %start to i64) /u 4))<nsw> + ((zext i32 %start to i64) /u 2))
74+
; CHECK-NEXT: Loop %loop: Trip multiple is 1
75+
;
76+
entry:
77+
%start = select i1 %c, i32 512, i32 0
78+
%div.2 = lshr i32 %start, 1
79+
%div.4 = lshr i32 %start, 2
80+
%iv.start = zext i32 %div.4 to i64
81+
%wide.trip.count = zext i32 %div.2 to i64
82+
br label %loop
83+
84+
loop:
85+
%iv = phi i64 [ %iv.start, %entry ], [ %iv.next, %loop ]
86+
%gep = getelementptr i8, ptr %A, i64 %iv
87+
call void @use(ptr %gep)
88+
%iv.next = add i64 %iv, 1
89+
%ec = icmp eq i64 %iv, %wide.trip.count
90+
br i1 %ec, label %exit, label %loop
91+
92+
exit:
93+
ret void
94+
}
95+
96+
97+
define void @udiv3_and_udiv5_mul_4(i1 %c, ptr %A) {
98+
; CHECK-LABEL: 'udiv3_and_udiv5_mul_4'
99+
; CHECK-NEXT: Classifying expressions for: @udiv3_and_udiv5_mul_4
100+
; CHECK-NEXT: %start = select i1 %c, i32 512, i32 0
101+
; CHECK-NEXT: --> %start U: [0,513) S: [0,513)
102+
; CHECK-NEXT: %div.3 = udiv i32 %start, 3
103+
; CHECK-NEXT: --> (%start /u 3) U: [0,171) S: [0,171)
104+
; CHECK-NEXT: %div.5 = udiv i32 %start, 5
105+
; CHECK-NEXT: --> (%start /u 5) U: [0,103) S: [0,103)
106+
; CHECK-NEXT: %iv.start = zext i32 %div.5 to i64
107+
; CHECK-NEXT: --> ((zext i32 %start to i64) /u 5) U: [0,103) S: [0,103)
108+
; CHECK-NEXT: %wide.trip.count = zext i32 %div.3 to i64
109+
; CHECK-NEXT: --> ((zext i32 %start to i64) /u 3) U: [0,171) S: [0,171)
110+
; CHECK-NEXT: %iv = phi i64 [ %iv.start, %entry ], [ %iv.next, %loop ]
111+
; CHECK-NEXT: --> {((zext i32 %start to i64) /u 5),+,1}<%loop> U: full-set S: full-set Exits: ((zext i32 %start to i64) /u 3) LoopDispositions: { %loop: Computable }
112+
; CHECK-NEXT: %gep = getelementptr i8, ptr %A, i64 %iv
113+
; CHECK-NEXT: --> {(((zext i32 %start to i64) /u 5) + %A),+,1}<%loop> U: full-set S: full-set Exits: (((zext i32 %start to i64) /u 3) + %A) LoopDispositions: { %loop: Computable }
114+
; CHECK-NEXT: %iv.next = add i64 %iv, 1
115+
; CHECK-NEXT: --> {(1 + ((zext i32 %start to i64) /u 5))<nuw><nsw>,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((zext i32 %start to i64) /u 3))<nuw><nsw> LoopDispositions: { %loop: Computable }
116+
; CHECK-NEXT: Determining loop execution counts for: @udiv3_and_udiv5_mul_4
117+
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * ((zext i32 %start to i64) /u 5))<nsw> + ((zext i32 %start to i64) /u 3))
118+
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1
119+
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * ((zext i32 %start to i64) /u 5))<nsw> + ((zext i32 %start to i64) /u 3))
120+
; CHECK-NEXT: Loop %loop: Trip multiple is 1
121+
;
122+
entry:
123+
%start = select i1 %c, i32 512, i32 0
124+
%div.3 = udiv i32 %start, 3
125+
%div.5 = udiv i32 %start, 5
126+
%iv.start = zext i32 %div.5 to i64
127+
%wide.trip.count = zext i32 %div.3 to i64
128+
br label %loop
129+
130+
loop:
131+
%iv = phi i64 [ %iv.start, %entry ], [ %iv.next, %loop ]
132+
%gep = getelementptr i8, ptr %A, i64 %iv
133+
call void @use(ptr %gep)
134+
%iv.next = add i64 %iv, 1
135+
%ec = icmp eq i64 %iv, %wide.trip.count
136+
br i1 %ec, label %exit, label %loop
137+
138+
exit:
139+
ret void
140+
}
141+
142+
define void @udiv4_and_udiv2_mul_4_dividend_multiple_of_2(i1 %c, ptr %A) {
143+
; CHECK-LABEL: 'udiv4_and_udiv2_mul_4_dividend_multiple_of_2'
144+
; CHECK-NEXT: Classifying expressions for: @udiv4_and_udiv2_mul_4_dividend_multiple_of_2
145+
; CHECK-NEXT: %start = select i1 %c, i32 514, i32 0
146+
; CHECK-NEXT: --> %start U: [0,515) S: [0,515)
147+
; CHECK-NEXT: %div.2 = lshr i32 %start, 1
148+
; CHECK-NEXT: --> (%start /u 2) U: [0,258) S: [0,258)
149+
; CHECK-NEXT: %div.4 = lshr i32 %start, 2
150+
; CHECK-NEXT: --> (%start /u 4) U: [0,129) S: [0,129)
151+
; CHECK-NEXT: %iv.start = zext i32 %div.4 to i64
152+
; CHECK-NEXT: --> ((zext i32 %start to i64) /u 4) U: [0,129) S: [0,129)
153+
; CHECK-NEXT: %wide.trip.count = zext i32 %div.2 to i64
154+
; CHECK-NEXT: --> ((zext i32 %start to i64) /u 2) U: [0,258) S: [0,258)
155+
; CHECK-NEXT: %iv = phi i64 [ %iv.start, %entry ], [ %iv.next, %loop ]
156+
; CHECK-NEXT: --> {((zext i32 %start to i64) /u 4),+,1}<%loop> U: full-set S: full-set Exits: ((zext i32 %start to i64) /u 2) LoopDispositions: { %loop: Computable }
157+
; CHECK-NEXT: %gep = getelementptr i32, ptr %A, i64 %iv
158+
; CHECK-NEXT: --> {((4 * ((zext i32 %start to i64) /u 4))<nuw><nsw> + %A),+,4}<%loop> U: full-set S: full-set Exits: ((4 * ((zext i32 %start to i64) /u 2))<nuw><nsw> + %A) LoopDispositions: { %loop: Computable }
159+
; CHECK-NEXT: %iv.next = add i64 %iv, 1
160+
; CHECK-NEXT: --> {(1 + ((zext i32 %start to i64) /u 4))<nuw><nsw>,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((zext i32 %start to i64) /u 2))<nuw><nsw> LoopDispositions: { %loop: Computable }
161+
; CHECK-NEXT: Determining loop execution counts for: @udiv4_and_udiv2_mul_4_dividend_multiple_of_2
162+
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * ((zext i32 %start to i64) /u 4))<nsw> + ((zext i32 %start to i64) /u 2))
163+
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1
164+
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * ((zext i32 %start to i64) /u 4))<nsw> + ((zext i32 %start to i64) /u 2))
165+
; CHECK-NEXT: Loop %loop: Trip multiple is 1
166+
;
167+
entry:
168+
%start = select i1 %c, i32 514, i32 0
169+
%div.2 = lshr i32 %start, 1
170+
%div.4 = lshr i32 %start, 2
171+
%iv.start = zext i32 %div.4 to i64
172+
%wide.trip.count = zext i32 %div.2 to i64
173+
br label %loop
174+
175+
loop:
176+
%iv = phi i64 [ %iv.start, %entry ], [ %iv.next, %loop ]
177+
%gep = getelementptr i32, ptr %A, i64 %iv
178+
call void @use(ptr %gep)
179+
%iv.next = add i64 %iv, 1
180+
%ec = icmp eq i64 %iv, %wide.trip.count
181+
br i1 %ec, label %exit, label %loop
182+
183+
exit:
184+
ret void
185+
}
186+
187+

0 commit comments

Comments
 (0)