44define i1 @ceil_shift4 (i32 %arg0 ) {
55; CHECK-LABEL: define i1 @ceil_shift4(
66; CHECK-SAME: i32 [[ARG0:%.*]]) {
7- ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[ARG0]], 0
7+ ; CHECK-NEXT: [[QUOT:%.*]] = lshr i32 [[ARG0]], 4
8+ ; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 15
9+ ; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne i32 [[REM]], 0
10+ ; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
11+ ; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or i32 [[QUOT]], [[ZEXT_HAS_REM]]
12+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[QUOT_OR_REM]], 0
813; CHECK-NEXT: ret i1 [[TMP1]]
914;
10- %1 = lshr i32 %arg0 , 4
11- %2 = and i32 %arg0 , 15
12- %3 = icmp ne i32 %2 , 0
13- %4 = zext i1 %3 to i32
14- %5 = add i32 %1 , %4
15- %6 = icmp eq i32 %5 , 0
16- ret i1 %6
15+ %quot = lshr i32 %arg0 , 4
16+ %rem = and i32 %arg0 , 15
17+ %has_rem = icmp ne i32 %rem , 0
18+ %zext_has_rem = zext i1 %has_rem to i32
19+ %quot_or_rem = or i32 %quot , %zext_has_rem
20+ %is_zero = icmp eq i32 %quot_or_rem , 0
21+ ret i1 %is_zero
22+ }
23+
24+ define i1 @ceil_shift4_add (i32 %arg0 ) {
25+ ; CHECK-LABEL: define i1 @ceil_shift4_add(
26+ ; CHECK-SAME: i32 [[ARG0:%.*]]) {
27+ ; CHECK-NEXT: [[QUOT:%.*]] = lshr i32 [[ARG0]], 4
28+ ; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 15
29+ ; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne i32 [[REM]], 0
30+ ; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
31+ ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[QUOT]], [[ZEXT_HAS_REM]]
32+ ; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP1]], 0
33+ ; CHECK-NEXT: ret i1 [[TMP6]]
34+ ;
35+ %quot = lshr i32 %arg0 , 4
36+ %rem = and i32 %arg0 , 15
37+ %has_rem = icmp ne i32 %rem , 0
38+ %zext_has_rem = zext i1 %has_rem to i32
39+ %ceil = add i32 %quot , %zext_has_rem
40+ %res = icmp eq i32 %ceil , 0
41+ ret i1 %res
1742}
1843
1944define i1 @ceil_shift6 (i32 %arg0 ) {
2045; CHECK-LABEL: define i1 @ceil_shift6(
2146; CHECK-SAME: i32 [[ARG0:%.*]]) {
22- ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[ARG0]], 0
47+ ; CHECK-NEXT: [[QUOT:%.*]] = lshr i32 [[ARG0]], 6
48+ ; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 63
49+ ; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne i32 [[REM]], 0
50+ ; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
51+ ; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or i32 [[QUOT]], [[ZEXT_HAS_REM]]
52+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[QUOT_OR_REM]], 0
2353; CHECK-NEXT: ret i1 [[TMP1]]
2454;
25- %1 = lshr i32 %arg0 , 6
26- %2 = and i32 %arg0 , 63
27- %3 = icmp ne i32 %2 , 0
28- %4 = zext i1 %3 to i32
29- %5 = add i32 %1 , %4
30- %6 = icmp eq i32 %5 , 0
31- ret i1 %6
55+ %quot = lshr i32 %arg0 , 6
56+ %rem = and i32 %arg0 , 63
57+ %has_rem = icmp ne i32 %rem , 0
58+ %zext_has_rem = zext i1 %has_rem to i32
59+ %quot_or_rem = or i32 %quot , %zext_has_rem
60+ %res = icmp eq i32 %quot_or_rem , 0
61+ ret i1 %res
3262}
3363
3464define i1 @ceil_shift11 (i32 %arg0 ) {
3565; CHECK-LABEL: define i1 @ceil_shift11(
3666; CHECK-SAME: i32 [[ARG0:%.*]]) {
37- ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[ARG0]], 0
67+ ; CHECK-NEXT: [[QUOT:%.*]] = lshr i32 [[ARG0]], 11
68+ ; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 2047
69+ ; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne i32 [[REM]], 0
70+ ; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
71+ ; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or i32 [[QUOT]], [[ZEXT_HAS_REM]]
72+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[QUOT_OR_REM]], 0
3873; CHECK-NEXT: ret i1 [[TMP1]]
3974;
40- %1 = lshr i32 %arg0 , 11
41- %2 = and i32 %arg0 , 2047
42- %3 = icmp ne i32 %2 , 0
43- %4 = zext i1 %3 to i32
44- %5 = add i32 %1 , %4
45- %6 = icmp eq i32 %5 , 0
46- ret i1 %6
75+ %quot = lshr i32 %arg0 , 11
76+ %rem = and i32 %arg0 , 2047
77+ %has_rem = icmp ne i32 %rem , 0
78+ %zext_has_rem = zext i1 %has_rem to i32
79+ %quot_or_rem = or i32 %quot , %zext_has_rem
80+ %res = icmp eq i32 %quot_or_rem , 0
81+ ret i1 %res
4782}
4883
4984define i1 @ceil_shift0 (i32 %arg0 ) {
@@ -52,13 +87,33 @@ define i1 @ceil_shift0(i32 %arg0) {
5287; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[ARG0]], 0
5388; CHECK-NEXT: ret i1 [[TMP1]]
5489;
55- %1 = lshr i32 %arg0 , 0
56- %2 = and i32 %arg0 , 0
57- %3 = icmp ne i32 %2 , 0
58- %4 = zext i1 %3 to i32
59- %5 = add i32 %1 , %4
60- %6 = icmp eq i32 %5 , 0
61- ret i1 %6
90+ %quot = lshr i32 %arg0 , 0
91+ %rem = and i32 %arg0 , 0
92+ %has_rem = icmp ne i32 %rem , 0
93+ %zext_has_rem = zext i1 %has_rem to i32
94+ %quot_or_rem = or i32 %quot , %zext_has_rem
95+ %res = icmp eq i32 %quot_or_rem , 0
96+ ret i1 %res
97+ }
98+
99+ define i1 @ceil_shift4_comm (i32 %arg0 ) {
100+ ; CHECK-LABEL: define i1 @ceil_shift4_comm(
101+ ; CHECK-SAME: i32 [[ARG0:%.*]]) {
102+ ; CHECK-NEXT: [[QUOT:%.*]] = lshr i32 [[ARG0]], 4
103+ ; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 15
104+ ; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne i32 [[REM]], 0
105+ ; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
106+ ; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or i32 [[QUOT]], [[ZEXT_HAS_REM]]
107+ ; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[QUOT_OR_REM]], 0
108+ ; CHECK-NEXT: ret i1 [[TMP6]]
109+ ;
110+ %quot = lshr i32 %arg0 , 4
111+ %rem = and i32 %arg0 , 15
112+ %has_rem = icmp ne i32 %rem , 0
113+ %zext_has_rem = zext i1 %has_rem to i32
114+ %quot_or_rem = or i32 %zext_has_rem , %quot
115+ %res = icmp eq i32 %quot_or_rem , 0
116+ ret i1 %res
62117}
63118
64119declare void @use (i32 )
@@ -68,17 +123,21 @@ define i1 @ceil_shift4_used_1(i32 %arg0) {
68123; CHECK-SAME: i32 [[ARG0:%.*]]) {
69124; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[ARG0]], 4
70125; CHECK-NEXT: call void @use(i32 [[TMP1]])
71- ; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[ARG0]], 0
126+ ; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 15
127+ ; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne i32 [[REM]], 0
128+ ; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
129+ ; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or i32 [[TMP1]], [[ZEXT_HAS_REM]]
130+ ; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[QUOT_OR_REM]], 0
72131; CHECK-NEXT: ret i1 [[TMP6]]
73132;
74- %1 = lshr i32 %arg0 , 4
75- call void @use (i32 %1 )
76- %2 = and i32 %arg0 , 15
77- %3 = icmp ne i32 %2 , 0
78- %4 = zext i1 %3 to i32
79- %5 = add i32 %1 , %4
80- %6 = icmp eq i32 %5 , 0
81- ret i1 %6
133+ %quot = lshr i32 %arg0 , 4
134+ call void @use (i32 %quot )
135+ %rem = and i32 %arg0 , 15
136+ %has_rem = icmp ne i32 %rem , 0
137+ %zext_has_rem = zext i1 %has_rem to i32
138+ %quot_or_rem = or i32 %quot , %zext_has_rem
139+ %res = icmp eq i32 %quot_or_rem , 0
140+ ret i1 %res
82141}
83142
84143define i1 @ceil_shift4_used_5 (i32 %arg0 ) {
@@ -88,49 +147,59 @@ define i1 @ceil_shift4_used_5(i32 %arg0) {
88147; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[ARG0]], 15
89148; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
90149; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
91- ; CHECK-NEXT: [[TMP5:%.*]] = add nuw nsw i32 [[TMP1]], [[TMP4]]
150+ ; CHECK-NEXT: [[TMP5:%.*]] = or i32 [[TMP1]], [[TMP4]]
92151; CHECK-NEXT: call void @use(i32 [[TMP5]])
93152; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0
94153; CHECK-NEXT: ret i1 [[TMP6]]
95154;
96- %1 = lshr i32 %arg0 , 4
97- %2 = and i32 %arg0 , 15
98- %3 = icmp ne i32 %2 , 0
99- %4 = zext i1 %3 to i32
100- %5 = add i32 %1 , %4
101- call void @use (i32 %5 )
102- %6 = icmp eq i32 %5 , 0
103- ret i1 %6
155+ %quot = lshr i32 %arg0 , 4
156+ %rem = and i32 %arg0 , 15
157+ %has_rem = icmp ne i32 %rem , 0
158+ %zext_has_rem = zext i1 %has_rem to i32
159+ %quot_or_rem = or i32 %quot , %zext_has_rem
160+ call void @use (i32 %quot_or_rem )
161+ %res = icmp eq i32 %quot_or_rem , 0
162+ ret i1 %res
104163}
105164
106165define <4 x i1 > @ceil_shift4_v4i32 (<4 x i32 > %arg0 ) {
107166; CHECK-LABEL: define <4 x i1> @ceil_shift4_v4i32(
108167; CHECK-SAME: <4 x i32> [[ARG0:%.*]]) {
109- ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[ARG0]], zeroinitializer
168+ ; CHECK-NEXT: [[QUOT:%.*]] = lshr <4 x i32> [[ARG0]], splat (i32 16)
169+ ; CHECK-NEXT: [[REM:%.*]] = and <4 x i32> [[ARG0]], splat (i32 65535)
170+ ; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne <4 x i32> [[REM]], zeroinitializer
171+ ; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext <4 x i1> [[HAS_REM]] to <4 x i32>
172+ ; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or <4 x i32> [[QUOT]], [[ZEXT_HAS_REM]]
173+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[QUOT_OR_REM]], zeroinitializer
110174; CHECK-NEXT: ret <4 x i1> [[TMP1]]
111175;
112- %1 = lshr <4 x i32 > %arg0 , splat (i32 16 )
113- %2 = and <4 x i32 > %arg0 , splat (i32 65535 )
114- %3 = icmp ne <4 x i32 > %2 , zeroinitializer
115- %4 = zext <4 x i1 > %3 to <4 x i32 >
116- %5 = add <4 x i32 > %1 , %4
117- %6 = icmp eq <4 x i32 > %5 , zeroinitializer
118- ret <4 x i1 > %6
176+ %quot = lshr <4 x i32 > %arg0 , splat (i32 16 )
177+ %rem = and <4 x i32 > %arg0 , splat (i32 65535 )
178+ %has_rem = icmp ne <4 x i32 > %rem , zeroinitializer
179+ %zext_has_rem = zext <4 x i1 > %has_rem to <4 x i32 >
180+ %quot_or_rem = or <4 x i32 > %quot , %zext_has_rem
181+ %res = icmp eq <4 x i32 > %quot_or_rem , zeroinitializer
182+ ret <4 x i1 > %res
119183}
120184
121185define <8 x i1 > @ceil_shift4_v8i16 (<8 x i16 > %arg0 ) {
122186; CHECK-LABEL: define <8 x i1> @ceil_shift4_v8i16(
123187; CHECK-SAME: <8 x i16> [[ARG0:%.*]]) {
124- ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <8 x i16> [[ARG0]], zeroinitializer
188+ ; CHECK-NEXT: [[QUOT:%.*]] = lshr <8 x i16> [[ARG0]], splat (i16 4)
189+ ; CHECK-NEXT: [[REM:%.*]] = and <8 x i16> [[ARG0]], splat (i16 15)
190+ ; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne <8 x i16> [[REM]], zeroinitializer
191+ ; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext <8 x i1> [[HAS_REM]] to <8 x i16>
192+ ; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or <8 x i16> [[QUOT]], [[ZEXT_HAS_REM]]
193+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <8 x i16> [[QUOT_OR_REM]], zeroinitializer
125194; CHECK-NEXT: ret <8 x i1> [[TMP1]]
126195;
127- %1 = lshr <8 x i16 > %arg0 , splat (i16 4 )
128- %2 = and <8 x i16 > %arg0 , splat (i16 15 )
129- %3 = icmp ne <8 x i16 > %2 , zeroinitializer
130- %4 = zext <8 x i1 > %3 to <8 x i16 >
131- %5 = add <8 x i16 > %1 , %4
132- %6 = icmp eq <8 x i16 > %5 , zeroinitializer
133- ret <8 x i1 > %6
196+ %quot = lshr <8 x i16 > %arg0 , splat (i16 4 )
197+ %rem = and <8 x i16 > %arg0 , splat (i16 15 )
198+ %has_rem = icmp ne <8 x i16 > %rem , zeroinitializer
199+ %zext_has_rem = zext <8 x i1 > %has_rem to <8 x i16 >
200+ %quot_or_rem = or <8 x i16 > %quot , %zext_has_rem
201+ %res = icmp eq <8 x i16 > %quot_or_rem , zeroinitializer
202+ ret <8 x i1 > %res
134203}
135204
136205; negative tests
@@ -146,13 +215,13 @@ define i1 @ceil_shift_not_mask_1(i32 %arg0) {
146215; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0
147216; CHECK-NEXT: ret i1 [[TMP6]]
148217;
149- %1 = lshr i32 %arg0 , 4
150- %2 = and i32 %arg0 , 31
151- %3 = icmp ne i32 %2 , 0
152- %4 = zext i1 %3 to i32
153- %5 = add i32 %1 , %4
154- %6 = icmp eq i32 %5 , 0
155- ret i1 %6
218+ %quot = lshr i32 %arg0 , 4
219+ %rem = and i32 %arg0 , 31
220+ %has_rem = icmp ne i32 %rem , 0
221+ %zext_has_rem = zext i1 %has_rem to i32
222+ %quot_or_rem = or i32 %quot , %zext_has_rem
223+ %res = icmp eq i32 %quot_or_rem , 0
224+ ret i1 %res
156225}
157226
158227define i1 @ceil_shift_not_mask_2 (i32 %arg0 ) {
@@ -166,11 +235,11 @@ define i1 @ceil_shift_not_mask_2(i32 %arg0) {
166235; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0
167236; CHECK-NEXT: ret i1 [[TMP6]]
168237;
169- %1 = lshr i32 %arg0 , 5
170- %2 = and i32 %arg0 , 15
171- %3 = icmp ne i32 %2 , 0
172- %4 = zext i1 %3 to i32
173- %5 = add i32 %1 , %4
174- %6 = icmp eq i32 %5 , 0
175- ret i1 %6
238+ %quot = lshr i32 %arg0 , 5
239+ %rem = and i32 %arg0 , 15
240+ %has_rem = icmp ne i32 %rem , 0
241+ %zext_has_rem = zext i1 %has_rem to i32
242+ %quot_or_rem = or i32 %quot , %zext_has_rem
243+ %res = icmp eq i32 %quot_or_rem , 0
244+ ret i1 %res
176245}
0 commit comments