Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / CodeGen / aarch64-sve-vls-bitwise-ops.c
blobf6c9e13190774f9fb59ebd18de47c499734ec6fa
1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve \
3 // RUN: -disable-O0-optnone -mvscale-min=4 -mvscale-max=4 \
4 // RUN: -emit-llvm -o - %s | opt -S -passes=sroa | FileCheck %s
6 // REQUIRES: aarch64-registered-target
8 #include <arm_sve.h>
10 #define N 512
12 typedef svint8_t fixed_int8_t __attribute__((arm_sve_vector_bits(N)));
13 typedef svint16_t fixed_int16_t __attribute__((arm_sve_vector_bits(N)));
14 typedef svint32_t fixed_int32_t __attribute__((arm_sve_vector_bits(N)));
15 typedef svint64_t fixed_int64_t __attribute__((arm_sve_vector_bits(N)));
17 typedef svuint8_t fixed_uint8_t __attribute__((arm_sve_vector_bits(N)));
18 typedef svuint16_t fixed_uint16_t __attribute__((arm_sve_vector_bits(N)));
19 typedef svuint32_t fixed_uint32_t __attribute__((arm_sve_vector_bits(N)));
20 typedef svuint64_t fixed_uint64_t __attribute__((arm_sve_vector_bits(N)));
22 typedef svfloat16_t fixed_float16_t __attribute__((arm_sve_vector_bits(N)));
23 typedef svfloat32_t fixed_float32_t __attribute__((arm_sve_vector_bits(N)));
24 typedef svfloat64_t fixed_float64_t __attribute__((arm_sve_vector_bits(N)));
26 typedef svbool_t fixed_bool_t __attribute__((arm_sve_vector_bits(N)));
28 // AND
30 // CHECK-LABEL: @and_bool(
31 // CHECK-NEXT: entry:
32 // CHECK-NEXT: [[A_COERCE:%.*]] = bitcast <vscale x 16 x i1> [[TMP0:%.*]] to <vscale x 2 x i8>
33 // CHECK-NEXT: [[A:%.*]] = call <8 x i8> @llvm.vector.extract.v8i8.nxv2i8(<vscale x 2 x i8> [[A_COERCE]], i64 0)
34 // CHECK-NEXT: [[B_COERCE:%.*]] = bitcast <vscale x 16 x i1> [[TMP1:%.*]] to <vscale x 2 x i8>
35 // CHECK-NEXT: [[B:%.*]] = call <8 x i8> @llvm.vector.extract.v8i8.nxv2i8(<vscale x 2 x i8> [[B_COERCE]], i64 0)
36 // CHECK-NEXT: [[AND:%.*]] = and <8 x i8> [[A]], [[B]]
37 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 2 x i8> @llvm.vector.insert.nxv2i8.v8i8(<vscale x 2 x i8> undef, <8 x i8> [[AND]], i64 0)
38 // CHECK-NEXT: [[TMP2:%.*]] = bitcast <vscale x 2 x i8> [[CASTSCALABLESVE]] to <vscale x 16 x i1>
39 // CHECK-NEXT: ret <vscale x 16 x i1> [[TMP2]]
41 fixed_bool_t and_bool(fixed_bool_t a, fixed_bool_t b) {
42 return a & b;
45 // CHECK-LABEL: @and_i8(
46 // CHECK-NEXT: entry:
47 // CHECK-NEXT: [[A:%.*]] = call <64 x i8> @llvm.vector.extract.v64i8.nxv16i8(<vscale x 16 x i8> [[A_COERCE:%.*]], i64 0)
48 // CHECK-NEXT: [[B:%.*]] = call <64 x i8> @llvm.vector.extract.v64i8.nxv16i8(<vscale x 16 x i8> [[B_COERCE:%.*]], i64 0)
49 // CHECK-NEXT: [[AND:%.*]] = and <64 x i8> [[A]], [[B]]
50 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 16 x i8> @llvm.vector.insert.nxv16i8.v64i8(<vscale x 16 x i8> undef, <64 x i8> [[AND]], i64 0)
51 // CHECK-NEXT: ret <vscale x 16 x i8> [[CASTSCALABLESVE]]
53 fixed_int8_t and_i8(fixed_int8_t a, fixed_int8_t b) {
54 return a & b;
57 // CHECK-LABEL: @and_i16(
58 // CHECK-NEXT: entry:
59 // CHECK-NEXT: [[A:%.*]] = call <32 x i16> @llvm.vector.extract.v32i16.nxv8i16(<vscale x 8 x i16> [[A_COERCE:%.*]], i64 0)
60 // CHECK-NEXT: [[B:%.*]] = call <32 x i16> @llvm.vector.extract.v32i16.nxv8i16(<vscale x 8 x i16> [[B_COERCE:%.*]], i64 0)
61 // CHECK-NEXT: [[AND:%.*]] = and <32 x i16> [[A]], [[B]]
62 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 8 x i16> @llvm.vector.insert.nxv8i16.v32i16(<vscale x 8 x i16> undef, <32 x i16> [[AND]], i64 0)
63 // CHECK-NEXT: ret <vscale x 8 x i16> [[CASTSCALABLESVE]]
65 fixed_int16_t and_i16(fixed_int16_t a, fixed_int16_t b) {
66 return a & b;
69 // CHECK-LABEL: @and_i32(
70 // CHECK-NEXT: entry:
71 // CHECK-NEXT: [[A:%.*]] = call <16 x i32> @llvm.vector.extract.v16i32.nxv4i32(<vscale x 4 x i32> [[A_COERCE:%.*]], i64 0)
72 // CHECK-NEXT: [[B:%.*]] = call <16 x i32> @llvm.vector.extract.v16i32.nxv4i32(<vscale x 4 x i32> [[B_COERCE:%.*]], i64 0)
73 // CHECK-NEXT: [[AND:%.*]] = and <16 x i32> [[A]], [[B]]
74 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> undef, <16 x i32> [[AND]], i64 0)
75 // CHECK-NEXT: ret <vscale x 4 x i32> [[CASTSCALABLESVE]]
77 fixed_int32_t and_i32(fixed_int32_t a, fixed_int32_t b) {
78 return a & b;
81 // CHECK-LABEL: @and_i64(
82 // CHECK-NEXT: entry:
83 // CHECK-NEXT: [[A:%.*]] = call <8 x i64> @llvm.vector.extract.v8i64.nxv2i64(<vscale x 2 x i64> [[A_COERCE:%.*]], i64 0)
84 // CHECK-NEXT: [[B:%.*]] = call <8 x i64> @llvm.vector.extract.v8i64.nxv2i64(<vscale x 2 x i64> [[B_COERCE:%.*]], i64 0)
85 // CHECK-NEXT: [[AND:%.*]] = and <8 x i64> [[A]], [[B]]
86 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 2 x i64> @llvm.vector.insert.nxv2i64.v8i64(<vscale x 2 x i64> undef, <8 x i64> [[AND]], i64 0)
87 // CHECK-NEXT: ret <vscale x 2 x i64> [[CASTSCALABLESVE]]
89 fixed_int64_t and_i64(fixed_int64_t a, fixed_int64_t b) {
90 return a & b;
93 // CHECK-LABEL: @and_u8(
94 // CHECK-NEXT: entry:
95 // CHECK-NEXT: [[A:%.*]] = call <64 x i8> @llvm.vector.extract.v64i8.nxv16i8(<vscale x 16 x i8> [[A_COERCE:%.*]], i64 0)
96 // CHECK-NEXT: [[B:%.*]] = call <64 x i8> @llvm.vector.extract.v64i8.nxv16i8(<vscale x 16 x i8> [[B_COERCE:%.*]], i64 0)
97 // CHECK-NEXT: [[AND:%.*]] = and <64 x i8> [[A]], [[B]]
98 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 16 x i8> @llvm.vector.insert.nxv16i8.v64i8(<vscale x 16 x i8> undef, <64 x i8> [[AND]], i64 0)
99 // CHECK-NEXT: ret <vscale x 16 x i8> [[CASTSCALABLESVE]]
101 fixed_uint8_t and_u8(fixed_uint8_t a, fixed_uint8_t b) {
102 return a & b;
105 // CHECK-LABEL: @and_u16(
106 // CHECK-NEXT: entry:
107 // CHECK-NEXT: [[A:%.*]] = call <32 x i16> @llvm.vector.extract.v32i16.nxv8i16(<vscale x 8 x i16> [[A_COERCE:%.*]], i64 0)
108 // CHECK-NEXT: [[B:%.*]] = call <32 x i16> @llvm.vector.extract.v32i16.nxv8i16(<vscale x 8 x i16> [[B_COERCE:%.*]], i64 0)
109 // CHECK-NEXT: [[AND:%.*]] = and <32 x i16> [[A]], [[B]]
110 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 8 x i16> @llvm.vector.insert.nxv8i16.v32i16(<vscale x 8 x i16> undef, <32 x i16> [[AND]], i64 0)
111 // CHECK-NEXT: ret <vscale x 8 x i16> [[CASTSCALABLESVE]]
113 fixed_uint16_t and_u16(fixed_uint16_t a, fixed_uint16_t b) {
114 return a & b;
117 // CHECK-LABEL: @and_u32(
118 // CHECK-NEXT: entry:
119 // CHECK-NEXT: [[A:%.*]] = call <16 x i32> @llvm.vector.extract.v16i32.nxv4i32(<vscale x 4 x i32> [[A_COERCE:%.*]], i64 0)
120 // CHECK-NEXT: [[B:%.*]] = call <16 x i32> @llvm.vector.extract.v16i32.nxv4i32(<vscale x 4 x i32> [[B_COERCE:%.*]], i64 0)
121 // CHECK-NEXT: [[AND:%.*]] = and <16 x i32> [[A]], [[B]]
122 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> undef, <16 x i32> [[AND]], i64 0)
123 // CHECK-NEXT: ret <vscale x 4 x i32> [[CASTSCALABLESVE]]
125 fixed_uint32_t and_u32(fixed_uint32_t a, fixed_uint32_t b) {
126 return a & b;
129 // CHECK-LABEL: @and_u64(
130 // CHECK-NEXT: entry:
131 // CHECK-NEXT: [[A:%.*]] = call <8 x i64> @llvm.vector.extract.v8i64.nxv2i64(<vscale x 2 x i64> [[A_COERCE:%.*]], i64 0)
132 // CHECK-NEXT: [[B:%.*]] = call <8 x i64> @llvm.vector.extract.v8i64.nxv2i64(<vscale x 2 x i64> [[B_COERCE:%.*]], i64 0)
133 // CHECK-NEXT: [[AND:%.*]] = and <8 x i64> [[A]], [[B]]
134 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 2 x i64> @llvm.vector.insert.nxv2i64.v8i64(<vscale x 2 x i64> undef, <8 x i64> [[AND]], i64 0)
135 // CHECK-NEXT: ret <vscale x 2 x i64> [[CASTSCALABLESVE]]
137 fixed_uint64_t and_u64(fixed_uint64_t a, fixed_uint64_t b) {
138 return a & b;
141 // OR
143 // CHECK-LABEL: @or_bool(
144 // CHECK-NEXT: entry:
145 // CHECK-NEXT: [[A_COERCE:%.*]] = bitcast <vscale x 16 x i1> [[TMP0:%.*]] to <vscale x 2 x i8>
146 // CHECK-NEXT: [[A:%.*]] = call <8 x i8> @llvm.vector.extract.v8i8.nxv2i8(<vscale x 2 x i8> [[A_COERCE]], i64 0)
147 // CHECK-NEXT: [[B_COERCE:%.*]] = bitcast <vscale x 16 x i1> [[TMP1:%.*]] to <vscale x 2 x i8>
148 // CHECK-NEXT: [[B:%.*]] = call <8 x i8> @llvm.vector.extract.v8i8.nxv2i8(<vscale x 2 x i8> [[B_COERCE]], i64 0)
149 // CHECK-NEXT: [[OR:%.*]] = or <8 x i8> [[A]], [[B]]
150 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 2 x i8> @llvm.vector.insert.nxv2i8.v8i8(<vscale x 2 x i8> undef, <8 x i8> [[OR]], i64 0)
151 // CHECK-NEXT: [[TMP2:%.*]] = bitcast <vscale x 2 x i8> [[CASTSCALABLESVE]] to <vscale x 16 x i1>
152 // CHECK-NEXT: ret <vscale x 16 x i1> [[TMP2]]
154 fixed_bool_t or_bool(fixed_bool_t a, fixed_bool_t b) {
155 return a | b;
158 // CHECK-LABEL: @or_i8(
159 // CHECK-NEXT: entry:
160 // CHECK-NEXT: [[A:%.*]] = call <64 x i8> @llvm.vector.extract.v64i8.nxv16i8(<vscale x 16 x i8> [[A_COERCE:%.*]], i64 0)
161 // CHECK-NEXT: [[B:%.*]] = call <64 x i8> @llvm.vector.extract.v64i8.nxv16i8(<vscale x 16 x i8> [[B_COERCE:%.*]], i64 0)
162 // CHECK-NEXT: [[OR:%.*]] = or <64 x i8> [[A]], [[B]]
163 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 16 x i8> @llvm.vector.insert.nxv16i8.v64i8(<vscale x 16 x i8> undef, <64 x i8> [[OR]], i64 0)
164 // CHECK-NEXT: ret <vscale x 16 x i8> [[CASTSCALABLESVE]]
166 fixed_int8_t or_i8(fixed_int8_t a, fixed_int8_t b) {
167 return a | b;
170 // CHECK-LABEL: @or_i16(
171 // CHECK-NEXT: entry:
172 // CHECK-NEXT: [[A:%.*]] = call <32 x i16> @llvm.vector.extract.v32i16.nxv8i16(<vscale x 8 x i16> [[A_COERCE:%.*]], i64 0)
173 // CHECK-NEXT: [[B:%.*]] = call <32 x i16> @llvm.vector.extract.v32i16.nxv8i16(<vscale x 8 x i16> [[B_COERCE:%.*]], i64 0)
174 // CHECK-NEXT: [[OR:%.*]] = or <32 x i16> [[A]], [[B]]
175 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 8 x i16> @llvm.vector.insert.nxv8i16.v32i16(<vscale x 8 x i16> undef, <32 x i16> [[OR]], i64 0)
176 // CHECK-NEXT: ret <vscale x 8 x i16> [[CASTSCALABLESVE]]
178 fixed_int16_t or_i16(fixed_int16_t a, fixed_int16_t b) {
179 return a | b;
182 // CHECK-LABEL: @or_i32(
183 // CHECK-NEXT: entry:
184 // CHECK-NEXT: [[A:%.*]] = call <16 x i32> @llvm.vector.extract.v16i32.nxv4i32(<vscale x 4 x i32> [[A_COERCE:%.*]], i64 0)
185 // CHECK-NEXT: [[B:%.*]] = call <16 x i32> @llvm.vector.extract.v16i32.nxv4i32(<vscale x 4 x i32> [[B_COERCE:%.*]], i64 0)
186 // CHECK-NEXT: [[OR:%.*]] = or <16 x i32> [[A]], [[B]]
187 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> undef, <16 x i32> [[OR]], i64 0)
188 // CHECK-NEXT: ret <vscale x 4 x i32> [[CASTSCALABLESVE]]
190 fixed_int32_t or_i32(fixed_int32_t a, fixed_int32_t b) {
191 return a | b;
194 // CHECK-LABEL: @or_i64(
195 // CHECK-NEXT: entry:
196 // CHECK-NEXT: [[A:%.*]] = call <8 x i64> @llvm.vector.extract.v8i64.nxv2i64(<vscale x 2 x i64> [[A_COERCE:%.*]], i64 0)
197 // CHECK-NEXT: [[B:%.*]] = call <8 x i64> @llvm.vector.extract.v8i64.nxv2i64(<vscale x 2 x i64> [[B_COERCE:%.*]], i64 0)
198 // CHECK-NEXT: [[OR:%.*]] = or <8 x i64> [[A]], [[B]]
199 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 2 x i64> @llvm.vector.insert.nxv2i64.v8i64(<vscale x 2 x i64> undef, <8 x i64> [[OR]], i64 0)
200 // CHECK-NEXT: ret <vscale x 2 x i64> [[CASTSCALABLESVE]]
202 fixed_int64_t or_i64(fixed_int64_t a, fixed_int64_t b) {
203 return a | b;
206 // CHECK-LABEL: @or_u8(
207 // CHECK-NEXT: entry:
208 // CHECK-NEXT: [[A:%.*]] = call <64 x i8> @llvm.vector.extract.v64i8.nxv16i8(<vscale x 16 x i8> [[A_COERCE:%.*]], i64 0)
209 // CHECK-NEXT: [[B:%.*]] = call <64 x i8> @llvm.vector.extract.v64i8.nxv16i8(<vscale x 16 x i8> [[B_COERCE:%.*]], i64 0)
210 // CHECK-NEXT: [[OR:%.*]] = or <64 x i8> [[A]], [[B]]
211 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 16 x i8> @llvm.vector.insert.nxv16i8.v64i8(<vscale x 16 x i8> undef, <64 x i8> [[OR]], i64 0)
212 // CHECK-NEXT: ret <vscale x 16 x i8> [[CASTSCALABLESVE]]
214 fixed_uint8_t or_u8(fixed_uint8_t a, fixed_uint8_t b) {
215 return a | b;
218 // CHECK-LABEL: @or_u16(
219 // CHECK-NEXT: entry:
220 // CHECK-NEXT: [[A:%.*]] = call <32 x i16> @llvm.vector.extract.v32i16.nxv8i16(<vscale x 8 x i16> [[A_COERCE:%.*]], i64 0)
221 // CHECK-NEXT: [[B:%.*]] = call <32 x i16> @llvm.vector.extract.v32i16.nxv8i16(<vscale x 8 x i16> [[B_COERCE:%.*]], i64 0)
222 // CHECK-NEXT: [[OR:%.*]] = or <32 x i16> [[A]], [[B]]
223 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 8 x i16> @llvm.vector.insert.nxv8i16.v32i16(<vscale x 8 x i16> undef, <32 x i16> [[OR]], i64 0)
224 // CHECK-NEXT: ret <vscale x 8 x i16> [[CASTSCALABLESVE]]
226 fixed_uint16_t or_u16(fixed_uint16_t a, fixed_uint16_t b) {
227 return a | b;
230 // CHECK-LABEL: @or_u32(
231 // CHECK-NEXT: entry:
232 // CHECK-NEXT: [[A:%.*]] = call <16 x i32> @llvm.vector.extract.v16i32.nxv4i32(<vscale x 4 x i32> [[A_COERCE:%.*]], i64 0)
233 // CHECK-NEXT: [[B:%.*]] = call <16 x i32> @llvm.vector.extract.v16i32.nxv4i32(<vscale x 4 x i32> [[B_COERCE:%.*]], i64 0)
234 // CHECK-NEXT: [[OR:%.*]] = or <16 x i32> [[A]], [[B]]
235 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> undef, <16 x i32> [[OR]], i64 0)
236 // CHECK-NEXT: ret <vscale x 4 x i32> [[CASTSCALABLESVE]]
238 fixed_uint32_t or_u32(fixed_uint32_t a, fixed_uint32_t b) {
239 return a | b;
242 // CHECK-LABEL: @or_u64(
243 // CHECK-NEXT: entry:
244 // CHECK-NEXT: [[A:%.*]] = call <8 x i64> @llvm.vector.extract.v8i64.nxv2i64(<vscale x 2 x i64> [[A_COERCE:%.*]], i64 0)
245 // CHECK-NEXT: [[B:%.*]] = call <8 x i64> @llvm.vector.extract.v8i64.nxv2i64(<vscale x 2 x i64> [[B_COERCE:%.*]], i64 0)
246 // CHECK-NEXT: [[OR:%.*]] = or <8 x i64> [[A]], [[B]]
247 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 2 x i64> @llvm.vector.insert.nxv2i64.v8i64(<vscale x 2 x i64> undef, <8 x i64> [[OR]], i64 0)
248 // CHECK-NEXT: ret <vscale x 2 x i64> [[CASTSCALABLESVE]]
250 fixed_uint64_t or_u64(fixed_uint64_t a, fixed_uint64_t b) {
251 return a | b;
254 // XOR
256 // CHECK-LABEL: @xor_bool(
257 // CHECK-NEXT: entry:
258 // CHECK-NEXT: [[A_COERCE:%.*]] = bitcast <vscale x 16 x i1> [[TMP0:%.*]] to <vscale x 2 x i8>
259 // CHECK-NEXT: [[A:%.*]] = call <8 x i8> @llvm.vector.extract.v8i8.nxv2i8(<vscale x 2 x i8> [[A_COERCE]], i64 0)
260 // CHECK-NEXT: [[B_COERCE:%.*]] = bitcast <vscale x 16 x i1> [[TMP1:%.*]] to <vscale x 2 x i8>
261 // CHECK-NEXT: [[B:%.*]] = call <8 x i8> @llvm.vector.extract.v8i8.nxv2i8(<vscale x 2 x i8> [[B_COERCE]], i64 0)
262 // CHECK-NEXT: [[XOR:%.*]] = xor <8 x i8> [[A]], [[B]]
263 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 2 x i8> @llvm.vector.insert.nxv2i8.v8i8(<vscale x 2 x i8> undef, <8 x i8> [[XOR]], i64 0)
264 // CHECK-NEXT: [[TMP2:%.*]] = bitcast <vscale x 2 x i8> [[CASTSCALABLESVE]] to <vscale x 16 x i1>
265 // CHECK-NEXT: ret <vscale x 16 x i1> [[TMP2]]
267 fixed_bool_t xor_bool(fixed_bool_t a, fixed_bool_t b) {
268 return a ^ b;
271 // CHECK-LABEL: @xor_i8(
272 // CHECK-NEXT: entry:
273 // CHECK-NEXT: [[A:%.*]] = call <64 x i8> @llvm.vector.extract.v64i8.nxv16i8(<vscale x 16 x i8> [[A_COERCE:%.*]], i64 0)
274 // CHECK-NEXT: [[B:%.*]] = call <64 x i8> @llvm.vector.extract.v64i8.nxv16i8(<vscale x 16 x i8> [[B_COERCE:%.*]], i64 0)
275 // CHECK-NEXT: [[XOR:%.*]] = xor <64 x i8> [[A]], [[B]]
276 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 16 x i8> @llvm.vector.insert.nxv16i8.v64i8(<vscale x 16 x i8> undef, <64 x i8> [[XOR]], i64 0)
277 // CHECK-NEXT: ret <vscale x 16 x i8> [[CASTSCALABLESVE]]
279 fixed_int8_t xor_i8(fixed_int8_t a, fixed_int8_t b) {
280 return a ^ b;
283 // CHECK-LABEL: @xor_i16(
284 // CHECK-NEXT: entry:
285 // CHECK-NEXT: [[A:%.*]] = call <32 x i16> @llvm.vector.extract.v32i16.nxv8i16(<vscale x 8 x i16> [[A_COERCE:%.*]], i64 0)
286 // CHECK-NEXT: [[B:%.*]] = call <32 x i16> @llvm.vector.extract.v32i16.nxv8i16(<vscale x 8 x i16> [[B_COERCE:%.*]], i64 0)
287 // CHECK-NEXT: [[XOR:%.*]] = xor <32 x i16> [[A]], [[B]]
288 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 8 x i16> @llvm.vector.insert.nxv8i16.v32i16(<vscale x 8 x i16> undef, <32 x i16> [[XOR]], i64 0)
289 // CHECK-NEXT: ret <vscale x 8 x i16> [[CASTSCALABLESVE]]
291 fixed_int16_t xor_i16(fixed_int16_t a, fixed_int16_t b) {
292 return a ^ b;
295 // CHECK-LABEL: @xor_i32(
296 // CHECK-NEXT: entry:
297 // CHECK-NEXT: [[A:%.*]] = call <16 x i32> @llvm.vector.extract.v16i32.nxv4i32(<vscale x 4 x i32> [[A_COERCE:%.*]], i64 0)
298 // CHECK-NEXT: [[B:%.*]] = call <16 x i32> @llvm.vector.extract.v16i32.nxv4i32(<vscale x 4 x i32> [[B_COERCE:%.*]], i64 0)
299 // CHECK-NEXT: [[XOR:%.*]] = xor <16 x i32> [[A]], [[B]]
300 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> undef, <16 x i32> [[XOR]], i64 0)
301 // CHECK-NEXT: ret <vscale x 4 x i32> [[CASTSCALABLESVE]]
303 fixed_int32_t xor_i32(fixed_int32_t a, fixed_int32_t b) {
304 return a ^ b;
307 // CHECK-LABEL: @xor_i64(
308 // CHECK-NEXT: entry:
309 // CHECK-NEXT: [[A:%.*]] = call <8 x i64> @llvm.vector.extract.v8i64.nxv2i64(<vscale x 2 x i64> [[A_COERCE:%.*]], i64 0)
310 // CHECK-NEXT: [[B:%.*]] = call <8 x i64> @llvm.vector.extract.v8i64.nxv2i64(<vscale x 2 x i64> [[B_COERCE:%.*]], i64 0)
311 // CHECK-NEXT: [[XOR:%.*]] = xor <8 x i64> [[A]], [[B]]
312 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 2 x i64> @llvm.vector.insert.nxv2i64.v8i64(<vscale x 2 x i64> undef, <8 x i64> [[XOR]], i64 0)
313 // CHECK-NEXT: ret <vscale x 2 x i64> [[CASTSCALABLESVE]]
315 fixed_int64_t xor_i64(fixed_int64_t a, fixed_int64_t b) {
316 return a ^ b;
319 // CHECK-LABEL: @xor_u8(
320 // CHECK-NEXT: entry:
321 // CHECK-NEXT: [[A:%.*]] = call <64 x i8> @llvm.vector.extract.v64i8.nxv16i8(<vscale x 16 x i8> [[A_COERCE:%.*]], i64 0)
322 // CHECK-NEXT: [[B:%.*]] = call <64 x i8> @llvm.vector.extract.v64i8.nxv16i8(<vscale x 16 x i8> [[B_COERCE:%.*]], i64 0)
323 // CHECK-NEXT: [[XOR:%.*]] = xor <64 x i8> [[A]], [[B]]
324 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 16 x i8> @llvm.vector.insert.nxv16i8.v64i8(<vscale x 16 x i8> undef, <64 x i8> [[XOR]], i64 0)
325 // CHECK-NEXT: ret <vscale x 16 x i8> [[CASTSCALABLESVE]]
327 fixed_uint8_t xor_u8(fixed_uint8_t a, fixed_uint8_t b) {
328 return a ^ b;
331 // CHECK-LABEL: @xor_u16(
332 // CHECK-NEXT: entry:
333 // CHECK-NEXT: [[A:%.*]] = call <32 x i16> @llvm.vector.extract.v32i16.nxv8i16(<vscale x 8 x i16> [[A_COERCE:%.*]], i64 0)
334 // CHECK-NEXT: [[B:%.*]] = call <32 x i16> @llvm.vector.extract.v32i16.nxv8i16(<vscale x 8 x i16> [[B_COERCE:%.*]], i64 0)
335 // CHECK-NEXT: [[XOR:%.*]] = xor <32 x i16> [[A]], [[B]]
336 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 8 x i16> @llvm.vector.insert.nxv8i16.v32i16(<vscale x 8 x i16> undef, <32 x i16> [[XOR]], i64 0)
337 // CHECK-NEXT: ret <vscale x 8 x i16> [[CASTSCALABLESVE]]
339 fixed_uint16_t xor_u16(fixed_uint16_t a, fixed_uint16_t b) {
340 return a ^ b;
343 // CHECK-LABEL: @xor_u32(
344 // CHECK-NEXT: entry:
345 // CHECK-NEXT: [[A:%.*]] = call <16 x i32> @llvm.vector.extract.v16i32.nxv4i32(<vscale x 4 x i32> [[A_COERCE:%.*]], i64 0)
346 // CHECK-NEXT: [[B:%.*]] = call <16 x i32> @llvm.vector.extract.v16i32.nxv4i32(<vscale x 4 x i32> [[B_COERCE:%.*]], i64 0)
347 // CHECK-NEXT: [[XOR:%.*]] = xor <16 x i32> [[A]], [[B]]
348 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> undef, <16 x i32> [[XOR]], i64 0)
349 // CHECK-NEXT: ret <vscale x 4 x i32> [[CASTSCALABLESVE]]
351 fixed_uint32_t xor_u32(fixed_uint32_t a, fixed_uint32_t b) {
352 return a ^ b;
355 // CHECK-LABEL: @xor_u64(
356 // CHECK-NEXT: entry:
357 // CHECK-NEXT: [[A:%.*]] = call <8 x i64> @llvm.vector.extract.v8i64.nxv2i64(<vscale x 2 x i64> [[A_COERCE:%.*]], i64 0)
358 // CHECK-NEXT: [[B:%.*]] = call <8 x i64> @llvm.vector.extract.v8i64.nxv2i64(<vscale x 2 x i64> [[B_COERCE:%.*]], i64 0)
359 // CHECK-NEXT: [[XOR:%.*]] = xor <8 x i64> [[A]], [[B]]
360 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 2 x i64> @llvm.vector.insert.nxv2i64.v8i64(<vscale x 2 x i64> undef, <8 x i64> [[XOR]], i64 0)
361 // CHECK-NEXT: ret <vscale x 2 x i64> [[CASTSCALABLESVE]]
363 fixed_uint64_t xor_u64(fixed_uint64_t a, fixed_uint64_t b) {
364 return a ^ b;
367 // NEG
369 // CHECK-LABEL: @neg_bool(
370 // CHECK-NEXT: entry:
371 // CHECK-NEXT: [[A_COERCE:%.*]] = bitcast <vscale x 16 x i1> [[TMP0:%.*]] to <vscale x 2 x i8>
372 // CHECK-NEXT: [[A:%.*]] = call <8 x i8> @llvm.vector.extract.v8i8.nxv2i8(<vscale x 2 x i8> [[A_COERCE]], i64 0)
373 // CHECK-NEXT: [[NEG:%.*]] = xor <8 x i8> [[A]], <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
374 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 2 x i8> @llvm.vector.insert.nxv2i8.v8i8(<vscale x 2 x i8> undef, <8 x i8> [[NEG]], i64 0)
375 // CHECK-NEXT: [[TMP1:%.*]] = bitcast <vscale x 2 x i8> [[CASTSCALABLESVE]] to <vscale x 16 x i1>
376 // CHECK-NEXT: ret <vscale x 16 x i1> [[TMP1]]
378 fixed_bool_t neg_bool(fixed_bool_t a) {
379 return ~a;
382 // CHECK-LABEL: @neg_i8(
383 // CHECK-NEXT: entry:
384 // CHECK-NEXT: [[A:%.*]] = call <64 x i8> @llvm.vector.extract.v64i8.nxv16i8(<vscale x 16 x i8> [[A_COERCE:%.*]], i64 0)
385 // CHECK-NEXT: [[NEG:%.*]] = xor <64 x i8> [[A]], <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
386 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 16 x i8> @llvm.vector.insert.nxv16i8.v64i8(<vscale x 16 x i8> undef, <64 x i8> [[NEG]], i64 0)
387 // CHECK-NEXT: ret <vscale x 16 x i8> [[CASTSCALABLESVE]]
389 fixed_int8_t neg_i8(fixed_int8_t a) {
390 return ~a;
393 // CHECK-LABEL: @neg_i16(
394 // CHECK-NEXT: entry:
395 // CHECK-NEXT: [[A:%.*]] = call <32 x i16> @llvm.vector.extract.v32i16.nxv8i16(<vscale x 8 x i16> [[A_COERCE:%.*]], i64 0)
396 // CHECK-NEXT: [[NEG:%.*]] = xor <32 x i16> [[A]], <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
397 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 8 x i16> @llvm.vector.insert.nxv8i16.v32i16(<vscale x 8 x i16> undef, <32 x i16> [[NEG]], i64 0)
398 // CHECK-NEXT: ret <vscale x 8 x i16> [[CASTSCALABLESVE]]
400 fixed_int16_t neg_i16(fixed_int16_t a) {
401 return ~a;
404 // CHECK-LABEL: @neg_i32(
405 // CHECK-NEXT: entry:
406 // CHECK-NEXT: [[A:%.*]] = call <16 x i32> @llvm.vector.extract.v16i32.nxv4i32(<vscale x 4 x i32> [[A_COERCE:%.*]], i64 0)
407 // CHECK-NEXT: [[NEG:%.*]] = xor <16 x i32> [[A]], <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
408 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> undef, <16 x i32> [[NEG]], i64 0)
409 // CHECK-NEXT: ret <vscale x 4 x i32> [[CASTSCALABLESVE]]
411 fixed_int32_t neg_i32(fixed_int32_t a) {
412 return ~a;
415 // CHECK-LABEL: @neg_i64(
416 // CHECK-NEXT: entry:
417 // CHECK-NEXT: [[A:%.*]] = call <8 x i64> @llvm.vector.extract.v8i64.nxv2i64(<vscale x 2 x i64> [[A_COERCE:%.*]], i64 0)
418 // CHECK-NEXT: [[NEG:%.*]] = xor <8 x i64> [[A]], <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>
419 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 2 x i64> @llvm.vector.insert.nxv2i64.v8i64(<vscale x 2 x i64> undef, <8 x i64> [[NEG]], i64 0)
420 // CHECK-NEXT: ret <vscale x 2 x i64> [[CASTSCALABLESVE]]
422 fixed_int64_t neg_i64(fixed_int64_t a) {
423 return ~a;
426 // CHECK-LABEL: @neg_u8(
427 // CHECK-NEXT: entry:
428 // CHECK-NEXT: [[A:%.*]] = call <64 x i8> @llvm.vector.extract.v64i8.nxv16i8(<vscale x 16 x i8> [[A_COERCE:%.*]], i64 0)
429 // CHECK-NEXT: [[NEG:%.*]] = xor <64 x i8> [[A]], <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
430 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 16 x i8> @llvm.vector.insert.nxv16i8.v64i8(<vscale x 16 x i8> undef, <64 x i8> [[NEG]], i64 0)
431 // CHECK-NEXT: ret <vscale x 16 x i8> [[CASTSCALABLESVE]]
433 fixed_uint8_t neg_u8(fixed_uint8_t a) {
434 return ~a;
437 // CHECK-LABEL: @neg_u16(
438 // CHECK-NEXT: entry:
439 // CHECK-NEXT: [[A:%.*]] = call <32 x i16> @llvm.vector.extract.v32i16.nxv8i16(<vscale x 8 x i16> [[A_COERCE:%.*]], i64 0)
440 // CHECK-NEXT: [[NEG:%.*]] = xor <32 x i16> [[A]], <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
441 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 8 x i16> @llvm.vector.insert.nxv8i16.v32i16(<vscale x 8 x i16> undef, <32 x i16> [[NEG]], i64 0)
442 // CHECK-NEXT: ret <vscale x 8 x i16> [[CASTSCALABLESVE]]
444 fixed_uint16_t neg_u16(fixed_uint16_t a) {
445 return ~a;
448 // CHECK-LABEL: @neg_u32(
449 // CHECK-NEXT: entry:
450 // CHECK-NEXT: [[A:%.*]] = call <16 x i32> @llvm.vector.extract.v16i32.nxv4i32(<vscale x 4 x i32> [[A_COERCE:%.*]], i64 0)
451 // CHECK-NEXT: [[NEG:%.*]] = xor <16 x i32> [[A]], <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
452 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> undef, <16 x i32> [[NEG]], i64 0)
453 // CHECK-NEXT: ret <vscale x 4 x i32> [[CASTSCALABLESVE]]
455 fixed_uint32_t neg_u32(fixed_uint32_t a) {
456 return ~a;
459 // CHECK-LABEL: @neg_u64(
460 // CHECK-NEXT: entry:
461 // CHECK-NEXT: [[A:%.*]] = call <8 x i64> @llvm.vector.extract.v8i64.nxv2i64(<vscale x 2 x i64> [[A_COERCE:%.*]], i64 0)
462 // CHECK-NEXT: [[NEG:%.*]] = xor <8 x i64> [[A]], <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>
463 // CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 2 x i64> @llvm.vector.insert.nxv2i64.v8i64(<vscale x 2 x i64> undef, <8 x i64> [[NEG]], i64 0)
464 // CHECK-NEXT: ret <vscale x 2 x i64> [[CASTSCALABLESVE]]
466 fixed_uint64_t neg_u64(fixed_uint64_t a) {
467 return ~a;