xref: /llvm-project/llvm/test/Transforms/InstCombine/icmp-rotate.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4declare i8 @llvm.fshl.i8(i8, i8, i8)
5declare i8 @llvm.fshr.i8(i8, i8, i8)
6declare <2 x i5> @llvm.fshl.v2i5(<2 x i5>, <2 x i5>, <2 x i5>)
7declare <2 x i5> @llvm.fshr.v2i5(<2 x i5>, <2 x i5>, <2 x i5>)
8declare void @use(i8)
9
10define i1 @rol_eq(i8 %x, i8 %y, i8 %z) {
11; CHECK-LABEL: @rol_eq(
12; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
13; CHECK-NEXT:    ret i1 [[R]]
14;
15  %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z)
16  %f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %z)
17  %r = icmp eq i8 %f, %f2
18  ret i1 %r
19}
20
21define i1 @rol_ne(i8 %x, i8 %y, i8 %z) {
22; CHECK-LABEL: @rol_ne(
23; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[X:%.*]], [[Y:%.*]]
24; CHECK-NEXT:    ret i1 [[R]]
25;
26  %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z)
27  %f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %z)
28  %r = icmp ne i8 %f, %f2
29  ret i1 %r
30}
31
32define i1 @ror_eq(i8 %x, i8 %y, i8 %z) {
33; CHECK-LABEL: @ror_eq(
34; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
35; CHECK-NEXT:    ret i1 [[R]]
36;
37  %f = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %z)
38  %f2 = tail call i8 @llvm.fshr.i8(i8 %y, i8 %y, i8 %z)
39  %r = icmp eq i8 %f, %f2
40  ret i1 %r
41}
42
43
44define i1 @ror_ne(i8 %x, i8 %y, i8 %z) {
45; CHECK-LABEL: @ror_ne(
46; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[X:%.*]], [[Y:%.*]]
47; CHECK-NEXT:    ret i1 [[R]]
48;
49  %f = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %z)
50  %f2 = tail call i8 @llvm.fshr.i8(i8 %y, i8 %y, i8 %z)
51  %r = icmp ne i8 %f, %f2
52  ret i1 %r
53}
54
55define i1 @rol_eq_use(i8 %x, i8 %y, i8 %z) {
56; CHECK-LABEL: @rol_eq_use(
57; CHECK-NEXT:    [[F:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Z:%.*]])
58; CHECK-NEXT:    call void @use(i8 [[F]])
59; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X]], [[Y:%.*]]
60; CHECK-NEXT:    ret i1 [[R]]
61;
62  %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z)
63  call void @use(i8 %f)
64  %f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %z)
65  %r = icmp eq i8 %f, %f2
66  ret i1 %r
67}
68
69define i1 @rol_eq_uses(i8 %x, i8 %y, i8 %z) {
70; CHECK-LABEL: @rol_eq_uses(
71; CHECK-NEXT:    [[F:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Z:%.*]])
72; CHECK-NEXT:    call void @use(i8 [[F]])
73; CHECK-NEXT:    [[F2:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[Y:%.*]], i8 [[Y]], i8 [[Z]])
74; CHECK-NEXT:    call void @use(i8 [[F2]])
75; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X]], [[Y]]
76; CHECK-NEXT:    ret i1 [[R]]
77;
78  %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z)
79  call void @use(i8 %f)
80  %f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %z)
81  call void @use(i8 %f2)
82  %r = icmp eq i8 %f, %f2
83  ret i1 %r
84}
85
86define <2 x i1> @rol_eq_vec(<2 x i5> %x, <2 x i5> %y, <2 x i5> %z) {
87; CHECK-LABEL: @rol_eq_vec(
88; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i5> [[X:%.*]], [[Y:%.*]]
89; CHECK-NEXT:    ret <2 x i1> [[R]]
90;
91  %f = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5> %x, <2 x i5> %x, <2 x i5> %z)
92  %f2 = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5> %y, <2 x i5> %y, <2 x i5> %z)
93  %r = icmp eq <2 x i5> %f, %f2
94  ret <2 x i1> %r
95}
96
97define <2 x i1> @ror_eq_vec(<2 x i5> %x, <2 x i5> %y, <2 x i5> %z) {
98; CHECK-LABEL: @ror_eq_vec(
99; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i5> [[X:%.*]], [[Y:%.*]]
100; CHECK-NEXT:    ret <2 x i1> [[R]]
101;
102  %f = tail call <2 x i5> @llvm.fshr.v2i5(<2 x i5> %x, <2 x i5> %x, <2 x i5> %z)
103  %f2 = tail call <2 x i5> @llvm.fshr.v2i5(<2 x i5> %y, <2 x i5> %y, <2 x i5> %z)
104  %r = icmp eq <2 x i5> %f, %f2
105  ret <2 x i1> %r
106}
107
108
109define i1 @rol_eq_cst(i8 %x) {
110; CHECK-LABEL: @rol_eq_cst(
111; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X:%.*]], 64
112; CHECK-NEXT:    ret i1 [[R]]
113;
114  %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 3)
115  %r = icmp eq i8 %f, 2
116  ret i1 %r
117}
118
119define i1 @rol_ne_cst(i8 %x) {
120; CHECK-LABEL: @rol_ne_cst(
121; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[X:%.*]], 64
122; CHECK-NEXT:    ret i1 [[R]]
123;
124  %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 3)
125  %r = icmp ne i8 %f, 2
126  ret i1 %r
127}
128
129define i1 @rol_eq_cst_use(i8 %x) {
130; CHECK-LABEL: @rol_eq_cst_use(
131; CHECK-NEXT:    [[F:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 3)
132; CHECK-NEXT:    call void @use(i8 [[F]])
133; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X]], 64
134; CHECK-NEXT:    ret i1 [[R]]
135;
136  %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 3)
137  call void @use(i8 %f)
138  %r = icmp eq i8 %f, 2
139  ret i1 %r
140}
141
142define i1 @ror_eq_cst(i8 %x) {
143; CHECK-LABEL: @ror_eq_cst(
144; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X:%.*]], 12
145; CHECK-NEXT:    ret i1 [[R]]
146;
147  %f = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 2)
148  %r = icmp eq i8 %f, 3
149  ret i1 %r
150}
151
152define i1 @ror_ne_cst(i8 %x) {
153; CHECK-LABEL: @ror_ne_cst(
154; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[X:%.*]], 12
155; CHECK-NEXT:    ret i1 [[R]]
156;
157  %f = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 2)
158  %r = icmp ne i8 %f, 3
159  ret i1 %r
160}
161
162define <2 x i1> @rol_eq_cst_vec(<2 x i5> %x) {
163; CHECK-LABEL: @rol_eq_cst_vec(
164; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i5> [[X:%.*]], splat (i5 8)
165; CHECK-NEXT:    ret <2 x i1> [[R]]
166;
167  %f = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5> %x, <2 x i5> %x, <2 x i5> <i5 3, i5 3>)
168  %r = icmp eq <2 x i5> %f, <i5 2, i5 2>
169  ret <2 x i1> %r
170}
171
172define <2 x i1> @rol_eq_cst_undef(<2 x i5> %x) {
173; CHECK-LABEL: @rol_eq_cst_undef(
174; CHECK-NEXT:    [[F:%.*]] = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5> [[X:%.*]], <2 x i5> [[X]], <2 x i5> splat (i5 3))
175; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i5> [[F]], <i5 2, i5 undef>
176; CHECK-NEXT:    ret <2 x i1> [[R]]
177;
178  %f = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5> %x, <2 x i5> %x, <2 x i5> <i5 3, i5 3>)
179  %r = icmp eq <2 x i5> %f, <i5 2, i5 undef>
180  ret <2 x i1> %r
181}
182
183; negative test - not a rotate
184define i1 @no_rotate(i8 %x, i8 %y, i8 %z) {
185; CHECK-LABEL: @no_rotate(
186; CHECK-NEXT:    [[F:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]])
187; CHECK-NEXT:    [[F2:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[Y]], i8 [[Y]], i8 [[Z]])
188; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[F]], [[F2]]
189; CHECK-NEXT:    ret i1 [[R]]
190;
191  %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %y, i8 %z)
192  %f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %z)
193  %r = icmp eq i8 %f, %f2
194  ret i1 %r
195}
196
197; negative test - wrong predicate
198define i1 @wrong_pred(i8 %x, i8 %y, i8 %z) {
199; CHECK-LABEL: @wrong_pred(
200; CHECK-NEXT:    [[F:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Z:%.*]])
201; CHECK-NEXT:    [[F2:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[Y:%.*]], i8 [[Y]], i8 [[Z]])
202; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[F]], [[F2]]
203; CHECK-NEXT:    ret i1 [[R]]
204;
205  %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z)
206  %f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %z)
207  %r = icmp ult i8 %f, %f2
208  ret i1 %r
209}
210
211; negative test - rotate amounts mismatch
212define i1 @amounts_mismatch(i8 %x, i8 %y, i8 %z, i8 %w) {
213; CHECK-LABEL: @amounts_mismatch(
214; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 [[Z:%.*]], [[W:%.*]]
215; CHECK-NEXT:    [[TMP2:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[TMP1]])
216; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[Y:%.*]], [[TMP2]]
217; CHECK-NEXT:    ret i1 [[R]]
218;
219  %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z)
220  %f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %w)
221  %r = icmp eq i8 %f, %f2
222  ret i1 %r
223}
224
225; negative test - wrong predicate
226define i1 @wrong_pred2(i8 %x) {
227; CHECK-LABEL: @wrong_pred2(
228; CHECK-NEXT:    [[F:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 5)
229; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[F]], 2
230; CHECK-NEXT:    ret i1 [[R]]
231;
232  %f = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 27)
233  %r = icmp ugt i8 %f, 2
234  ret i1 %r
235}
236