1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 declare i8 @llvm.fshl.i8(i8, i8, i8)
5 declare i8 @llvm.fshr.i8(i8, i8, i8)
6 declare <2 x i5> @llvm.fshl.v2i5(<2 x i5>, <2 x i5>, <2 x i5>)
7 declare <2 x i5> @llvm.fshr.v2i5(<2 x i5>, <2 x i5>, <2 x i5>)
10 define 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]]
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
21 define 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]]
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
32 define 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]]
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
44 define 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]]
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
55 define 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]]
62 %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z)
64 %f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %z)
65 %r = icmp eq i8 %f, %f2
69 define 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]]
78 %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z)
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
86 define <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]]
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
97 define <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]]
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
109 define 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]]
114 %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 3)
115 %r = icmp eq i8 %f, 2
119 define 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]]
124 %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 3)
125 %r = icmp ne i8 %f, 2
129 define 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]]
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
142 define 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]]
147 %f = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 2)
148 %r = icmp eq i8 %f, 3
152 define 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]]
157 %f = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 2)
158 %r = icmp ne i8 %f, 3
162 define <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:%.*]], <i5 8, i5 8>
165 ; CHECK-NEXT: ret <2 x i1> [[R]]
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>
172 define <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> <i5 3, i5 3>)
175 ; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i5> [[F]], <i5 2, i5 undef>
176 ; CHECK-NEXT: ret <2 x i1> [[R]]
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>
183 ; negative test - not a rotate
184 define 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]]
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
197 ; negative test - wrong predicate
198 define 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]]
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
211 ; negative test - rotate amounts mismatch
212 define i1 @amounts_mismatch(i8 %x, i8 %y, i8 %z, i8 %w) {
213 ; CHECK-LABEL: @amounts_mismatch(
214 ; CHECK-NEXT: [[F:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Z:%.*]])
215 ; CHECK-NEXT: [[F2:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[Y:%.*]], i8 [[Y]], i8 [[W:%.*]])
216 ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[F]], [[F2]]
217 ; CHECK-NEXT: ret i1 [[R]]
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
225 ; negative test - wrong predicate
226 define 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]]
232 %f = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 27)
233 %r = icmp ugt i8 %f, 2