xref: /llvm-project/llvm/test/Transforms/InstCombine/vector-logical-reductions.ll (revision f6add66b720f85bf1092af7d6702b7397da57349)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4define i1 @reduction_logical_or(<4 x i1> %x) {
5; CHECK-LABEL: @reduction_logical_or(
6; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i1> [[X:%.*]] to i4
7; CHECK-NEXT:    [[R:%.*]] = icmp ne i4 [[TMP1]], 0
8; CHECK-NEXT:    ret i1 [[R]]
9;
10  %r = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> %x)
11  ret i1 %r
12}
13
14define i1 @reduction_logical_or_nxv2i1(<vscale x 2 x i1> %x) {
15; CHECK-LABEL: @reduction_logical_or_nxv2i1(
16; CHECK-NEXT:    [[R:%.*]] = call i1 @llvm.vector.reduce.or.nxv2i1(<vscale x 2 x i1> [[X:%.*]])
17; CHECK-NEXT:    ret i1 [[R]]
18;
19  %r = call i1 @llvm.vector.reduce.or.nxv2i1(<vscale x 2 x i1> %x)
20  ret i1 %r
21}
22
23define i1 @reduction_logical_and(<4 x i1> %x) {
24; CHECK-LABEL: @reduction_logical_and(
25; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i1> [[X:%.*]] to i4
26; CHECK-NEXT:    [[R:%.*]] = icmp eq i4 [[TMP1]], -1
27; CHECK-NEXT:    ret i1 [[R]]
28;
29  %r = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> %x)
30  ret i1 %r
31}
32
33define i1 @reduction_logical_and_nxv2i1(<vscale x 2 x i1> %x) {
34; CHECK-LABEL: @reduction_logical_and_nxv2i1(
35; CHECK-NEXT:    [[R:%.*]] = call i1 @llvm.vector.reduce.and.nxv2i1(<vscale x 2 x i1> [[X:%.*]])
36; CHECK-NEXT:    ret i1 [[R]]
37;
38  %r = call i1 @llvm.vector.reduce.and.nxv2i1(<vscale x 2 x i1> %x)
39  ret i1 %r
40}
41
42define i1 @reduction_logical_mul(<2 x i1> %x) {
43; CHECK-LABEL: @reduction_logical_mul(
44; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i1> [[X:%.*]] to i2
45; CHECK-NEXT:    [[R:%.*]] = icmp eq i2 [[TMP1]], -1
46; CHECK-NEXT:    ret i1 [[R]]
47;
48  %r = call i1 @llvm.vector.reduce.mul.v4i1(<2 x i1> %x)
49  ret i1 %r
50}
51
52define i1 @reduction_logical_mul_nxv2i1(<vscale x 2 x i1> %x) {
53; CHECK-LABEL: @reduction_logical_mul_nxv2i1(
54; CHECK-NEXT:    [[R:%.*]] = call i1 @llvm.vector.reduce.and.nxv2i1(<vscale x 2 x i1> [[X:%.*]])
55; CHECK-NEXT:    ret i1 [[R]]
56;
57  %r = call i1 @llvm.vector.reduce.mul.nxv2i1(<vscale x 2 x i1> %x)
58  ret i1 %r
59}
60
61define i1 @reduction_logical_xor(<2 x i1> %x) {
62; CHECK-LABEL: @reduction_logical_xor(
63; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i1> [[X:%.*]] to i2
64; CHECK-NEXT:    [[TMP2:%.*]] = call range(i2 0, -1) i2 @llvm.ctpop.i2(i2 [[TMP1]])
65; CHECK-NEXT:    [[R:%.*]] = trunc i2 [[TMP2]] to i1
66; CHECK-NEXT:    ret i1 [[R]]
67;
68  %r = call i1 @llvm.vector.reduce.xor.v4i1(<2 x i1> %x)
69  ret i1 %r
70}
71
72define i1 @reduction_logical_xor_nxv2i1(<vscale x 2 x i1> %x) {
73; CHECK-LABEL: @reduction_logical_xor_nxv2i1(
74; CHECK-NEXT:    [[R:%.*]] = call i1 @llvm.vector.reduce.add.nxv2i1(<vscale x 2 x i1> [[X:%.*]])
75; CHECK-NEXT:    ret i1 [[R]]
76;
77  %r = call i1 @llvm.vector.reduce.xor.nxv2i1(<vscale x 2 x i1> %x)
78  ret i1 %r
79}
80
81define i1 @reduction_logical_smin(<2 x i1> %x) {
82; CHECK-LABEL: @reduction_logical_smin(
83; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i1> [[X:%.*]] to i2
84; CHECK-NEXT:    [[R:%.*]] = icmp ne i2 [[TMP1]], 0
85; CHECK-NEXT:    ret i1 [[R]]
86;
87  %r = call i1 @llvm.vector.reduce.smin.v4i1(<2 x i1> %x)
88  ret i1 %r
89}
90
91define i1 @reduction_logical_smin_nxv2i1(<vscale x 2 x i1> %x) {
92; CHECK-LABEL: @reduction_logical_smin_nxv2i1(
93; CHECK-NEXT:    [[R:%.*]] = call i1 @llvm.vector.reduce.or.nxv2i1(<vscale x 2 x i1> [[X:%.*]])
94; CHECK-NEXT:    ret i1 [[R]]
95;
96  %r = call i1 @llvm.vector.reduce.smin.nxv2i1(<vscale x 2 x i1> %x)
97  ret i1 %r
98}
99
100define i1 @reduction_logical_smax(<2 x i1> %x) {
101; CHECK-LABEL: @reduction_logical_smax(
102; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i1> [[X:%.*]] to i2
103; CHECK-NEXT:    [[R:%.*]] = icmp eq i2 [[TMP1]], -1
104; CHECK-NEXT:    ret i1 [[R]]
105;
106  %r = call i1 @llvm.vector.reduce.smax.v4i1(<2 x i1> %x)
107  ret i1 %r
108}
109
110define i1 @reduction_logical_smax_nxv2i1(<vscale x 2 x i1> %x) {
111; CHECK-LABEL: @reduction_logical_smax_nxv2i1(
112; CHECK-NEXT:    [[R:%.*]] = call i1 @llvm.vector.reduce.and.nxv2i1(<vscale x 2 x i1> [[X:%.*]])
113; CHECK-NEXT:    ret i1 [[R]]
114;
115  %r = call i1 @llvm.vector.reduce.smax.nxv2i1(<vscale x 2 x i1> %x)
116  ret i1 %r
117}
118
119define i1 @reduction_logical_umin(<2 x i1> %x) {
120; CHECK-LABEL: @reduction_logical_umin(
121; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i1> [[X:%.*]] to i2
122; CHECK-NEXT:    [[R:%.*]] = icmp eq i2 [[TMP1]], -1
123; CHECK-NEXT:    ret i1 [[R]]
124;
125  %r = call i1 @llvm.vector.reduce.umin.v4i1(<2 x i1> %x)
126  ret i1 %r
127}
128
129define i1 @reduction_logical_umin_nxv2i1(<vscale x 2 x i1> %x) {
130; CHECK-LABEL: @reduction_logical_umin_nxv2i1(
131; CHECK-NEXT:    [[R:%.*]] = call i1 @llvm.vector.reduce.and.nxv2i1(<vscale x 2 x i1> [[X:%.*]])
132; CHECK-NEXT:    ret i1 [[R]]
133;
134  %r = call i1 @llvm.vector.reduce.umin.nxv2i1(<vscale x 2 x i1> %x)
135  ret i1 %r
136}
137
138define i1 @reduction_logical_umax(<2 x i1> %x) {
139; CHECK-LABEL: @reduction_logical_umax(
140; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i1> [[X:%.*]] to i2
141; CHECK-NEXT:    [[R:%.*]] = icmp ne i2 [[TMP1]], 0
142; CHECK-NEXT:    ret i1 [[R]]
143;
144  %r = call i1 @llvm.vector.reduce.umax.v4i1(<2 x i1> %x)
145  ret i1 %r
146}
147
148define i1 @reduction_logical_umax_nxv2i1(<vscale x 2 x i1> %x) {
149; CHECK-LABEL: @reduction_logical_umax_nxv2i1(
150; CHECK-NEXT:    [[R:%.*]] = call i1 @llvm.vector.reduce.or.nxv2i1(<vscale x 2 x i1> [[X:%.*]])
151; CHECK-NEXT:    ret i1 [[R]]
152;
153  %r = call i1 @llvm.vector.reduce.umax.nxv2i1(<vscale x 2 x i1> %x)
154  ret i1 %r
155}
156
157
158define i1 @reduction_logical_or_reverse_nxv2i1(<vscale x 2 x i1> %p) {
159; CHECK-LABEL: @reduction_logical_or_reverse_nxv2i1(
160; CHECK-NEXT:    [[RED:%.*]] = call i1 @llvm.vector.reduce.or.nxv2i1(<vscale x 2 x i1> [[P:%.*]])
161; CHECK-NEXT:    ret i1 [[RED]]
162;
163  %rev = call <vscale x 2 x i1> @llvm.vector.reverse.nxv2i1(<vscale x 2 x i1> %p)
164  %red = call i1 @llvm.vector.reduce.or.nxv2i1(<vscale x 2 x i1> %rev)
165  ret i1 %red
166}
167
168define i1 @reduction_logical_or_reverse_v2i1(<2 x i1> %p) {
169; CHECK-LABEL: @reduction_logical_or_reverse_v2i1(
170; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i1> [[P:%.*]] to i2
171; CHECK-NEXT:    [[RED:%.*]] = icmp ne i2 [[TMP1]], 0
172; CHECK-NEXT:    ret i1 [[RED]]
173;
174  %rev = call <2 x i1> @llvm.vector.reverse.v2i1(<2 x i1> %p)
175  %red = call i1 @llvm.vector.reduce.or.v2i1(<2 x i1> %rev)
176  ret i1 %red
177}
178
179define i1 @reduction_logical_and_reverse_nxv2i1(<vscale x 2 x i1> %p) {
180; CHECK-LABEL: @reduction_logical_and_reverse_nxv2i1(
181; CHECK-NEXT:    [[RED:%.*]] = call i1 @llvm.vector.reduce.and.nxv2i1(<vscale x 2 x i1> [[P:%.*]])
182; CHECK-NEXT:    ret i1 [[RED]]
183;
184  %rev = call <vscale x 2 x i1> @llvm.vector.reverse.nxv2i1(<vscale x 2 x i1> %p)
185  %red = call i1 @llvm.vector.reduce.and.nxv2i1(<vscale x 2 x i1> %rev)
186  ret i1 %red
187}
188
189define i1 @reduction_logical_and_reverse_v2i1(<2 x i1> %p) {
190; CHECK-LABEL: @reduction_logical_and_reverse_v2i1(
191; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i1> [[P:%.*]] to i2
192; CHECK-NEXT:    [[RED:%.*]] = icmp eq i2 [[TMP1]], -1
193; CHECK-NEXT:    ret i1 [[RED]]
194;
195  %rev = call <2 x i1> @llvm.vector.reverse.v2i1(<2 x i1> %p)
196  %red = call i1 @llvm.vector.reduce.and.v2i1(<2 x i1> %rev)
197  ret i1 %red
198}
199
200define i1 @reduction_logical_xor_reverse_nxv2i1(<vscale x 2 x i1> %p) {
201; CHECK-LABEL: @reduction_logical_xor_reverse_nxv2i1(
202; CHECK-NEXT:    [[RED:%.*]] = call i1 @llvm.vector.reduce.add.nxv2i1(<vscale x 2 x i1> [[P:%.*]])
203; CHECK-NEXT:    ret i1 [[RED]]
204;
205  %rev = call <vscale x 2 x i1> @llvm.vector.reverse.nxv2i1(<vscale x 2 x i1> %p)
206  %red = call i1 @llvm.vector.reduce.xor.nxv2i1(<vscale x 2 x i1> %rev)
207  ret i1 %red
208}
209
210define i1 @reduction_logical_xor_reverse_v2i1(<2 x i1> %p) {
211; CHECK-LABEL: @reduction_logical_xor_reverse_v2i1(
212; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i1> [[P:%.*]] to i2
213; CHECK-NEXT:    [[TMP2:%.*]] = call range(i2 0, -1) i2 @llvm.ctpop.i2(i2 [[TMP1]])
214; CHECK-NEXT:    [[RED:%.*]] = trunc i2 [[TMP2]] to i1
215; CHECK-NEXT:    ret i1 [[RED]]
216;
217  %rev = call <2 x i1> @llvm.vector.reverse.v2i1(<2 x i1> %p)
218  %red = call i1 @llvm.vector.reduce.xor.v2i1(<2 x i1> %rev)
219  ret i1 %red
220}
221
222declare i1 @llvm.vector.reduce.or.v4i1(<4 x i1>)
223declare i1 @llvm.vector.reduce.or.nxv2i1(<vscale x 2 x i1>)
224declare i1 @llvm.vector.reduce.or.v2i1(<2 x i1>)
225declare i1 @llvm.vector.reduce.and.v4i1(<4 x i1>)
226declare i1 @llvm.vector.reduce.and.nxv2i1(<vscale x 2 x i1>)
227declare i1 @llvm.vector.reduce.and.v2i1(<2 x i1>)
228declare i1 @llvm.vector.reduce.xor.nxv2i1(<vscale x 2 x i1>)
229declare i1 @llvm.vector.reduce.xor.v2i1(<2 x i1>)
230declare i1 @llvm.vector.reduce.mul.nxv2i1(<vscale x 2 x i1>)
231declare i1 @llvm.vector.reduce.mul.v2i1(<2 x i1>)
232declare i1 @llvm.vector.reduce.smin.nxv2i1(<vscale x 2 x i1>)
233declare i1 @llvm.vector.reduce.smin.v2i1(<2 x i1>)
234declare i1 @llvm.vector.reduce.smax.nxv2i1(<vscale x 2 x i1>)
235declare i1 @llvm.vector.reduce.smax.v2i1(<2 x i1>)
236declare i1 @llvm.vector.reduce.umin.nxv2i1(<vscale x 2 x i1>)
237declare i1 @llvm.vector.reduce.umin.v2i1(<2 x i1>)
238declare i1 @llvm.vector.reduce.umax.nxv2i1(<vscale x 2 x i1>)
239declare i1 @llvm.vector.reduce.umax.v2i1(<2 x i1>)
240declare <vscale x 2 x i1> @llvm.vector.reverse.nxv2i1(<vscale x 2 x i1>)
241declare <2 x i1> @llvm.vector.reverse.v2i1(<2 x i1>)
242