1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
5 ; CHECK-LABEL: define i8 @scmp_lt() {
6 ; CHECK-NEXT: ret i8 -1
8 %1 = call i8 @llvm.scmp(i32 -7, i32 3)
12 define i8 @scmp_eq() {
13 ; CHECK-LABEL: define i8 @scmp_eq() {
14 ; CHECK-NEXT: ret i8 0
16 %1 = call i8 @llvm.scmp(i32 2, i32 2)
20 define i8 @scmp_gt() {
21 ; CHECK-LABEL: define i8 @scmp_gt() {
22 ; CHECK-NEXT: ret i8 1
24 %1 = call i8 @llvm.scmp(i32 2, i32 -7)
28 define i8 @ucmp_lt() {
29 ; CHECK-LABEL: define i8 @ucmp_lt() {
30 ; CHECK-NEXT: ret i8 -1
32 %1 = call i8 @llvm.ucmp(i32 7, i32 12)
36 define i2 @ucmp_eq() {
37 ; CHECK-LABEL: define i2 @ucmp_eq() {
38 ; CHECK-NEXT: ret i2 0
40 %1 = call i2 @llvm.ucmp(i32 12, i32 12)
44 define i100 @ucmp_gt() {
45 ; CHECK-LABEL: define i100 @ucmp_gt() {
46 ; CHECK-NEXT: ret i100 1
48 %1 = call i100 @llvm.ucmp(i32 7, i32 3)
52 define i8 @ucmp_poison() {
53 ; CHECK-LABEL: define i8 @ucmp_poison() {
54 ; CHECK-NEXT: ret i8 poison
56 %1 = call i8 @llvm.ucmp(i32 poison, i32 5)
60 define i8 @scmp_poison() {
61 ; CHECK-LABEL: define i8 @scmp_poison() {
62 ; CHECK-NEXT: ret i8 poison
64 %1 = call i8 @llvm.scmp(i32 0, i32 poison)
68 define i8 @scmp_undef() {
69 ; CHECK-LABEL: define i8 @scmp_undef() {
70 ; CHECK-NEXT: ret i8 0
72 %1 = call i8 @llvm.scmp(i32 undef, i32 -12)
76 define i8 @ucmp_undef() {
77 ; CHECK-LABEL: define i8 @ucmp_undef() {
78 ; CHECK-NEXT: ret i8 0
80 %1 = call i8 @llvm.ucmp(i32 2, i32 undef)
84 define <4 x i8> @ucmp_lt_splat() {
85 ; CHECK-LABEL: define <4 x i8> @ucmp_lt_splat() {
86 ; CHECK-NEXT: ret <4 x i8> splat (i8 -1)
88 %1 = call <4 x i8> @llvm.ucmp(<4 x i32> splat(i32 1), <4 x i32> splat(i32 3))
92 define <4 x i8> @scmp_nonsplat() {
93 ; CHECK-LABEL: define <4 x i8> @scmp_nonsplat() {
94 ; CHECK-NEXT: ret <4 x i8> <i8 1, i8 0, i8 1, i8 -1>
96 %1 = call <4 x i8> @llvm.scmp(<4 x i32> <i32 0, i32 1, i32 2, i32 3>, <4 x i32> <i32 -1, i32 1, i32 -2, i32 4>)
100 define i8 @scmp_with_itself(i32 %x) {
101 ; CHECK-LABEL: define i8 @scmp_with_itself(
102 ; CHECK-SAME: i32 [[X:%.*]]) {
103 ; CHECK-NEXT: ret i8 0
105 %1 = call i8 @llvm.scmp(i32 %x, i32 %x)
109 define <4 x i8> @ucmp_vec_with_itself(<4 x i32> %x) {
110 ; CHECK-LABEL: define <4 x i8> @ucmp_vec_with_itself(
111 ; CHECK-SAME: <4 x i32> [[X:%.*]]) {
112 ; CHECK-NEXT: ret <4 x i8> zeroinitializer
114 %1 = call <4 x i8> @llvm.scmp(<4 x i32> %x, <4 x i32> %x)
118 define i8 @scmp_known_gt(i32 %x, i32 %y) {
119 ; CHECK-LABEL: define i8 @scmp_known_gt(
120 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
121 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[X]], [[Y]]
122 ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
123 ; CHECK-NEXT: ret i8 1
125 %1 = icmp sgt i32 %x, %y
126 call void @llvm.assume(i1 %1)
128 %2 = call i8 @llvm.scmp(i32 %x, i32 %y)
132 define i8 @scmp_known_eq(i32 %x, i32 %y) {
133 ; CHECK-LABEL: define i8 @scmp_known_eq(
134 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
135 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X]], [[Y]]
136 ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
137 ; CHECK-NEXT: ret i8 0
139 %1 = icmp eq i32 %x, %y
140 call void @llvm.assume(i1 %1)
142 %2 = call i8 @llvm.scmp(i32 %x, i32 %y)
146 define i8 @scmp_known_lt(i32 %x, i32 %y) {
147 ; CHECK-LABEL: define i8 @scmp_known_lt(
148 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
149 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X]], [[Y]]
150 ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
151 ; CHECK-NEXT: ret i8 -1
153 %1 = icmp slt i32 %x, %y
154 call void @llvm.assume(i1 %1)
156 %2 = call i8 @llvm.scmp(i32 %x, i32 %y)
160 define i8 @ucmp_known_gt(i32 %x, i32 %y) {
161 ; CHECK-LABEL: define i8 @ucmp_known_gt(
162 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
163 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X]], [[Y]]
164 ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
165 ; CHECK-NEXT: ret i8 1
167 %1 = icmp ugt i32 %x, %y
168 call void @llvm.assume(i1 %1)
170 %2 = call i8 @llvm.ucmp(i32 %x, i32 %y)
174 define i8 @ucmp_known_eq(i32 %x, i32 %y) {
175 ; CHECK-LABEL: define i8 @ucmp_known_eq(
176 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
177 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X]], [[Y]]
178 ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
179 ; CHECK-NEXT: ret i8 0
181 %1 = icmp eq i32 %x, %y
182 call void @llvm.assume(i1 %1)
184 %2 = call i8 @llvm.ucmp(i32 %x, i32 %y)
188 define i8 @ucmp_known_lt(i32 %x, i32 %y) {
189 ; CHECK-LABEL: define i8 @ucmp_known_lt(
190 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
191 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X]], [[Y]]
192 ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
193 ; CHECK-NEXT: ret i8 -1
195 %1 = icmp ult i32 %x, %y
196 call void @llvm.assume(i1 %1)
198 %2 = call i8 @llvm.ucmp(i32 %x, i32 %y)
202 define i8 @ucmp_with_addition(i32 %x) {
203 ; CHECK-LABEL: define i8 @ucmp_with_addition(
204 ; CHECK-SAME: i32 [[X:%.*]]) {
205 ; CHECK-NEXT: ret i8 -1
207 %1 = add nuw i32 %x, 1
208 %2 = call i8 @llvm.ucmp(i32 %x, i32 %1)
212 define i8 @ucmp_with_addition2(i32 %x) {
213 ; CHECK-LABEL: define i8 @ucmp_with_addition2(
214 ; CHECK-SAME: i32 [[X:%.*]]) {
215 ; CHECK-NEXT: ret i8 1
217 %1 = add nuw i32 %x, 1
218 %2 = call i8 @llvm.ucmp(i32 %1, i32 %x)
222 define <4 x i8> @ucmp_with_addition_vec(<4 x i32> %x) {
223 ; CHECK-LABEL: define <4 x i8> @ucmp_with_addition_vec(
224 ; CHECK-SAME: <4 x i32> [[X:%.*]]) {
225 ; CHECK-NEXT: ret <4 x i8> splat (i8 -1)
227 %1 = add nuw <4 x i32> %x, splat(i32 1)
228 %2 = call <4 x i8> @llvm.ucmp(<4 x i32> %x, <4 x i32> %1)
232 define i1 @scmp_eq_4(i32 %x, i32 %y) {
233 ; CHECK-LABEL: define i1 @scmp_eq_4(
234 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
235 ; CHECK-NEXT: ret i1 false
237 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
238 %2 = icmp eq i8 %1, 4
242 define i1 @ucmp_ne_negative_2(i32 %x, i32 %y) {
243 ; CHECK-LABEL: define i1 @ucmp_ne_negative_2(
244 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
245 ; CHECK-NEXT: ret i1 true
247 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
248 %2 = icmp ne i8 %1, -2
252 ; Negative case: mismatched signedness of predicates
253 define i8 @scmp_known_ugt(i32 %x, i32 %y) {
254 ; CHECK-LABEL: define i8 @scmp_known_ugt(
255 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
256 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X]], [[Y]]
257 ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
258 ; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
259 ; CHECK-NEXT: ret i8 [[TMP2]]
261 %1 = icmp ugt i32 %x, %y
262 call void @llvm.assume(i1 %1)
264 %2 = call i8 @llvm.scmp(i32 %x, i32 %y)
268 define i8 @scmp_known_ult(i32 %x, i32 %y) {
269 ; CHECK-LABEL: define i8 @scmp_known_ult(
270 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
271 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X]], [[Y]]
272 ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
273 ; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
274 ; CHECK-NEXT: ret i8 [[TMP2]]
276 %1 = icmp ult i32 %x, %y
277 call void @llvm.assume(i1 %1)
279 %2 = call i8 @llvm.scmp(i32 %x, i32 %y)
283 define i8 @ucmp_known_sgt(i32 %x, i32 %y) {
284 ; CHECK-LABEL: define i8 @ucmp_known_sgt(
285 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
286 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[X]], [[Y]]
287 ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
288 ; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
289 ; CHECK-NEXT: ret i8 [[TMP2]]
291 %1 = icmp sgt i32 %x, %y
292 call void @llvm.assume(i1 %1)
294 %2 = call i8 @llvm.ucmp(i32 %x, i32 %y)
298 define i8 @ucmp_known_slt(i32 %x, i32 %y) {
299 ; CHECK-LABEL: define i8 @ucmp_known_slt(
300 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
301 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X]], [[Y]]
302 ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
303 ; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
304 ; CHECK-NEXT: ret i8 [[TMP2]]
306 %1 = icmp slt i32 %x, %y
307 call void @llvm.assume(i1 %1)
309 %2 = call i8 @llvm.ucmp(i32 %x, i32 %y)
313 ; Negative case: no nuw flag
314 define i8 @ucmp_with_addition_no_nuw(i32 %x) {
315 ; CHECK-LABEL: define i8 @ucmp_with_addition_no_nuw(
316 ; CHECK-SAME: i32 [[X:%.*]]) {
317 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], 1
318 ; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[TMP1]])
319 ; CHECK-NEXT: ret i8 [[TMP2]]
322 %2 = call i8 @llvm.ucmp(i32 %x, i32 %1)