1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4; https://bugs.llvm.org/show_bug.cgi?id=38149
5
6; Pattern:
7;   ((%x << MaskedBits) a>> MaskedBits) != %x
8; Should be transformed into:
9;   (add %x, (1 << (KeptBits-1))) u>= (1 << KeptBits)
10; Where  KeptBits = bitwidth(%x) - MaskedBits
11
12; ============================================================================ ;
13; Basic positive tests
14; ============================================================================ ;
15
16define i1 @p0(i8 %x) {
17; CHECK-LABEL: @p0(
18; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[X:%.*]], 4
19; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt i8 [[TMP1]], 7
20; CHECK-NEXT:    ret i1 [[TMP2]]
21;
22  %tmp0 = shl i8 %x, 5
23  %tmp1 = ashr exact i8 %tmp0, 5
24  %tmp2 = icmp ne i8 %tmp1, %x
25  ret i1 %tmp2
26}
27
28; Big unusual bit width, https://bugs.llvm.org/show_bug.cgi?id=38204
29define i1 @pb(i65 %x) {
30; CHECK-LABEL: @pb(
31; CHECK-NEXT:    [[TMP1:%.*]] = add i65 [[X:%.*]], 9223372036854775808
32; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i65 [[TMP1]], 0
33; CHECK-NEXT:    ret i1 [[TMP2]]
34;
35  %tmp0 = shl i65 %x, 1
36  %tmp1 = ashr exact i65 %tmp0, 1
37  %tmp2 = icmp ne i65 %x, %tmp1
38  ret i1 %tmp2
39}
40
41; ============================================================================ ;
42; Vector tests
43; ============================================================================ ;
44
45define <2 x i1> @p1_vec_splat(<2 x i8> %x) {
46; CHECK-LABEL: @p1_vec_splat(
47; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], <i8 4, i8 4>
48; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt <2 x i8> [[TMP1]], <i8 7, i8 7>
49; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
50;
51  %tmp0 = shl <2 x i8> %x, <i8 5, i8 5>
52  %tmp1 = ashr exact <2 x i8> %tmp0, <i8 5, i8 5>
53  %tmp2 = icmp ne <2 x i8> %tmp1, %x
54  ret <2 x i1> %tmp2
55}
56
57define <2 x i1> @p2_vec_nonsplat(<2 x i8> %x) {
58; CHECK-LABEL: @p2_vec_nonsplat(
59; CHECK-NEXT:    [[TMP0:%.*]] = shl <2 x i8> [[X:%.*]], <i8 5, i8 6>
60; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact <2 x i8> [[TMP0]], <i8 5, i8 6>
61; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i8> [[TMP1]], [[X]]
62; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
63;
64  %tmp0 = shl <2 x i8> %x, <i8 5, i8 6>
65  %tmp1 = ashr exact <2 x i8> %tmp0, <i8 5, i8 6>
66  %tmp2 = icmp ne <2 x i8> %tmp1, %x
67  ret <2 x i1> %tmp2
68}
69
70define <3 x i1> @p3_vec_undef0(<3 x i8> %x) {
71; CHECK-LABEL: @p3_vec_undef0(
72; CHECK-NEXT:    [[TMP0:%.*]] = shl <3 x i8> [[X:%.*]], <i8 5, i8 undef, i8 5>
73; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact <3 x i8> [[TMP0]], <i8 5, i8 5, i8 5>
74; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <3 x i8> [[TMP1]], [[X]]
75; CHECK-NEXT:    ret <3 x i1> [[TMP2]]
76;
77  %tmp0 = shl <3 x i8> %x, <i8 5, i8 undef, i8 5>
78  %tmp1 = ashr exact <3 x i8> %tmp0, <i8 5, i8 5, i8 5>
79  %tmp2 = icmp ne <3 x i8> %tmp1, %x
80  ret <3 x i1> %tmp2
81}
82
83define <3 x i1> @p4_vec_undef1(<3 x i8> %x) {
84; CHECK-LABEL: @p4_vec_undef1(
85; CHECK-NEXT:    [[TMP0:%.*]] = shl <3 x i8> [[X:%.*]], <i8 5, i8 5, i8 5>
86; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact <3 x i8> [[TMP0]], <i8 5, i8 undef, i8 5>
87; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <3 x i8> [[TMP1]], [[X]]
88; CHECK-NEXT:    ret <3 x i1> [[TMP2]]
89;
90  %tmp0 = shl <3 x i8> %x, <i8 5, i8 5, i8 5>
91  %tmp1 = ashr exact <3 x i8> %tmp0, <i8 5, i8 undef, i8 5>
92  %tmp2 = icmp ne <3 x i8> %tmp1, %x
93  ret <3 x i1> %tmp2
94}
95
96define <3 x i1> @p5_vec_undef2(<3 x i8> %x) {
97; CHECK-LABEL: @p5_vec_undef2(
98; CHECK-NEXT:    [[TMP0:%.*]] = shl <3 x i8> [[X:%.*]], <i8 5, i8 undef, i8 5>
99; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact <3 x i8> [[TMP0]], <i8 5, i8 undef, i8 5>
100; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <3 x i8> [[TMP1]], [[X]]
101; CHECK-NEXT:    ret <3 x i1> [[TMP2]]
102;
103  %tmp0 = shl <3 x i8> %x, <i8 5, i8 undef, i8 5>
104  %tmp1 = ashr exact <3 x i8> %tmp0, <i8 5, i8 undef, i8 5>
105  %tmp2 = icmp ne <3 x i8> %tmp1, %x
106  ret <3 x i1> %tmp2
107}
108
109; ============================================================================ ;
110; Commutativity tests.
111; ============================================================================ ;
112
113declare i8 @gen8()
114
115define i1 @c0() {
116; CHECK-LABEL: @c0(
117; CHECK-NEXT:    [[X:%.*]] = call i8 @gen8()
118; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[X]], 4
119; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt i8 [[TMP1]], 7
120; CHECK-NEXT:    ret i1 [[TMP2]]
121;
122  %x = call i8 @gen8()
123  %tmp0 = shl i8 %x, 5
124  %tmp1 = ashr exact i8 %tmp0, 5
125  %tmp2 = icmp ne i8 %x, %tmp1 ; swapped order
126  ret i1 %tmp2
127}
128
129; ============================================================================ ;
130; One-use tests.
131; ============================================================================ ;
132
133declare void @use8(i8)
134
135define i1 @n_oneuse0(i8 %x) {
136; CHECK-LABEL: @n_oneuse0(
137; CHECK-NEXT:    [[TMP0:%.*]] = shl i8 [[X:%.*]], 5
138; CHECK-NEXT:    call void @use8(i8 [[TMP0]])
139; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[X]], 4
140; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt i8 [[TMP1]], 7
141; CHECK-NEXT:    ret i1 [[TMP2]]
142;
143  %tmp0 = shl i8 %x, 5
144  call void @use8(i8 %tmp0)
145  %tmp1 = ashr exact i8 %tmp0, 5
146  %tmp2 = icmp ne i8 %tmp1, %x
147  ret i1 %tmp2
148}
149
150define i1 @n_oneuse1(i8 %x) {
151; CHECK-LABEL: @n_oneuse1(
152; CHECK-NEXT:    [[TMP0:%.*]] = shl i8 [[X:%.*]], 5
153; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact i8 [[TMP0]], 5
154; CHECK-NEXT:    call void @use8(i8 [[TMP1]])
155; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[TMP1]], [[X]]
156; CHECK-NEXT:    ret i1 [[TMP2]]
157;
158  %tmp0 = shl i8 %x, 5
159  %tmp1 = ashr exact i8 %tmp0, 5
160  call void @use8(i8 %tmp1)
161  %tmp2 = icmp ne i8 %tmp1, %x
162  ret i1 %tmp2
163}
164
165define i1 @n_oneuse2(i8 %x) {
166; CHECK-LABEL: @n_oneuse2(
167; CHECK-NEXT:    [[TMP0:%.*]] = shl i8 [[X:%.*]], 5
168; CHECK-NEXT:    call void @use8(i8 [[TMP0]])
169; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact i8 [[TMP0]], 5
170; CHECK-NEXT:    call void @use8(i8 [[TMP1]])
171; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[TMP1]], [[X]]
172; CHECK-NEXT:    ret i1 [[TMP2]]
173;
174  %tmp0 = shl i8 %x, 5
175  call void @use8(i8 %tmp0)
176  %tmp1 = ashr exact i8 %tmp0, 5
177  call void @use8(i8 %tmp1)
178  %tmp2 = icmp ne i8 %tmp1, %x
179  ret i1 %tmp2
180}
181
182; ============================================================================ ;
183; Negative tests
184; ============================================================================ ;
185
186define i1 @n0(i8 %x) {
187; CHECK-LABEL: @n0(
188; CHECK-NEXT:    [[TMP0:%.*]] = shl i8 [[X:%.*]], 5
189; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact i8 [[TMP0]], 3
190; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[TMP1]], [[X]]
191; CHECK-NEXT:    ret i1 [[TMP2]]
192;
193  %tmp0 = shl i8 %x, 5
194  %tmp1 = ashr exact i8 %tmp0, 3 ; not 5
195  %tmp2 = icmp ne i8 %tmp1, %x
196  ret i1 %tmp2
197}
198
199define i1 @n1(i8 %x) {
200; CHECK-LABEL: @n1(
201; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[X:%.*]], 7
202; CHECK-NEXT:    ret i1 [[TMP1]]
203;
204  %tmp0 = shl i8 %x, 5
205  %tmp1 = lshr exact i8 %tmp0, 5 ; not ashr
206  %tmp2 = icmp ne i8 %tmp1, %x
207  ret i1 %tmp2
208}
209
210define i1 @n2(i8 %x, i8 %y) {
211; CHECK-LABEL: @n2(
212; CHECK-NEXT:    [[TMP0:%.*]] = shl i8 [[X:%.*]], 5
213; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact i8 [[TMP0]], 5
214; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[TMP1]], [[Y:%.*]]
215; CHECK-NEXT:    ret i1 [[TMP2]]
216;
217  %tmp0 = shl i8 %x, 5
218  %tmp1 = ashr exact i8 %tmp0, 5
219  %tmp2 = icmp ne i8 %tmp1, %y ; not %x
220  ret i1 %tmp2
221}
222
223define <2 x i1> @n3_vec_nonsplat(<2 x i8> %x) {
224; CHECK-LABEL: @n3_vec_nonsplat(
225; CHECK-NEXT:    [[TMP0:%.*]] = shl <2 x i8> [[X:%.*]], <i8 5, i8 5>
226; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact <2 x i8> [[TMP0]], <i8 5, i8 3>
227; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i8> [[TMP1]], [[X]]
228; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
229;
230  %tmp0 = shl <2 x i8> %x, <i8 5, i8 5>
231  %tmp1 = ashr exact <2 x i8> %tmp0, <i8 5, i8 3> ; 3 instead of 5
232  %tmp2 = icmp ne <2 x i8> %tmp1, %x
233  ret <2 x i1> %tmp2
234}
235