xref: /llvm-project/llvm/test/Transforms/InstCombine/icmp-fsh.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 void @use(i8)
8
9define i1 @rotl_eq_0(i8 %x, i8 %y) {
10; CHECK-LABEL: @rotl_eq_0(
11; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X:%.*]], 0
12; CHECK-NEXT:    ret i1 [[R]]
13;
14  %rot = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %y)
15  %r = icmp eq i8 %rot, 0
16  ret i1 %r
17}
18
19; Extra use is ok.
20
21define i1 @rotl_ne_0(i8 %x, i8 %y) {
22; CHECK-LABEL: @rotl_ne_0(
23; CHECK-NEXT:    [[ROT:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]])
24; CHECK-NEXT:    call void @use(i8 [[ROT]])
25; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[X]], 0
26; CHECK-NEXT:    ret i1 [[R]]
27;
28  %rot = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %y)
29  call void @use(i8 %rot)
30  %r = icmp ne i8 %rot, 0
31  ret i1 %r
32}
33
34define i1 @rotl_eq_n1(i8 %x, i8 %y) {
35; CHECK-LABEL: @rotl_eq_n1(
36; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X:%.*]], -1
37; CHECK-NEXT:    ret i1 [[R]]
38;
39  %rot = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %y)
40  %r = icmp eq i8 %rot, -1
41  ret i1 %r
42}
43
44; Vectors work too.
45
46define <2 x i1> @rotl_ne_n1(<2 x i5> %x, <2 x i5> %y) {
47; CHECK-LABEL: @rotl_ne_n1(
48; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i5> [[X:%.*]], splat (i5 -1)
49; CHECK-NEXT:    ret <2 x i1> [[R]]
50;
51  %rot = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5>%x, <2 x i5> %x, <2 x i5> %y)
52  %r = icmp ne <2 x i5> %rot, <i5 -1, i5 -1>
53  ret <2 x i1> %r
54}
55
56define <2 x i1> @rotl_ne_n1_poison(<2 x i5> %x, <2 x i5> %y) {
57; CHECK-LABEL: @rotl_ne_n1_poison(
58; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i5> [[X:%.*]], <i5 -1, i5 poison>
59; CHECK-NEXT:    ret <2 x i1> [[R]]
60;
61  %rot = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5>%x, <2 x i5> %x, <2 x i5> %y)
62  %r = icmp ne <2 x i5> %rot, <i5 -1, i5 poison>
63  ret <2 x i1> %r
64}
65
66define <2 x i1> @rotl_eq_0_poison(<2 x i5> %x, <2 x i5> %y) {
67; CHECK-LABEL: @rotl_eq_0_poison(
68; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i5> [[X:%.*]], <i5 0, i5 poison>
69; CHECK-NEXT:    ret <2 x i1> [[R]]
70;
71  %rot = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5>%x, <2 x i5> %x, <2 x i5> %y)
72  %r = icmp eq <2 x i5> %rot, <i5 0, i5 poison>
73  ret <2 x i1> %r
74}
75
76; negative test - wrong constant value
77
78define <2 x i1> @rotl_eq_1_poison(<2 x i5> %x, <2 x i5> %y) {
79; CHECK-LABEL: @rotl_eq_1_poison(
80; CHECK-NEXT:    [[ROT:%.*]] = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5> [[X:%.*]], <2 x i5> [[X]], <2 x i5> [[Y:%.*]])
81; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i5> [[ROT]], <i5 poison, i5 1>
82; CHECK-NEXT:    ret <2 x i1> [[R]]
83;
84  %rot = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5>%x, <2 x i5> %x, <2 x i5> %y)
85  %r = icmp eq <2 x i5> %rot, <i5 poison, i5 1>
86  ret <2 x i1> %r
87}
88
89; negative test - wrong predicate
90
91define <2 x i1> @rotl_sgt_0_poison(<2 x i5> %x, <2 x i5> %y) {
92; CHECK-LABEL: @rotl_sgt_0_poison(
93; CHECK-NEXT:    [[ROT:%.*]] = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5> [[X:%.*]], <2 x i5> [[X]], <2 x i5> [[Y:%.*]])
94; CHECK-NEXT:    [[R:%.*]] = icmp sgt <2 x i5> [[ROT]], <i5 0, i5 poison>
95; CHECK-NEXT:    ret <2 x i1> [[R]]
96;
97  %rot = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5>%x, <2 x i5> %x, <2 x i5> %y)
98  %r = icmp sgt <2 x i5> %rot, <i5 0, i5 poison>
99  ret <2 x i1> %r
100}
101
102define i1 @rotr_eq_0(i8 %x, i8 %y) {
103; CHECK-LABEL: @rotr_eq_0(
104; CHECK-NEXT:    [[ROT:%.*]] = tail call i8 @llvm.fshr.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]])
105; CHECK-NEXT:    call void @use(i8 [[ROT]])
106; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X]], 0
107; CHECK-NEXT:    ret i1 [[R]]
108;
109  %rot = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %y)
110  call void @use(i8 %rot)
111  %r = icmp eq i8 %rot, 0
112  ret i1 %r
113}
114
115define i1 @rotr_ne_0(i8 %x, i8 %y) {
116; CHECK-LABEL: @rotr_ne_0(
117; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[X:%.*]], 0
118; CHECK-NEXT:    ret i1 [[R]]
119;
120  %rot = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %y)
121  %r = icmp ne i8 %rot, 0
122  ret i1 %r
123}
124
125define i1 @rotr_eq_n1(i8 %x, i8 %y) {
126; CHECK-LABEL: @rotr_eq_n1(
127; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X:%.*]], -1
128; CHECK-NEXT:    ret i1 [[R]]
129;
130  %rot = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %y)
131  %r = icmp eq i8 %rot, -1
132  ret i1 %r
133}
134
135define i1 @rotr_ne_n1(i8 %x, i8 %y) {
136; CHECK-LABEL: @rotr_ne_n1(
137; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[X:%.*]], -1
138; CHECK-NEXT:    ret i1 [[R]]
139;
140  %rot = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %y)
141  %r = icmp ne i8 %rot, -1
142  ret i1 %r
143}
144
145; negative test - wrong constant value
146
147define i1 @rotr_ne_1(i8 %x, i8 %y) {
148; CHECK-LABEL: @rotr_ne_1(
149; CHECK-NEXT:    [[ROT:%.*]] = tail call i8 @llvm.fshr.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]])
150; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[ROT]], 1
151; CHECK-NEXT:    ret i1 [[R]]
152;
153  %rot = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %y)
154  %r = icmp ne i8 %rot, 1
155  ret i1 %r
156}
157
158; negative test - wrong predicate
159
160define i1 @rotr_sgt_n1(i8 %x, i8 %y) {
161; CHECK-LABEL: @rotr_sgt_n1(
162; CHECK-NEXT:    [[ROT:%.*]] = tail call i8 @llvm.fshr.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]])
163; CHECK-NEXT:    [[R:%.*]] = icmp sgt i8 [[ROT]], -1
164; CHECK-NEXT:    ret i1 [[R]]
165;
166  %rot = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %y)
167  %r = icmp sgt i8 %rot, -1
168  ret i1 %r
169}
170
171; negative test - must be a rotate, not general funnel shift
172
173define i1 @fshr_sgt_n1(i8 %x, i8 %y, i8 %z) {
174; CHECK-LABEL: @fshr_sgt_n1(
175; CHECK-NEXT:    [[FSH:%.*]] = tail call i8 @llvm.fshr.i8(i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]])
176; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[FSH]], -1
177; CHECK-NEXT:    ret i1 [[R]]
178;
179  %fsh = tail call i8 @llvm.fshr.i8(i8 %x, i8 %y, i8 %z)
180  %r = icmp eq i8 %fsh, -1
181  ret i1 %r
182}
183