1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 ; https://bugs.llvm.org/show_bug.cgi?id=38123
8 ; Should be transformed into:
10 ; That is then later transformed into:
13 ; ============================================================================ ;
14 ; Basic positive tests
15 ; ============================================================================ ;
17 define i1 @p0(i8 %x, i8 %y) {
19 ; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 [[X:%.*]], [[Y:%.*]]
20 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[TMP1]], 0
21 ; CHECK-NEXT: ret i1 [[RET]]
26 %ret = icmp ne i8 %t2, %x
30 ; ============================================================================ ;
32 ; ============================================================================ ;
34 define <2 x i1> @p1_vec(<2 x i8> %x, <2 x i8> %y) {
35 ; CHECK-LABEL: @p1_vec(
36 ; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i8> [[X:%.*]], [[Y:%.*]]
37 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i8> [[TMP1]], zeroinitializer
38 ; CHECK-NEXT: ret <2 x i1> [[RET]]
40 %t0 = shl <2 x i8> <i8 -1, i8 -1>, %y
41 %t1 = xor <2 x i8> %t0, <i8 -1, i8 -1>
42 %t2 = and <2 x i8> %t1, %x
43 %ret = icmp ne <2 x i8> %t2, %x
47 define <3 x i1> @p2_vec_poison0(<3 x i8> %x, <3 x i8> %y) {
48 ; CHECK-LABEL: @p2_vec_poison0(
49 ; CHECK-NEXT: [[TMP1:%.*]] = lshr <3 x i8> [[X:%.*]], [[Y:%.*]]
50 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <3 x i8> [[TMP1]], zeroinitializer
51 ; CHECK-NEXT: ret <3 x i1> [[RET]]
53 %t0 = shl <3 x i8> <i8 -1, i8 poison, i8 -1>, %y
54 %t1 = xor <3 x i8> %t0, <i8 -1, i8 -1, i8 -1>
55 %t2 = and <3 x i8> %t1, %x
56 %ret = icmp ne <3 x i8> %t2, %x
60 define <3 x i1> @p3_vec_poison0(<3 x i8> %x, <3 x i8> %y) {
61 ; CHECK-LABEL: @p3_vec_poison0(
62 ; CHECK-NEXT: [[TMP1:%.*]] = lshr <3 x i8> [[X:%.*]], [[Y:%.*]]
63 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <3 x i8> [[TMP1]], zeroinitializer
64 ; CHECK-NEXT: ret <3 x i1> [[RET]]
66 %t0 = shl <3 x i8> <i8 -1, i8 -1, i8 -1>, %y
67 %t1 = xor <3 x i8> %t0, <i8 -1, i8 poison, i8 -1>
68 %t2 = and <3 x i8> %t1, %x
69 %ret = icmp ne <3 x i8> %t2, %x
73 define <3 x i1> @p4_vec_poison2(<3 x i8> %x, <3 x i8> %y) {
74 ; CHECK-LABEL: @p4_vec_poison2(
75 ; CHECK-NEXT: [[TMP1:%.*]] = lshr <3 x i8> [[X:%.*]], [[Y:%.*]]
76 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <3 x i8> [[TMP1]], zeroinitializer
77 ; CHECK-NEXT: ret <3 x i1> [[RET]]
79 %t0 = shl <3 x i8> <i8 -1, i8 poison, i8 -1>, %y
80 %t1 = xor <3 x i8> %t0, <i8 -1, i8 poison, i8 -1>
81 %t2 = and <3 x i8> %t1, %x
82 %ret = icmp ne <3 x i8> %t2, %x
86 ; ============================================================================ ;
87 ; Commutativity tests.
88 ; ============================================================================ ;
92 define i1 @c0(i8 %y) {
94 ; CHECK-NEXT: [[X:%.*]] = call i8 @gen8()
95 ; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 [[X]], [[Y:%.*]]
96 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[TMP1]], 0
97 ; CHECK-NEXT: ret i1 [[RET]]
102 %t2 = and i8 %x, %t1 ; swapped order
103 %ret = icmp ne i8 %t2, %x
107 define i1 @c1(i8 %y) {
109 ; CHECK-NEXT: [[X:%.*]] = call i8 @gen8()
110 ; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 [[X]], [[Y:%.*]]
111 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[TMP1]], 0
112 ; CHECK-NEXT: ret i1 [[RET]]
118 %ret = icmp ne i8 %x, %t2 ; swapped order
122 define i1 @c2(i8 %y) {
124 ; CHECK-NEXT: [[X:%.*]] = call i8 @gen8()
125 ; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 [[X]], [[Y:%.*]]
126 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[TMP1]], 0
127 ; CHECK-NEXT: ret i1 [[RET]]
132 %t2 = and i8 %x, %t1 ; swapped order
133 %ret = icmp ne i8 %x, %t2 ; swapped order
137 ; ============================================================================ ;
138 ; One-use tests. We don't care about multi-uses here.
139 ; ============================================================================ ;
141 declare void @use8(i8)
143 define i1 @oneuse0(i8 %x, i8 %y) {
144 ; CHECK-LABEL: @oneuse0(
145 ; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
146 ; CHECK-NEXT: call void @use8(i8 [[T0]])
147 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], [[T0]]
148 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[TMP1]], 0
149 ; CHECK-NEXT: ret i1 [[RET]]
152 call void @use8(i8 %t0)
155 %ret = icmp ne i8 %t2, %x
159 define i1 @oneuse1(i8 %x, i8 %y) {
160 ; CHECK-LABEL: @oneuse1(
161 ; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
162 ; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -1
163 ; CHECK-NEXT: call void @use8(i8 [[T1]])
164 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], [[T0]]
165 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[TMP1]], 0
166 ; CHECK-NEXT: ret i1 [[RET]]
170 call void @use8(i8 %t1)
172 %ret = icmp ne i8 %t2, %x
176 define i1 @oneuse2(i8 %x, i8 %y) {
177 ; CHECK-LABEL: @oneuse2(
178 ; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
179 ; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -1
180 ; CHECK-NEXT: [[T2:%.*]] = and i8 [[X:%.*]], [[T1]]
181 ; CHECK-NEXT: call void @use8(i8 [[T2]])
182 ; CHECK-NEXT: [[RET:%.*]] = icmp ugt i8 [[X]], [[T1]]
183 ; CHECK-NEXT: ret i1 [[RET]]
188 call void @use8(i8 %t2)
189 %ret = icmp ne i8 %t2, %x
193 define i1 @oneuse3(i8 %x, i8 %y) {
194 ; CHECK-LABEL: @oneuse3(
195 ; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
196 ; CHECK-NEXT: call void @use8(i8 [[T0]])
197 ; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -1
198 ; CHECK-NEXT: call void @use8(i8 [[T1]])
199 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], [[T0]]
200 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[TMP1]], 0
201 ; CHECK-NEXT: ret i1 [[RET]]
204 call void @use8(i8 %t0)
206 call void @use8(i8 %t1)
208 %ret = icmp ne i8 %t2, %x
212 define i1 @oneuse4(i8 %x, i8 %y) {
213 ; CHECK-LABEL: @oneuse4(
214 ; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
215 ; CHECK-NEXT: call void @use8(i8 [[T0]])
216 ; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -1
217 ; CHECK-NEXT: [[T2:%.*]] = and i8 [[X:%.*]], [[T1]]
218 ; CHECK-NEXT: call void @use8(i8 [[T2]])
219 ; CHECK-NEXT: [[RET:%.*]] = icmp ugt i8 [[X]], [[T1]]
220 ; CHECK-NEXT: ret i1 [[RET]]
223 call void @use8(i8 %t0)
226 call void @use8(i8 %t2)
227 %ret = icmp ne i8 %t2, %x
231 define i1 @oneuse5(i8 %x, i8 %y) {
232 ; CHECK-LABEL: @oneuse5(
233 ; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
234 ; CHECK-NEXT: call void @use8(i8 [[T0]])
235 ; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -1
236 ; CHECK-NEXT: call void @use8(i8 [[T1]])
237 ; CHECK-NEXT: [[T2:%.*]] = and i8 [[X:%.*]], [[T1]]
238 ; CHECK-NEXT: call void @use8(i8 [[T2]])
239 ; CHECK-NEXT: [[RET:%.*]] = icmp ugt i8 [[X]], [[T1]]
240 ; CHECK-NEXT: ret i1 [[RET]]
243 call void @use8(i8 %t0)
245 call void @use8(i8 %t1)
247 call void @use8(i8 %t2)
248 %ret = icmp ne i8 %t2, %x
252 ; ============================================================================ ;
254 ; ============================================================================ ;
256 define i1 @n0(i8 %x, i8 %y, i8 %notx) {
258 ; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
259 ; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -1
260 ; CHECK-NEXT: [[T2:%.*]] = and i8 [[X:%.*]], [[T1]]
261 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[NOTX:%.*]]
262 ; CHECK-NEXT: ret i1 [[RET]]
267 %ret = icmp ne i8 %t2, %notx ; not %x
271 define i1 @n1(i8 %x, i8 %y) {
273 ; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
274 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], [[T0]]
275 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[TMP1]], 0
276 ; CHECK-NEXT: ret i1 [[RET]]
278 %t0 = shl i8 1, %y ; not -1
281 %ret = icmp ne i8 %t2, %x
285 define i1 @n2(i8 %x, i8 %y) {
287 ; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
288 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[T0]], -2
289 ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
290 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[TMP2]], 0
291 ; CHECK-NEXT: ret i1 [[RET]]
294 %t1 = xor i8 %t0, 1 ; not -1
296 %ret = icmp ne i8 %t2, %x