xref: /llvm-project/clang/test/CodeGen/RISCV/rvv-vls-bitwise-ops.c (revision 98e747ba56b2f8b51a7c797a3f379d02c545c42b)
1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2 // RUN: %clang_cc1 -triple riscv64-none-linux-gnu -target-feature +zve64d \
3 // RUN: -target-feature +f -target-feature +d -disable-O0-optnone \
4 // RUN: -mvscale-min=4 -mvscale-max=4 -emit-llvm -o - %s | \
5 // RUN: opt -S -passes=sroa | FileCheck %s
6 
7 // REQUIRES: riscv-registered-target
8 
9 #include <stdint.h>
10 
11 typedef __rvv_int8m1_t vint8m1_t;
12 typedef __rvv_uint8m1_t vuint8m1_t;
13 typedef __rvv_int16m1_t vint16m1_t;
14 typedef __rvv_uint16m1_t vuint16m1_t;
15 typedef __rvv_int32m1_t vint32m1_t;
16 typedef __rvv_uint32m1_t vuint32m1_t;
17 typedef __rvv_int64m1_t vint64m1_t;
18 typedef __rvv_uint64m1_t vuint64m1_t;
19 typedef __rvv_float32m1_t vfloat32m1_t;
20 typedef __rvv_float64m1_t vfloat64m1_t;
21 
22 typedef vint8m1_t fixed_int8m1_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen)));
23 typedef vint16m1_t fixed_int16m1_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen)));
24 typedef vint32m1_t fixed_int32m1_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen)));
25 typedef vint64m1_t fixed_int64m1_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen)));
26 
27 typedef vuint8m1_t fixed_uint8m1_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen)));
28 typedef vuint16m1_t fixed_uint16m1_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen)));
29 typedef vuint32m1_t fixed_uint32m1_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen)));
30 typedef vuint64m1_t fixed_uint64m1_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen)));
31 
32 typedef vfloat32m1_t fixed_float32m1_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen)));
33 typedef vfloat64m1_t fixed_float64m1_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen)));
34 
35 // AND
36 
37 // CHECK-LABEL: @and_i8(
38 // CHECK-NEXT:  entry:
39 // CHECK-NEXT:    [[A:%.*]] = call <32 x i8> @llvm.vector.extract.v32i8.nxv8i8(<vscale x 8 x i8> [[A_COERCE:%.*]], i64 0)
40 // CHECK-NEXT:    [[B:%.*]] = call <32 x i8> @llvm.vector.extract.v32i8.nxv8i8(<vscale x 8 x i8> [[B_COERCE:%.*]], i64 0)
41 // CHECK-NEXT:    [[AND:%.*]] = and <32 x i8> [[A]], [[B]]
42 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 8 x i8> @llvm.vector.insert.nxv8i8.v32i8(<vscale x 8 x i8> poison, <32 x i8> [[AND]], i64 0)
43 // CHECK-NEXT:    ret <vscale x 8 x i8> [[CAST_SCALABLE]]
44 //
45 fixed_int8m1_t and_i8(fixed_int8m1_t a, fixed_int8m1_t b) {
46   return a & b;
47 }
48 
49 // CHECK-LABEL: @and_i16(
50 // CHECK-NEXT:  entry:
51 // CHECK-NEXT:    [[A:%.*]] = call <16 x i16> @llvm.vector.extract.v16i16.nxv4i16(<vscale x 4 x i16> [[A_COERCE:%.*]], i64 0)
52 // CHECK-NEXT:    [[B:%.*]] = call <16 x i16> @llvm.vector.extract.v16i16.nxv4i16(<vscale x 4 x i16> [[B_COERCE:%.*]], i64 0)
53 // CHECK-NEXT:    [[AND:%.*]] = and <16 x i16> [[A]], [[B]]
54 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 4 x i16> @llvm.vector.insert.nxv4i16.v16i16(<vscale x 4 x i16> poison, <16 x i16> [[AND]], i64 0)
55 // CHECK-NEXT:    ret <vscale x 4 x i16> [[CAST_SCALABLE]]
56 //
57 fixed_int16m1_t and_i16(fixed_int16m1_t a, fixed_int16m1_t b) {
58   return a & b;
59 }
60 
61 // CHECK-LABEL: @and_i32(
62 // CHECK-NEXT:  entry:
63 // CHECK-NEXT:    [[A:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32(<vscale x 2 x i32> [[A_COERCE:%.*]], i64 0)
64 // CHECK-NEXT:    [[B:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32(<vscale x 2 x i32> [[B_COERCE:%.*]], i64 0)
65 // CHECK-NEXT:    [[AND:%.*]] = and <8 x i32> [[A]], [[B]]
66 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> poison, <8 x i32> [[AND]], i64 0)
67 // CHECK-NEXT:    ret <vscale x 2 x i32> [[CAST_SCALABLE]]
68 //
69 fixed_int32m1_t and_i32(fixed_int32m1_t a, fixed_int32m1_t b) {
70   return a & b;
71 }
72 
73 // CHECK-LABEL: @and_i64(
74 // CHECK-NEXT:  entry:
75 // CHECK-NEXT:    [[A:%.*]] = call <4 x i64> @llvm.vector.extract.v4i64.nxv1i64(<vscale x 1 x i64> [[A_COERCE:%.*]], i64 0)
76 // CHECK-NEXT:    [[B:%.*]] = call <4 x i64> @llvm.vector.extract.v4i64.nxv1i64(<vscale x 1 x i64> [[B_COERCE:%.*]], i64 0)
77 // CHECK-NEXT:    [[AND:%.*]] = and <4 x i64> [[A]], [[B]]
78 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 1 x i64> @llvm.vector.insert.nxv1i64.v4i64(<vscale x 1 x i64> poison, <4 x i64> [[AND]], i64 0)
79 // CHECK-NEXT:    ret <vscale x 1 x i64> [[CAST_SCALABLE]]
80 //
81 fixed_int64m1_t and_i64(fixed_int64m1_t a, fixed_int64m1_t b) {
82   return a & b;
83 }
84 
85 // CHECK-LABEL: @and_u8(
86 // CHECK-NEXT:  entry:
87 // CHECK-NEXT:    [[A:%.*]] = call <32 x i8> @llvm.vector.extract.v32i8.nxv8i8(<vscale x 8 x i8> [[A_COERCE:%.*]], i64 0)
88 // CHECK-NEXT:    [[B:%.*]] = call <32 x i8> @llvm.vector.extract.v32i8.nxv8i8(<vscale x 8 x i8> [[B_COERCE:%.*]], i64 0)
89 // CHECK-NEXT:    [[AND:%.*]] = and <32 x i8> [[A]], [[B]]
90 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 8 x i8> @llvm.vector.insert.nxv8i8.v32i8(<vscale x 8 x i8> poison, <32 x i8> [[AND]], i64 0)
91 // CHECK-NEXT:    ret <vscale x 8 x i8> [[CAST_SCALABLE]]
92 //
93 fixed_uint8m1_t and_u8(fixed_uint8m1_t a, fixed_uint8m1_t b) {
94   return a & b;
95 }
96 
97 // CHECK-LABEL: @and_u16(
98 // CHECK-NEXT:  entry:
99 // CHECK-NEXT:    [[A:%.*]] = call <16 x i16> @llvm.vector.extract.v16i16.nxv4i16(<vscale x 4 x i16> [[A_COERCE:%.*]], i64 0)
100 // CHECK-NEXT:    [[B:%.*]] = call <16 x i16> @llvm.vector.extract.v16i16.nxv4i16(<vscale x 4 x i16> [[B_COERCE:%.*]], i64 0)
101 // CHECK-NEXT:    [[AND:%.*]] = and <16 x i16> [[A]], [[B]]
102 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 4 x i16> @llvm.vector.insert.nxv4i16.v16i16(<vscale x 4 x i16> poison, <16 x i16> [[AND]], i64 0)
103 // CHECK-NEXT:    ret <vscale x 4 x i16> [[CAST_SCALABLE]]
104 //
105 fixed_uint16m1_t and_u16(fixed_uint16m1_t a, fixed_uint16m1_t b) {
106   return a & b;
107 }
108 
109 // CHECK-LABEL: @and_u32(
110 // CHECK-NEXT:  entry:
111 // CHECK-NEXT:    [[A:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32(<vscale x 2 x i32> [[A_COERCE:%.*]], i64 0)
112 // CHECK-NEXT:    [[B:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32(<vscale x 2 x i32> [[B_COERCE:%.*]], i64 0)
113 // CHECK-NEXT:    [[AND:%.*]] = and <8 x i32> [[A]], [[B]]
114 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> poison, <8 x i32> [[AND]], i64 0)
115 // CHECK-NEXT:    ret <vscale x 2 x i32> [[CAST_SCALABLE]]
116 //
117 fixed_uint32m1_t and_u32(fixed_uint32m1_t a, fixed_uint32m1_t b) {
118   return a & b;
119 }
120 
121 // CHECK-LABEL: @and_u64(
122 // CHECK-NEXT:  entry:
123 // CHECK-NEXT:    [[A:%.*]] = call <4 x i64> @llvm.vector.extract.v4i64.nxv1i64(<vscale x 1 x i64> [[A_COERCE:%.*]], i64 0)
124 // CHECK-NEXT:    [[B:%.*]] = call <4 x i64> @llvm.vector.extract.v4i64.nxv1i64(<vscale x 1 x i64> [[B_COERCE:%.*]], i64 0)
125 // CHECK-NEXT:    [[AND:%.*]] = and <4 x i64> [[A]], [[B]]
126 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 1 x i64> @llvm.vector.insert.nxv1i64.v4i64(<vscale x 1 x i64> poison, <4 x i64> [[AND]], i64 0)
127 // CHECK-NEXT:    ret <vscale x 1 x i64> [[CAST_SCALABLE]]
128 //
129 fixed_uint64m1_t and_u64(fixed_uint64m1_t a, fixed_uint64m1_t b) {
130   return a & b;
131 }
132 
133 // OR
134 
135 // CHECK-LABEL: @or_i8(
136 // CHECK-NEXT:  entry:
137 // CHECK-NEXT:    [[A:%.*]] = call <32 x i8> @llvm.vector.extract.v32i8.nxv8i8(<vscale x 8 x i8> [[A_COERCE:%.*]], i64 0)
138 // CHECK-NEXT:    [[B:%.*]] = call <32 x i8> @llvm.vector.extract.v32i8.nxv8i8(<vscale x 8 x i8> [[B_COERCE:%.*]], i64 0)
139 // CHECK-NEXT:    [[OR:%.*]] = or <32 x i8> [[A]], [[B]]
140 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 8 x i8> @llvm.vector.insert.nxv8i8.v32i8(<vscale x 8 x i8> poison, <32 x i8> [[OR]], i64 0)
141 // CHECK-NEXT:    ret <vscale x 8 x i8> [[CAST_SCALABLE]]
142 //
143 fixed_int8m1_t or_i8(fixed_int8m1_t a, fixed_int8m1_t b) {
144   return a | b;
145 }
146 
147 // CHECK-LABEL: @or_i16(
148 // CHECK-NEXT:  entry:
149 // CHECK-NEXT:    [[A:%.*]] = call <16 x i16> @llvm.vector.extract.v16i16.nxv4i16(<vscale x 4 x i16> [[A_COERCE:%.*]], i64 0)
150 // CHECK-NEXT:    [[B:%.*]] = call <16 x i16> @llvm.vector.extract.v16i16.nxv4i16(<vscale x 4 x i16> [[B_COERCE:%.*]], i64 0)
151 // CHECK-NEXT:    [[OR:%.*]] = or <16 x i16> [[A]], [[B]]
152 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 4 x i16> @llvm.vector.insert.nxv4i16.v16i16(<vscale x 4 x i16> poison, <16 x i16> [[OR]], i64 0)
153 // CHECK-NEXT:    ret <vscale x 4 x i16> [[CAST_SCALABLE]]
154 //
155 fixed_int16m1_t or_i16(fixed_int16m1_t a, fixed_int16m1_t b) {
156   return a | b;
157 }
158 
159 // CHECK-LABEL: @or_i32(
160 // CHECK-NEXT:  entry:
161 // CHECK-NEXT:    [[A:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32(<vscale x 2 x i32> [[A_COERCE:%.*]], i64 0)
162 // CHECK-NEXT:    [[B:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32(<vscale x 2 x i32> [[B_COERCE:%.*]], i64 0)
163 // CHECK-NEXT:    [[OR:%.*]] = or <8 x i32> [[A]], [[B]]
164 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> poison, <8 x i32> [[OR]], i64 0)
165 // CHECK-NEXT:    ret <vscale x 2 x i32> [[CAST_SCALABLE]]
166 //
167 fixed_int32m1_t or_i32(fixed_int32m1_t a, fixed_int32m1_t b) {
168   return a | b;
169 }
170 
171 // CHECK-LABEL: @or_i64(
172 // CHECK-NEXT:  entry:
173 // CHECK-NEXT:    [[A:%.*]] = call <4 x i64> @llvm.vector.extract.v4i64.nxv1i64(<vscale x 1 x i64> [[A_COERCE:%.*]], i64 0)
174 // CHECK-NEXT:    [[B:%.*]] = call <4 x i64> @llvm.vector.extract.v4i64.nxv1i64(<vscale x 1 x i64> [[B_COERCE:%.*]], i64 0)
175 // CHECK-NEXT:    [[OR:%.*]] = or <4 x i64> [[A]], [[B]]
176 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 1 x i64> @llvm.vector.insert.nxv1i64.v4i64(<vscale x 1 x i64> poison, <4 x i64> [[OR]], i64 0)
177 // CHECK-NEXT:    ret <vscale x 1 x i64> [[CAST_SCALABLE]]
178 //
179 fixed_int64m1_t or_i64(fixed_int64m1_t a, fixed_int64m1_t b) {
180   return a | b;
181 }
182 
183 // CHECK-LABEL: @or_u8(
184 // CHECK-NEXT:  entry:
185 // CHECK-NEXT:    [[A:%.*]] = call <32 x i8> @llvm.vector.extract.v32i8.nxv8i8(<vscale x 8 x i8> [[A_COERCE:%.*]], i64 0)
186 // CHECK-NEXT:    [[B:%.*]] = call <32 x i8> @llvm.vector.extract.v32i8.nxv8i8(<vscale x 8 x i8> [[B_COERCE:%.*]], i64 0)
187 // CHECK-NEXT:    [[OR:%.*]] = or <32 x i8> [[A]], [[B]]
188 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 8 x i8> @llvm.vector.insert.nxv8i8.v32i8(<vscale x 8 x i8> poison, <32 x i8> [[OR]], i64 0)
189 // CHECK-NEXT:    ret <vscale x 8 x i8> [[CAST_SCALABLE]]
190 //
191 fixed_uint8m1_t or_u8(fixed_uint8m1_t a, fixed_uint8m1_t b) {
192   return a | b;
193 }
194 
195 // CHECK-LABEL: @or_u16(
196 // CHECK-NEXT:  entry:
197 // CHECK-NEXT:    [[A:%.*]] = call <16 x i16> @llvm.vector.extract.v16i16.nxv4i16(<vscale x 4 x i16> [[A_COERCE:%.*]], i64 0)
198 // CHECK-NEXT:    [[B:%.*]] = call <16 x i16> @llvm.vector.extract.v16i16.nxv4i16(<vscale x 4 x i16> [[B_COERCE:%.*]], i64 0)
199 // CHECK-NEXT:    [[OR:%.*]] = or <16 x i16> [[A]], [[B]]
200 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 4 x i16> @llvm.vector.insert.nxv4i16.v16i16(<vscale x 4 x i16> poison, <16 x i16> [[OR]], i64 0)
201 // CHECK-NEXT:    ret <vscale x 4 x i16> [[CAST_SCALABLE]]
202 //
203 fixed_uint16m1_t or_u16(fixed_uint16m1_t a, fixed_uint16m1_t b) {
204   return a | b;
205 }
206 
207 // CHECK-LABEL: @or_u32(
208 // CHECK-NEXT:  entry:
209 // CHECK-NEXT:    [[A:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32(<vscale x 2 x i32> [[A_COERCE:%.*]], i64 0)
210 // CHECK-NEXT:    [[B:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32(<vscale x 2 x i32> [[B_COERCE:%.*]], i64 0)
211 // CHECK-NEXT:    [[OR:%.*]] = or <8 x i32> [[A]], [[B]]
212 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> poison, <8 x i32> [[OR]], i64 0)
213 // CHECK-NEXT:    ret <vscale x 2 x i32> [[CAST_SCALABLE]]
214 //
215 fixed_uint32m1_t or_u32(fixed_uint32m1_t a, fixed_uint32m1_t b) {
216   return a | b;
217 }
218 
219 // CHECK-LABEL: @or_u64(
220 // CHECK-NEXT:  entry:
221 // CHECK-NEXT:    [[A:%.*]] = call <4 x i64> @llvm.vector.extract.v4i64.nxv1i64(<vscale x 1 x i64> [[A_COERCE:%.*]], i64 0)
222 // CHECK-NEXT:    [[B:%.*]] = call <4 x i64> @llvm.vector.extract.v4i64.nxv1i64(<vscale x 1 x i64> [[B_COERCE:%.*]], i64 0)
223 // CHECK-NEXT:    [[OR:%.*]] = or <4 x i64> [[A]], [[B]]
224 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 1 x i64> @llvm.vector.insert.nxv1i64.v4i64(<vscale x 1 x i64> poison, <4 x i64> [[OR]], i64 0)
225 // CHECK-NEXT:    ret <vscale x 1 x i64> [[CAST_SCALABLE]]
226 //
227 fixed_uint64m1_t or_u64(fixed_uint64m1_t a, fixed_uint64m1_t b) {
228   return a | b;
229 }
230 
231 // XOR
232 
233 // CHECK-LABEL: @xor_i8(
234 // CHECK-NEXT:  entry:
235 // CHECK-NEXT:    [[A:%.*]] = call <32 x i8> @llvm.vector.extract.v32i8.nxv8i8(<vscale x 8 x i8> [[A_COERCE:%.*]], i64 0)
236 // CHECK-NEXT:    [[B:%.*]] = call <32 x i8> @llvm.vector.extract.v32i8.nxv8i8(<vscale x 8 x i8> [[B_COERCE:%.*]], i64 0)
237 // CHECK-NEXT:    [[XOR:%.*]] = xor <32 x i8> [[A]], [[B]]
238 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 8 x i8> @llvm.vector.insert.nxv8i8.v32i8(<vscale x 8 x i8> poison, <32 x i8> [[XOR]], i64 0)
239 // CHECK-NEXT:    ret <vscale x 8 x i8> [[CAST_SCALABLE]]
240 //
241 fixed_int8m1_t xor_i8(fixed_int8m1_t a, fixed_int8m1_t b) {
242   return a ^ b;
243 }
244 
245 // CHECK-LABEL: @xor_i16(
246 // CHECK-NEXT:  entry:
247 // CHECK-NEXT:    [[A:%.*]] = call <16 x i16> @llvm.vector.extract.v16i16.nxv4i16(<vscale x 4 x i16> [[A_COERCE:%.*]], i64 0)
248 // CHECK-NEXT:    [[B:%.*]] = call <16 x i16> @llvm.vector.extract.v16i16.nxv4i16(<vscale x 4 x i16> [[B_COERCE:%.*]], i64 0)
249 // CHECK-NEXT:    [[XOR:%.*]] = xor <16 x i16> [[A]], [[B]]
250 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 4 x i16> @llvm.vector.insert.nxv4i16.v16i16(<vscale x 4 x i16> poison, <16 x i16> [[XOR]], i64 0)
251 // CHECK-NEXT:    ret <vscale x 4 x i16> [[CAST_SCALABLE]]
252 //
253 fixed_int16m1_t xor_i16(fixed_int16m1_t a, fixed_int16m1_t b) {
254   return a ^ b;
255 }
256 
257 // CHECK-LABEL: @xor_i32(
258 // CHECK-NEXT:  entry:
259 // CHECK-NEXT:    [[A:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32(<vscale x 2 x i32> [[A_COERCE:%.*]], i64 0)
260 // CHECK-NEXT:    [[B:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32(<vscale x 2 x i32> [[B_COERCE:%.*]], i64 0)
261 // CHECK-NEXT:    [[XOR:%.*]] = xor <8 x i32> [[A]], [[B]]
262 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> poison, <8 x i32> [[XOR]], i64 0)
263 // CHECK-NEXT:    ret <vscale x 2 x i32> [[CAST_SCALABLE]]
264 //
265 fixed_int32m1_t xor_i32(fixed_int32m1_t a, fixed_int32m1_t b) {
266   return a ^ b;
267 }
268 
269 // CHECK-LABEL: @xor_i64(
270 // CHECK-NEXT:  entry:
271 // CHECK-NEXT:    [[A:%.*]] = call <4 x i64> @llvm.vector.extract.v4i64.nxv1i64(<vscale x 1 x i64> [[A_COERCE:%.*]], i64 0)
272 // CHECK-NEXT:    [[B:%.*]] = call <4 x i64> @llvm.vector.extract.v4i64.nxv1i64(<vscale x 1 x i64> [[B_COERCE:%.*]], i64 0)
273 // CHECK-NEXT:    [[XOR:%.*]] = xor <4 x i64> [[A]], [[B]]
274 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 1 x i64> @llvm.vector.insert.nxv1i64.v4i64(<vscale x 1 x i64> poison, <4 x i64> [[XOR]], i64 0)
275 // CHECK-NEXT:    ret <vscale x 1 x i64> [[CAST_SCALABLE]]
276 //
277 fixed_int64m1_t xor_i64(fixed_int64m1_t a, fixed_int64m1_t b) {
278   return a ^ b;
279 }
280 
281 // CHECK-LABEL: @xor_u8(
282 // CHECK-NEXT:  entry:
283 // CHECK-NEXT:    [[A:%.*]] = call <32 x i8> @llvm.vector.extract.v32i8.nxv8i8(<vscale x 8 x i8> [[A_COERCE:%.*]], i64 0)
284 // CHECK-NEXT:    [[B:%.*]] = call <32 x i8> @llvm.vector.extract.v32i8.nxv8i8(<vscale x 8 x i8> [[B_COERCE:%.*]], i64 0)
285 // CHECK-NEXT:    [[XOR:%.*]] = xor <32 x i8> [[A]], [[B]]
286 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 8 x i8> @llvm.vector.insert.nxv8i8.v32i8(<vscale x 8 x i8> poison, <32 x i8> [[XOR]], i64 0)
287 // CHECK-NEXT:    ret <vscale x 8 x i8> [[CAST_SCALABLE]]
288 //
289 fixed_uint8m1_t xor_u8(fixed_uint8m1_t a, fixed_uint8m1_t b) {
290   return a ^ b;
291 }
292 
293 // CHECK-LABEL: @xor_u16(
294 // CHECK-NEXT:  entry:
295 // CHECK-NEXT:    [[A:%.*]] = call <16 x i16> @llvm.vector.extract.v16i16.nxv4i16(<vscale x 4 x i16> [[A_COERCE:%.*]], i64 0)
296 // CHECK-NEXT:    [[B:%.*]] = call <16 x i16> @llvm.vector.extract.v16i16.nxv4i16(<vscale x 4 x i16> [[B_COERCE:%.*]], i64 0)
297 // CHECK-NEXT:    [[XOR:%.*]] = xor <16 x i16> [[A]], [[B]]
298 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 4 x i16> @llvm.vector.insert.nxv4i16.v16i16(<vscale x 4 x i16> poison, <16 x i16> [[XOR]], i64 0)
299 // CHECK-NEXT:    ret <vscale x 4 x i16> [[CAST_SCALABLE]]
300 //
301 fixed_uint16m1_t xor_u16(fixed_uint16m1_t a, fixed_uint16m1_t b) {
302   return a ^ b;
303 }
304 
305 // CHECK-LABEL: @xor_u32(
306 // CHECK-NEXT:  entry:
307 // CHECK-NEXT:    [[A:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32(<vscale x 2 x i32> [[A_COERCE:%.*]], i64 0)
308 // CHECK-NEXT:    [[B:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32(<vscale x 2 x i32> [[B_COERCE:%.*]], i64 0)
309 // CHECK-NEXT:    [[XOR:%.*]] = xor <8 x i32> [[A]], [[B]]
310 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> poison, <8 x i32> [[XOR]], i64 0)
311 // CHECK-NEXT:    ret <vscale x 2 x i32> [[CAST_SCALABLE]]
312 //
313 fixed_uint32m1_t xor_u32(fixed_uint32m1_t a, fixed_uint32m1_t b) {
314   return a ^ b;
315 }
316 
317 // CHECK-LABEL: @xor_u64(
318 // CHECK-NEXT:  entry:
319 // CHECK-NEXT:    [[A:%.*]] = call <4 x i64> @llvm.vector.extract.v4i64.nxv1i64(<vscale x 1 x i64> [[A_COERCE:%.*]], i64 0)
320 // CHECK-NEXT:    [[B:%.*]] = call <4 x i64> @llvm.vector.extract.v4i64.nxv1i64(<vscale x 1 x i64> [[B_COERCE:%.*]], i64 0)
321 // CHECK-NEXT:    [[XOR:%.*]] = xor <4 x i64> [[A]], [[B]]
322 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 1 x i64> @llvm.vector.insert.nxv1i64.v4i64(<vscale x 1 x i64> poison, <4 x i64> [[XOR]], i64 0)
323 // CHECK-NEXT:    ret <vscale x 1 x i64> [[CAST_SCALABLE]]
324 //
325 fixed_uint64m1_t xor_u64(fixed_uint64m1_t a, fixed_uint64m1_t b) {
326   return a ^ b;
327 }
328 
329 // NEG
330 
331 // CHECK-LABEL: @not_i8(
332 // CHECK-NEXT:  entry:
333 // CHECK-NEXT:    [[A:%.*]] = call <32 x i8> @llvm.vector.extract.v32i8.nxv8i8(<vscale x 8 x i8> [[A_COERCE:%.*]], i64 0)
334 // CHECK-NEXT:    [[NOT:%.*]] = xor <32 x i8> [[A]], splat (i8 -1)
335 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 8 x i8> @llvm.vector.insert.nxv8i8.v32i8(<vscale x 8 x i8> poison, <32 x i8> [[NOT]], i64 0)
336 // CHECK-NEXT:    ret <vscale x 8 x i8> [[CAST_SCALABLE]]
337 //
338 fixed_int8m1_t not_i8(fixed_int8m1_t a) {
339   return ~a;
340 }
341 
342 // CHECK-LABEL: @not_i16(
343 // CHECK-NEXT:  entry:
344 // CHECK-NEXT:    [[A:%.*]] = call <16 x i16> @llvm.vector.extract.v16i16.nxv4i16(<vscale x 4 x i16> [[A_COERCE:%.*]], i64 0)
345 // CHECK-NEXT:    [[NOT:%.*]] = xor <16 x i16> [[A]], splat (i16 -1)
346 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 4 x i16> @llvm.vector.insert.nxv4i16.v16i16(<vscale x 4 x i16> poison, <16 x i16> [[NOT]], i64 0)
347 // CHECK-NEXT:    ret <vscale x 4 x i16> [[CAST_SCALABLE]]
348 //
349 fixed_int16m1_t not_i16(fixed_int16m1_t a) {
350   return ~a;
351 }
352 
353 // CHECK-LABEL: @not_i32(
354 // CHECK-NEXT:  entry:
355 // CHECK-NEXT:    [[A:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32(<vscale x 2 x i32> [[A_COERCE:%.*]], i64 0)
356 // CHECK-NEXT:    [[NOT:%.*]] = xor <8 x i32> [[A]], splat (i32 -1)
357 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> poison, <8 x i32> [[NOT]], i64 0)
358 // CHECK-NEXT:    ret <vscale x 2 x i32> [[CAST_SCALABLE]]
359 //
360 fixed_int32m1_t not_i32(fixed_int32m1_t a) {
361   return ~a;
362 }
363 
364 // CHECK-LABEL: @not_i64(
365 // CHECK-NEXT:  entry:
366 // CHECK-NEXT:    [[A:%.*]] = call <4 x i64> @llvm.vector.extract.v4i64.nxv1i64(<vscale x 1 x i64> [[A_COERCE:%.*]], i64 0)
367 // CHECK-NEXT:    [[NOT:%.*]] = xor <4 x i64> [[A]], splat (i64 -1)
368 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 1 x i64> @llvm.vector.insert.nxv1i64.v4i64(<vscale x 1 x i64> poison, <4 x i64> [[NOT]], i64 0)
369 // CHECK-NEXT:    ret <vscale x 1 x i64> [[CAST_SCALABLE]]
370 //
371 fixed_int64m1_t not_i64(fixed_int64m1_t a) {
372   return ~a;
373 }
374 
375 // CHECK-LABEL: @not_u8(
376 // CHECK-NEXT:  entry:
377 // CHECK-NEXT:    [[A:%.*]] = call <32 x i8> @llvm.vector.extract.v32i8.nxv8i8(<vscale x 8 x i8> [[A_COERCE:%.*]], i64 0)
378 // CHECK-NEXT:    [[NOT:%.*]] = xor <32 x i8> [[A]], splat (i8 -1)
379 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 8 x i8> @llvm.vector.insert.nxv8i8.v32i8(<vscale x 8 x i8> poison, <32 x i8> [[NOT]], i64 0)
380 // CHECK-NEXT:    ret <vscale x 8 x i8> [[CAST_SCALABLE]]
381 //
382 fixed_uint8m1_t not_u8(fixed_uint8m1_t a) {
383   return ~a;
384 }
385 
386 // CHECK-LABEL: @not_u16(
387 // CHECK-NEXT:  entry:
388 // CHECK-NEXT:    [[A:%.*]] = call <16 x i16> @llvm.vector.extract.v16i16.nxv4i16(<vscale x 4 x i16> [[A_COERCE:%.*]], i64 0)
389 // CHECK-NEXT:    [[NOT:%.*]] = xor <16 x i16> [[A]], splat (i16 -1)
390 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 4 x i16> @llvm.vector.insert.nxv4i16.v16i16(<vscale x 4 x i16> poison, <16 x i16> [[NOT]], i64 0)
391 // CHECK-NEXT:    ret <vscale x 4 x i16> [[CAST_SCALABLE]]
392 //
393 fixed_uint16m1_t not_u16(fixed_uint16m1_t a) {
394   return ~a;
395 }
396 
397 // CHECK-LABEL: @not_u32(
398 // CHECK-NEXT:  entry:
399 // CHECK-NEXT:    [[A:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32(<vscale x 2 x i32> [[A_COERCE:%.*]], i64 0)
400 // CHECK-NEXT:    [[NOT:%.*]] = xor <8 x i32> [[A]], splat (i32 -1)
401 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> poison, <8 x i32> [[NOT]], i64 0)
402 // CHECK-NEXT:    ret <vscale x 2 x i32> [[CAST_SCALABLE]]
403 //
404 fixed_uint32m1_t not_u32(fixed_uint32m1_t a) {
405   return ~a;
406 }
407 
408 // CHECK-LABEL: @not_u64(
409 // CHECK-NEXT:  entry:
410 // CHECK-NEXT:    [[A:%.*]] = call <4 x i64> @llvm.vector.extract.v4i64.nxv1i64(<vscale x 1 x i64> [[A_COERCE:%.*]], i64 0)
411 // CHECK-NEXT:    [[NOT:%.*]] = xor <4 x i64> [[A]], splat (i64 -1)
412 // CHECK-NEXT:    [[CAST_SCALABLE:%.*]] = call <vscale x 1 x i64> @llvm.vector.insert.nxv1i64.v4i64(<vscale x 1 x i64> poison, <4 x i64> [[NOT]], i64 0)
413 // CHECK-NEXT:    ret <vscale x 1 x i64> [[CAST_SCALABLE]]
414 //
415 fixed_uint64m1_t not_u64(fixed_uint64m1_t a) {
416   return ~a;
417 }
418