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;
1015 %quot = lshr i32 %arg0 , 4
@@ -19,7 +24,12 @@ define i1 @ceil_shift4(i32 %arg0) {
1924define i1 @ceil_shift4_add (i32 %arg0 ) {
2025; CHECK-LABEL: define i1 @ceil_shift4_add(
2126; CHECK-SAME: i32 [[ARG0:%.*]]) {
22- ; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[ARG0]], 0
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
2333; CHECK-NEXT: ret i1 [[TMP6]]
2434;
2535 %quot = lshr i32 %arg0 , 4
@@ -34,7 +44,12 @@ define i1 @ceil_shift4_add(i32 %arg0) {
3444define i1 @ceil_shift6 (i32 %arg0 ) {
3545; CHECK-LABEL: define i1 @ceil_shift6(
3646; CHECK-SAME: i32 [[ARG0:%.*]]) {
37- ; 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
3853; CHECK-NEXT: ret i1 [[TMP1]]
3954;
4055 %quot = lshr i32 %arg0 , 6
@@ -49,7 +64,12 @@ define i1 @ceil_shift6(i32 %arg0) {
4964define i1 @ceil_shift6_ne (i32 %arg0 ) {
5065; CHECK-LABEL: define i1 @ceil_shift6_ne(
5166; CHECK-SAME: i32 [[ARG0:%.*]]) {
52- ; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[ARG0]], 0
67+ ; CHECK-NEXT: [[QUOT:%.*]] = lshr i32 [[ARG0]], 6
68+ ; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 63
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: [[RES:%.*]] = icmp ne i32 [[QUOT_OR_REM]], 0
5373; CHECK-NEXT: ret i1 [[RES]]
5474;
5575 %quot = lshr i32 %arg0 , 6
@@ -64,7 +84,12 @@ define i1 @ceil_shift6_ne(i32 %arg0) {
6484define i1 @ceil_shift11 (i32 %arg0 ) {
6585; CHECK-LABEL: define i1 @ceil_shift11(
6686; CHECK-SAME: i32 [[ARG0:%.*]]) {
67- ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[ARG0]], 0
87+ ; CHECK-NEXT: [[QUOT:%.*]] = lshr i32 [[ARG0]], 11
88+ ; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 2047
89+ ; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne i32 [[REM]], 0
90+ ; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
91+ ; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or i32 [[QUOT]], [[ZEXT_HAS_REM]]
92+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[QUOT_OR_REM]], 0
6893; CHECK-NEXT: ret i1 [[TMP1]]
6994;
7095 %quot = lshr i32 %arg0 , 11
@@ -79,7 +104,12 @@ define i1 @ceil_shift11(i32 %arg0) {
79104define i1 @ceil_shift11_ne (i32 %arg0 ) {
80105; CHECK-LABEL: define i1 @ceil_shift11_ne(
81106; CHECK-SAME: i32 [[ARG0:%.*]]) {
82- ; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[ARG0]], 0
107+ ; CHECK-NEXT: [[QUOT:%.*]] = lshr i32 [[ARG0]], 6
108+ ; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 63
109+ ; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne i32 [[REM]], 0
110+ ; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
111+ ; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or i32 [[QUOT]], [[ZEXT_HAS_REM]]
112+ ; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[QUOT_OR_REM]], 0
83113; CHECK-NEXT: ret i1 [[RES]]
84114;
85115 %quot = lshr i32 %arg0 , 6
@@ -109,7 +139,12 @@ define i1 @ceil_shift0(i32 %arg0) {
109139define i1 @ceil_shift4_comm (i32 %arg0 ) {
110140; CHECK-LABEL: define i1 @ceil_shift4_comm(
111141; CHECK-SAME: i32 [[ARG0:%.*]]) {
112- ; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[ARG0]], 0
142+ ; CHECK-NEXT: [[QUOT:%.*]] = lshr i32 [[ARG0]], 4
143+ ; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 15
144+ ; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne i32 [[REM]], 0
145+ ; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
146+ ; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or i32 [[QUOT]], [[ZEXT_HAS_REM]]
147+ ; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[QUOT_OR_REM]], 0
113148; CHECK-NEXT: ret i1 [[TMP6]]
114149;
115150 %quot = lshr i32 %arg0 , 4
@@ -128,7 +163,11 @@ define i1 @ceil_shift4_used_1(i32 %arg0) {
128163; CHECK-SAME: i32 [[ARG0:%.*]]) {
129164; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[ARG0]], 4
130165; CHECK-NEXT: call void @use(i32 [[TMP1]])
131- ; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[ARG0]], 0
166+ ; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 15
167+ ; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne i32 [[REM]], 0
168+ ; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
169+ ; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or i32 [[TMP1]], [[ZEXT_HAS_REM]]
170+ ; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[QUOT_OR_REM]], 0
132171; CHECK-NEXT: ret i1 [[TMP6]]
133172;
134173 %quot = lshr i32 %arg0 , 4
@@ -163,10 +202,37 @@ define i1 @ceil_shift4_used_5(i32 %arg0) {
163202 ret i1 %res
164203}
165204
205+ define i1 @ceil_shift4_used_add_nuw_nsw (i32 %arg0 ) {
206+ ; CHECK-LABEL: define i1 @ceil_shift4_used_add_nuw_nsw(
207+ ; CHECK-SAME: i32 [[ARG0:%.*]]) {
208+ ; CHECK-NEXT: [[QUOT:%.*]] = lshr i32 [[ARG0]], 4
209+ ; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 15
210+ ; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne i32 [[REM]], 0
211+ ; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext i1 [[HAS_REM]] to i32
212+ ; CHECK-NEXT: [[CEIL:%.*]] = add nuw nsw i32 [[QUOT]], [[ZEXT_HAS_REM]]
213+ ; CHECK-NEXT: call void @use(i32 [[CEIL]])
214+ ; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[CEIL]], 0
215+ ; CHECK-NEXT: ret i1 [[RES]]
216+ ;
217+ %quot = lshr i32 %arg0 , 4
218+ %rem = and i32 %arg0 , 15
219+ %has_rem = icmp ne i32 %rem , 0
220+ %zext_has_rem = zext i1 %has_rem to i32
221+ %ceil = add nuw nsw i32 %quot , %zext_has_rem
222+ call void @use (i32 %ceil )
223+ %res = icmp eq i32 %ceil , 0
224+ ret i1 %res
225+ }
226+
166227define <4 x i1 > @ceil_shift4_v4i32 (<4 x i32 > %arg0 ) {
167228; CHECK-LABEL: define <4 x i1> @ceil_shift4_v4i32(
168229; CHECK-SAME: <4 x i32> [[ARG0:%.*]]) {
169- ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[ARG0]], zeroinitializer
230+ ; CHECK-NEXT: [[QUOT:%.*]] = lshr <4 x i32> [[ARG0]], splat (i32 16)
231+ ; CHECK-NEXT: [[REM:%.*]] = and <4 x i32> [[ARG0]], splat (i32 65535)
232+ ; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne <4 x i32> [[REM]], zeroinitializer
233+ ; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext <4 x i1> [[HAS_REM]] to <4 x i32>
234+ ; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or <4 x i32> [[QUOT]], [[ZEXT_HAS_REM]]
235+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[QUOT_OR_REM]], zeroinitializer
170236; CHECK-NEXT: ret <4 x i1> [[TMP1]]
171237;
172238 %quot = lshr <4 x i32 > %arg0 , splat (i32 16 )
@@ -181,7 +247,12 @@ define <4 x i1> @ceil_shift4_v4i32(<4 x i32> %arg0) {
181247define <8 x i1 > @ceil_shift4_v8i16 (<8 x i16 > %arg0 ) {
182248; CHECK-LABEL: define <8 x i1> @ceil_shift4_v8i16(
183249; CHECK-SAME: <8 x i16> [[ARG0:%.*]]) {
184- ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <8 x i16> [[ARG0]], zeroinitializer
250+ ; CHECK-NEXT: [[QUOT:%.*]] = lshr <8 x i16> [[ARG0]], splat (i16 4)
251+ ; CHECK-NEXT: [[REM:%.*]] = and <8 x i16> [[ARG0]], splat (i16 15)
252+ ; CHECK-NEXT: [[HAS_REM:%.*]] = icmp ne <8 x i16> [[REM]], zeroinitializer
253+ ; CHECK-NEXT: [[ZEXT_HAS_REM:%.*]] = zext <8 x i1> [[HAS_REM]] to <8 x i16>
254+ ; CHECK-NEXT: [[QUOT_OR_REM:%.*]] = or <8 x i16> [[QUOT]], [[ZEXT_HAS_REM]]
255+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <8 x i16> [[QUOT_OR_REM]], zeroinitializer
185256; CHECK-NEXT: ret <8 x i1> [[TMP1]]
186257;
187258 %quot = lshr <8 x i16 > %arg0 , splat (i16 4 )
@@ -234,3 +305,23 @@ define i1 @ceil_shift_not_mask_2(i32 %arg0) {
234305 %res = icmp eq i32 %quot_or_rem , 0
235306 ret i1 %res
236307}
308+
309+ define i1 @ceil_shift_not_add_or (i32 %arg0 ) {
310+ ; CHECK-LABEL: define i1 @ceil_shift_not_add_or(
311+ ; CHECK-SAME: i32 [[ARG0:%.*]]) {
312+ ; CHECK-NEXT: [[REM:%.*]] = and i32 [[ARG0]], 15
313+ ; CHECK-NEXT: [[HAS_REM_NOT:%.*]] = icmp eq i32 [[REM]], 0
314+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARG0]], 32
315+ ; CHECK-NEXT: [[RES1:%.*]] = icmp eq i32 [[TMP1]], 0
316+ ; CHECK-NEXT: [[RES:%.*]] = or i1 [[HAS_REM_NOT]], [[RES1]]
317+ ; CHECK-NEXT: ret i1 [[RES]]
318+ ;
319+ %quot = lshr i32 %arg0 , 5
320+ %rem = and i32 %arg0 , 15
321+ %has_rem = icmp ne i32 %rem , 0
322+ %zext_has_rem = zext i1 %has_rem to i32
323+ %quot_and_rem = and i32 %quot , %zext_has_rem
324+ %res = icmp eq i32 %quot_and_rem , 0
325+ ret i1 %res
326+ }
327+
0 commit comments