Skip to content

Commit 87aa097

Browse files
[InstCombine] Introduce test for PR100977 (NFC)
1 parent 81fae0d commit 87aa097

File tree

1 file changed

+213
-0
lines changed

1 file changed

+213
-0
lines changed
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2+
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3+
4+
define i8 @ceil_div_idiom(i8 %x, i8 %y) {
5+
; CHECK-LABEL: define i8 @ceil_div_idiom(
6+
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
7+
; CHECK-NEXT: [[WO:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 [[X]], i8 [[Y]])
8+
; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[WO]], 1
9+
; CHECK-NEXT: [[OV_NOT:%.*]] = xor i1 [[OV]], true
10+
; CHECK-NEXT: call void @llvm.assume(i1 [[OV_NOT]])
11+
; CHECK-NEXT: [[NONZERO:%.*]] = icmp ne i8 [[X]], 0
12+
; CHECK-NEXT: [[BIAS:%.*]] = zext i1 [[NONZERO]] to i8
13+
; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[X]], [[BIAS]]
14+
; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[SUB]], [[Y]]
15+
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[DIV]], [[BIAS]]
16+
; CHECK-NEXT: ret i8 [[ADD]]
17+
;
18+
%wo = call {i8, i1} @llvm.uadd.with.overflow(i8 %x, i8 %y)
19+
%ov = extractvalue {i8, i1} %wo, 1
20+
%ov.not = xor i1 %ov, true
21+
call void @llvm.assume(i1 %ov.not)
22+
23+
%nonzero = icmp ne i8 %x, 0
24+
%bias = zext i1 %nonzero to i8
25+
%sub = sub i8 %x, %bias
26+
%div = udiv i8 %sub, %y
27+
%add = add i8 %div, %bias
28+
ret i8 %add
29+
}
30+
31+
define i8 @ceil_div_idiom_2(i8 %x, i8 %y) {
32+
; CHECK-LABEL: define i8 @ceil_div_idiom_2(
33+
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
34+
; CHECK-NEXT: [[OV_NOT:%.*]] = add nuw i8 [[X]], [[Y]]
35+
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[OV_NOT]] to i1
36+
; CHECK-NEXT: call void @llvm.assume(i1 [[TRUNC]])
37+
; CHECK-NEXT: [[NONZERO:%.*]] = icmp ne i8 [[X]], 0
38+
; CHECK-NEXT: [[BIAS:%.*]] = zext i1 [[NONZERO]] to i8
39+
; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[X]], [[BIAS]]
40+
; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[SUB]], [[Y]]
41+
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[DIV]], [[BIAS]]
42+
; CHECK-NEXT: ret i8 [[ADD]]
43+
;
44+
%ov.not = add nuw i8 %x, %y
45+
%trunc = trunc i8 %ov.not to i1
46+
call void @llvm.assume(i1 %trunc)
47+
48+
%nonzero = icmp ne i8 %x, 0
49+
%bias = zext i1 %nonzero to i8
50+
%sub = sub i8 %x, %bias
51+
%div = udiv i8 %sub, %y
52+
%add = add i8 %div, %bias
53+
ret i8 %add
54+
}
55+
56+
define i8 @ceil_div_idiom_with_lshr(i8 %x, i8 %y) {
57+
; CHECK-LABEL: define i8 @ceil_div_idiom_with_lshr(
58+
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
59+
; CHECK-NEXT: [[WO:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 [[X]], i8 [[Y]])
60+
; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[WO]], 1
61+
; CHECK-NEXT: [[OV_NOT:%.*]] = xor i1 [[OV]], true
62+
; CHECK-NEXT: call void @llvm.assume(i1 [[OV_NOT]])
63+
; CHECK-NEXT: [[CTPOPULATION:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[Y]])
64+
; CHECK-NEXT: [[IS_POW_2:%.*]] = icmp eq i8 [[CTPOPULATION]], 1
65+
; CHECK-NEXT: call void @llvm.assume(i1 [[IS_POW_2]])
66+
; CHECK-NEXT: [[NONZERO:%.*]] = icmp ne i8 [[X]], 0
67+
; CHECK-NEXT: [[BIAS:%.*]] = zext i1 [[NONZERO]] to i8
68+
; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[X]], [[BIAS]]
69+
; CHECK-NEXT: [[CTLZ:%.*]] = tail call range(i8 0, 9) i8 @llvm.ctlz.i8(i8 [[Y]], i1 true)
70+
; CHECK-NEXT: [[N:%.*]] = xor i8 [[CTLZ]], 7
71+
; CHECK-NEXT: [[DIV:%.*]] = lshr i8 [[SUB]], [[N]]
72+
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[DIV]], [[BIAS]]
73+
; CHECK-NEXT: ret i8 [[ADD]]
74+
;
75+
%wo = call {i8, i1} @llvm.uadd.with.overflow(i8 %x, i8 %y)
76+
%ov = extractvalue {i8, i1} %wo, 1
77+
%ov.not = xor i1 %ov, true
78+
call void @llvm.assume(i1 %ov.not)
79+
80+
%ctpopulation = call i8 @llvm.ctpop.i8(i8 %y)
81+
%is_pow_2 = icmp eq i8 %ctpopulation, 1
82+
call void @llvm.assume(i1 %is_pow_2)
83+
84+
%nonzero = icmp ne i8 %x, 0
85+
%bias = zext i1 %nonzero to i8
86+
%sub = sub i8 %x, %bias
87+
%ctlz = tail call i8 @llvm.ctlz.i8(i8 %y, i1 true)
88+
%n = sub i8 7, %ctlz
89+
%div = lshr i8 %sub, %n
90+
%add = add i8 %div, %bias
91+
ret i8 %add
92+
}
93+
94+
define i8 @ceil_div_idiom_add_may_overflow(i8 %x, i8 %y) {
95+
; CHECK-LABEL: define i8 @ceil_div_idiom_add_may_overflow(
96+
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
97+
; CHECK-NEXT: [[NONZERO:%.*]] = icmp ne i8 [[X]], 0
98+
; CHECK-NEXT: [[BIAS:%.*]] = zext i1 [[NONZERO]] to i8
99+
; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[X]], [[BIAS]]
100+
; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[SUB]], [[Y]]
101+
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[DIV]], [[BIAS]]
102+
; CHECK-NEXT: ret i8 [[ADD]]
103+
;
104+
%nonzero = icmp ne i8 %x, 0
105+
%bias = zext i1 %nonzero to i8
106+
%sub = sub i8 %x, %bias
107+
%div = udiv i8 %sub, %y
108+
%add = add i8 %div, %bias
109+
ret i8 %add
110+
}
111+
112+
define i8 @ceil_div_idiom_multiuse_bias(i8 %x, i8 %y) {
113+
; CHECK-LABEL: define i8 @ceil_div_idiom_multiuse_bias(
114+
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
115+
; CHECK-NEXT: [[WO:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 [[X]], i8 [[Y]])
116+
; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[WO]], 1
117+
; CHECK-NEXT: [[OV_NOT:%.*]] = xor i1 [[OV]], true
118+
; CHECK-NEXT: call void @llvm.assume(i1 [[OV_NOT]])
119+
; CHECK-NEXT: [[NONZERO:%.*]] = icmp ne i8 [[X]], 0
120+
; CHECK-NEXT: [[BIAS:%.*]] = zext i1 [[NONZERO]] to i8
121+
; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[X]], [[BIAS]]
122+
; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[SUB]], [[Y]]
123+
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[DIV]], [[BIAS]]
124+
; CHECK-NEXT: call void @use(i8 [[BIAS]])
125+
; CHECK-NEXT: ret i8 [[ADD]]
126+
;
127+
%wo = call {i8, i1} @llvm.uadd.with.overflow(i8 %x, i8 %y)
128+
%ov = extractvalue {i8, i1} %wo, 1
129+
%ov.not = xor i1 %ov, true
130+
call void @llvm.assume(i1 %ov.not)
131+
132+
%nonzero = icmp ne i8 %x, 0
133+
%bias = zext i1 %nonzero to i8
134+
%sub = sub i8 %x, %bias
135+
%div = udiv i8 %sub, %y
136+
%add = add i8 %div, %bias
137+
call void @use(i8 %bias)
138+
ret i8 %add
139+
}
140+
141+
define i8 @ceil_div_idiom_with_lshr_not_power_2(i8 %x, i8 %y) {
142+
; CHECK-LABEL: define i8 @ceil_div_idiom_with_lshr_not_power_2(
143+
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
144+
; CHECK-NEXT: [[WO:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 [[X]], i8 [[Y]])
145+
; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[WO]], 1
146+
; CHECK-NEXT: [[OV_NOT:%.*]] = xor i1 [[OV]], true
147+
; CHECK-NEXT: call void @llvm.assume(i1 [[OV_NOT]])
148+
; CHECK-NEXT: [[NONZERO:%.*]] = icmp ne i8 [[X]], 0
149+
; CHECK-NEXT: [[BIAS:%.*]] = zext i1 [[NONZERO]] to i8
150+
; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[X]], [[BIAS]]
151+
; CHECK-NEXT: [[CTLZ:%.*]] = tail call range(i8 0, 9) i8 @llvm.ctlz.i8(i8 [[Y]], i1 true)
152+
; CHECK-NEXT: [[N:%.*]] = xor i8 [[CTLZ]], 7
153+
; CHECK-NEXT: [[DIV:%.*]] = lshr i8 [[SUB]], [[N]]
154+
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[DIV]], [[BIAS]]
155+
; CHECK-NEXT: ret i8 [[ADD]]
156+
;
157+
%wo = call {i8, i1} @llvm.uadd.with.overflow(i8 %x, i8 %y)
158+
%ov = extractvalue {i8, i1} %wo, 1
159+
%ov.not = xor i1 %ov, true
160+
call void @llvm.assume(i1 %ov.not)
161+
162+
%nonzero = icmp ne i8 %x, 0
163+
%bias = zext i1 %nonzero to i8
164+
%sub = sub i8 %x, %bias
165+
%ctlz = tail call i8 @llvm.ctlz.i8(i8 %y, i1 true)
166+
%n = sub i8 7, %ctlz
167+
%div = lshr i8 %sub, %n
168+
%add = add i8 %div, %bias
169+
ret i8 %add
170+
}
171+
172+
define i8 @ceil_div_idiom_with_lshr_wrong_bw(i8 %x, i8 %y) {
173+
; CHECK-LABEL: define i8 @ceil_div_idiom_with_lshr_wrong_bw(
174+
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
175+
; CHECK-NEXT: [[WO:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 [[X]], i8 [[Y]])
176+
; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[WO]], 1
177+
; CHECK-NEXT: [[OV_NOT:%.*]] = xor i1 [[OV]], true
178+
; CHECK-NEXT: call void @llvm.assume(i1 [[OV_NOT]])
179+
; CHECK-NEXT: [[CTPOPULATION:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[Y]])
180+
; CHECK-NEXT: [[IS_POW_2:%.*]] = icmp eq i8 [[CTPOPULATION]], 1
181+
; CHECK-NEXT: call void @llvm.assume(i1 [[IS_POW_2]])
182+
; CHECK-NEXT: [[NONZERO:%.*]] = icmp ne i8 [[X]], 0
183+
; CHECK-NEXT: [[BIAS:%.*]] = zext i1 [[NONZERO]] to i8
184+
; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[X]], [[BIAS]]
185+
; CHECK-NEXT: [[CTLZ:%.*]] = tail call range(i8 0, 9) i8 @llvm.ctlz.i8(i8 [[Y]], i1 true)
186+
; CHECK-NEXT: [[N:%.*]] = sub nuw nsw i8 8, [[CTLZ]]
187+
; CHECK-NEXT: [[DIV:%.*]] = lshr i8 [[SUB]], [[N]]
188+
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[DIV]], [[BIAS]]
189+
; CHECK-NEXT: ret i8 [[ADD]]
190+
;
191+
%wo = call {i8, i1} @llvm.uadd.with.overflow(i8 %x, i8 %y)
192+
%ov = extractvalue {i8, i1} %wo, 1
193+
%ov.not = xor i1 %ov, true
194+
call void @llvm.assume(i1 %ov.not)
195+
196+
%ctpopulation = call i8 @llvm.ctpop.i8(i8 %y)
197+
%is_pow_2 = icmp eq i8 %ctpopulation, 1
198+
call void @llvm.assume(i1 %is_pow_2)
199+
200+
%nonzero = icmp ne i8 %x, 0
201+
%bias = zext i1 %nonzero to i8
202+
%sub = sub i8 %x, %bias
203+
%ctlz = tail call i8 @llvm.ctlz.i8(i8 %y, i1 true)
204+
%n = sub i8 8, %ctlz
205+
%div = lshr i8 %sub, %n
206+
%add = add i8 %div, %bias
207+
ret i8 %add
208+
}
209+
210+
declare { i8, i1 } @llvm.uadd.with.overflow.i8(i8, i8)
211+
declare i8 @llvm.ctpop.i8(i8)
212+
declare void @llvm.assume(i1)
213+
declare void @use(i8)

0 commit comments

Comments
 (0)