Skip to content

Commit 71150f2

Browse files
authored
[AArch64] Use SVE2 bit-sel instructions for some binary patterns. (#147544)
We can use NBSL/BSL2N to implement the following operations via the corresponding identities: * EON(a, b) = BSL2N(a, a, b) = BSL2N(b, b, a) * NAND(a, b) = NBSL(a, b, b) = NBSL(b, a, a) * NOR(a, b) = NBSL(a, b, a) = NBSL(b, a, b) * ORN(a, b) = BSL2N(a, b, a) Most of these operations are currently lowered into at least two instructions because we don't have dedicated Neon/SVE instructions for them. With the appropriate pattern of NBSL/BSL2N we can lower them in a single instruction. We could also use NBSL to implement an unpredicated NOT(a) = NBSL(a, a, a), but because of the tied register constraint, this may not always be profitable.
1 parent a446300 commit 71150f2

File tree

5 files changed

+234
-12
lines changed

5 files changed

+234
-12
lines changed

llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4034,6 +4034,36 @@ let Predicates = [HasSVE2_or_SME] in {
40344034
defm BSL2N_ZZZZ : sve2_int_bitwise_ternary_op<0b101, "bsl2n", AArch64bsl2n>;
40354035
defm NBSL_ZZZZ : sve2_int_bitwise_ternary_op<0b111, "nbsl", AArch64nbsl>;
40364036

4037+
multiclass binary_bitwise<ValueType VT, SDPatternOperator InOp, SDPatternOperator OutOp> {
4038+
def : Pat<(InOp VT:$op1, VT:$op2), (OutOp $op1, $op2)>;
4039+
4040+
def : Pat<(SVEType<VT>.DSub (InOp V64:$op1, V64:$op2)),
4041+
(EXTRACT_SUBREG (OutOp (INSERT_SUBREG (IMPLICIT_DEF), (SVEType<VT>.DSub $op1), dsub),
4042+
(INSERT_SUBREG (IMPLICIT_DEF), (SVEType<VT>.DSub $op2), dsub)), dsub)>;
4043+
4044+
def : Pat<(SVEType<VT>.ZSub (InOp V128:$op1, V128:$op2)),
4045+
(EXTRACT_SUBREG (OutOp (INSERT_SUBREG (IMPLICIT_DEF), (SVEType<VT>.ZSub $op1), zsub),
4046+
(INSERT_SUBREG (IMPLICIT_DEF), (SVEType<VT>.ZSub $op2), zsub)), zsub)>;
4047+
}
4048+
4049+
foreach VT = [nxv16i8, nxv8i16, nxv4i32, nxv2i64] in {
4050+
// EON (a, b) = BSL2N (a, a, b) = BSL2N (b, b, a)
4051+
defm : binary_bitwise<VT, PatFrag<(ops node:$op1, node:$op2), (vnot (xor node:$op1, node:$op2))>,
4052+
OutPatFrag<(ops node:$op1, node:$op2), (BSL2N_ZZZZ $op1, $op1, $op2)>>;
4053+
4054+
// NAND (a, b) = NBSL (a, b, b) = NBSL (b, a, a)
4055+
defm : binary_bitwise<VT, PatFrag<(ops node:$op1, node:$op2), (vnot (and node:$op1, node:$op2))>,
4056+
OutPatFrag<(ops node:$op1, node:$op2), (NBSL_ZZZZ $op2, $op1, $op1)>>;
4057+
4058+
// NOR (a, b) = NBSL (a, b, a) = NBSL (b, a, b)
4059+
defm : binary_bitwise<VT, PatFrag<(ops node:$op1, node:$op2), (vnot (or node:$op1, node:$op2))>,
4060+
OutPatFrag<(ops node:$op1, node:$op2), (NBSL_ZZZZ $op2, $op1, $op2)>>;
4061+
4062+
// ORN (a, b) = BSL2N (a, b, a)
4063+
defm : binary_bitwise<VT, PatFrag<(ops node:$op1, node:$op2), (or node:$op1, (vnot node:$op2))>,
4064+
OutPatFrag<(ops node:$op1, node:$op2), (BSL2N_ZZZZ $op1, $op2, $op1)>>;
4065+
}
4066+
40374067
// SVE2 bitwise xor and rotate right by immediate
40384068
defm XAR_ZZZI : sve2_int_rotate_right_imm<"xar", int_aarch64_sve_xar>;
40394069

llvm/test/CodeGen/AArch64/bsl.ll

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,3 +431,94 @@ define <4 x i8> @bsl2n_v4i8(<4 x i8> %0, <4 x i8> %1, <4 x i8> %2) {
431431
%7 = or <4 x i8> %4, %6
432432
ret <4 x i8> %7
433433
}
434+
435+
; NOT (a) has a dedicated instruction (MVN).
436+
define <2 x i64> @not_q(<2 x i64> %0) #0 {
437+
; NEON-LABEL: not_q:
438+
; NEON: // %bb.0:
439+
; NEON-NEXT: mvn v0.16b, v0.16b
440+
; NEON-NEXT: ret
441+
;
442+
; SVE2-LABEL: not_q:
443+
; SVE2: // %bb.0:
444+
; SVE2-NEXT: mvn v0.16b, v0.16b
445+
; SVE2-NEXT: ret
446+
%2 = xor <2 x i64> %0, splat (i64 -1)
447+
ret <2 x i64> %2
448+
}
449+
450+
; NAND (a, b) = NBSL (a, b, b) = NBSL (b, a, a).
451+
define <2 x i64> @nand_q(<2 x i64> %0, <2 x i64> %1) #0 {
452+
; NEON-LABEL: nand_q:
453+
; NEON: // %bb.0:
454+
; NEON-NEXT: and v0.16b, v1.16b, v0.16b
455+
; NEON-NEXT: mvn v0.16b, v0.16b
456+
; NEON-NEXT: ret
457+
;
458+
; SVE2-LABEL: nand_q:
459+
; SVE2: // %bb.0:
460+
; SVE2-NEXT: // kill: def $q0 killed $q0 def $z0
461+
; SVE2-NEXT: // kill: def $q1 killed $q1 def $z1
462+
; SVE2-NEXT: nbsl z0.d, z0.d, z1.d, z1.d
463+
; SVE2-NEXT: // kill: def $q0 killed $q0 killed $z0
464+
; SVE2-NEXT: ret
465+
%3 = and <2 x i64> %1, %0
466+
%4 = xor <2 x i64> %3, splat (i64 -1)
467+
ret <2 x i64> %4
468+
}
469+
470+
; NOR (a, b) = NBSL (a, b, a) = NBSL (b, a, b).
471+
define <2 x i64> @nor_q(<2 x i64> %0, <2 x i64> %1) #0 {
472+
; NEON-LABEL: nor_q:
473+
; NEON: // %bb.0:
474+
; NEON-NEXT: orr v0.16b, v1.16b, v0.16b
475+
; NEON-NEXT: mvn v0.16b, v0.16b
476+
; NEON-NEXT: ret
477+
;
478+
; SVE2-LABEL: nor_q:
479+
; SVE2: // %bb.0:
480+
; SVE2-NEXT: // kill: def $q0 killed $q0 def $z0
481+
; SVE2-NEXT: // kill: def $q1 killed $q1 def $z1
482+
; SVE2-NEXT: nbsl z0.d, z0.d, z1.d, z0.d
483+
; SVE2-NEXT: // kill: def $q0 killed $q0 killed $z0
484+
; SVE2-NEXT: ret
485+
%3 = or <2 x i64> %1, %0
486+
%4 = xor <2 x i64> %3, splat (i64 -1)
487+
ret <2 x i64> %4
488+
}
489+
490+
; EON (a, b) = BSL2N (a, a, b) = BSL2N (b, b, a).
491+
define <2 x i64> @eon_q(<2 x i64> %0, <2 x i64> %1) #0 {
492+
; NEON-LABEL: eon_q:
493+
; NEON: // %bb.0:
494+
; NEON-NEXT: eor v0.16b, v0.16b, v1.16b
495+
; NEON-NEXT: mvn v0.16b, v0.16b
496+
; NEON-NEXT: ret
497+
;
498+
; SVE2-LABEL: eon_q:
499+
; SVE2: // %bb.0:
500+
; SVE2-NEXT: // kill: def $q0 killed $q0 def $z0
501+
; SVE2-NEXT: // kill: def $q1 killed $q1 def $z1
502+
; SVE2-NEXT: bsl2n z0.d, z0.d, z0.d, z1.d
503+
; SVE2-NEXT: // kill: def $q0 killed $q0 killed $z0
504+
; SVE2-NEXT: ret
505+
%3 = xor <2 x i64> %0, %1
506+
%4 = xor <2 x i64> %3, splat (i64 -1)
507+
ret <2 x i64> %4
508+
}
509+
510+
; ORN (a, b) has a dedicated instruction (ORN).
511+
define <2 x i64> @orn_q(<2 x i64> %0, <2 x i64> %1) #0 {
512+
; NEON-LABEL: orn_q:
513+
; NEON: // %bb.0:
514+
; NEON-NEXT: orn v0.16b, v0.16b, v1.16b
515+
; NEON-NEXT: ret
516+
;
517+
; SVE2-LABEL: orn_q:
518+
; SVE2: // %bb.0:
519+
; SVE2-NEXT: orn v0.16b, v0.16b, v1.16b
520+
; SVE2-NEXT: ret
521+
%3 = xor <2 x i64> %1, splat (i64 -1)
522+
%4 = or <2 x i64> %0, %3
523+
ret <2 x i64> %4
524+
}

llvm/test/CodeGen/AArch64/eor3.ll

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
; RUN: llc -mtriple=aarch64 -mattr=+sha3 < %s | FileCheck --check-prefix=SHA3 %s
33
; RUN: llc -mtriple=aarch64 -mattr=-sha3 < %s | FileCheck --check-prefix=NOSHA3 %s
44
; RUN: llc -mtriple=aarch64 -mattr=+sve2 < %s | FileCheck --check-prefix=SVE2 %s
5-
; RUN: llc -mtriple=aarch64 -mattr=+sha3,+sve2 < %s | FileCheck --check-prefix=SHA3 %s
5+
; RUN: llc -mtriple=aarch64 -mattr=+sha3,+sve2 < %s | FileCheck --check-prefix=SHA3-SVE2 %s
66

77
define <16 x i8> @eor3_16x8_left(<16 x i8> %0, <16 x i8> %1, <16 x i8> %2) {
88
; SHA3-LABEL: eor3_16x8_left:
@@ -24,6 +24,11 @@ define <16 x i8> @eor3_16x8_left(<16 x i8> %0, <16 x i8> %1, <16 x i8> %2) {
2424
; SVE2-NEXT: eor3 z2.d, z2.d, z0.d, z1.d
2525
; SVE2-NEXT: mov v0.16b, v2.16b
2626
; SVE2-NEXT: ret
27+
;
28+
; SHA3-SVE2-LABEL: eor3_16x8_left:
29+
; SHA3-SVE2: // %bb.0:
30+
; SHA3-SVE2-NEXT: eor3 v0.16b, v0.16b, v1.16b, v2.16b
31+
; SHA3-SVE2-NEXT: ret
2732
%4 = xor <16 x i8> %0, %1
2833
%5 = xor <16 x i8> %2, %4
2934
ret <16 x i8> %5
@@ -49,6 +54,11 @@ define <16 x i8> @eor3_16x8_right(<16 x i8> %0, <16 x i8> %1, <16 x i8> %2) {
4954
; SVE2-NEXT: eor3 z1.d, z1.d, z2.d, z0.d
5055
; SVE2-NEXT: mov v0.16b, v1.16b
5156
; SVE2-NEXT: ret
57+
;
58+
; SHA3-SVE2-LABEL: eor3_16x8_right:
59+
; SHA3-SVE2: // %bb.0:
60+
; SHA3-SVE2-NEXT: eor3 v0.16b, v1.16b, v2.16b, v0.16b
61+
; SHA3-SVE2-NEXT: ret
5262
%4 = xor <16 x i8> %1, %2
5363
%5 = xor <16 x i8> %4, %0
5464
ret <16 x i8> %5
@@ -74,6 +84,11 @@ define <8 x i16> @eor3_8x16_left(<8 x i16> %0, <8 x i16> %1, <8 x i16> %2) {
7484
; SVE2-NEXT: eor3 z2.d, z2.d, z0.d, z1.d
7585
; SVE2-NEXT: mov v0.16b, v2.16b
7686
; SVE2-NEXT: ret
87+
;
88+
; SHA3-SVE2-LABEL: eor3_8x16_left:
89+
; SHA3-SVE2: // %bb.0:
90+
; SHA3-SVE2-NEXT: eor3 v0.16b, v0.16b, v1.16b, v2.16b
91+
; SHA3-SVE2-NEXT: ret
7792
%4 = xor <8 x i16> %0, %1
7893
%5 = xor <8 x i16> %2, %4
7994
ret <8 x i16> %5
@@ -99,6 +114,11 @@ define <8 x i16> @eor3_8x16_right(<8 x i16> %0, <8 x i16> %1, <8 x i16> %2) {
99114
; SVE2-NEXT: eor3 z1.d, z1.d, z2.d, z0.d
100115
; SVE2-NEXT: mov v0.16b, v1.16b
101116
; SVE2-NEXT: ret
117+
;
118+
; SHA3-SVE2-LABEL: eor3_8x16_right:
119+
; SHA3-SVE2: // %bb.0:
120+
; SHA3-SVE2-NEXT: eor3 v0.16b, v1.16b, v2.16b, v0.16b
121+
; SHA3-SVE2-NEXT: ret
102122
%4 = xor <8 x i16> %1, %2
103123
%5 = xor <8 x i16> %4, %0
104124
ret <8 x i16> %5
@@ -124,6 +144,11 @@ define <4 x i32> @eor3_4x32_left(<4 x i32> %0, <4 x i32> %1, <4 x i32> %2) {
124144
; SVE2-NEXT: eor3 z2.d, z2.d, z0.d, z1.d
125145
; SVE2-NEXT: mov v0.16b, v2.16b
126146
; SVE2-NEXT: ret
147+
;
148+
; SHA3-SVE2-LABEL: eor3_4x32_left:
149+
; SHA3-SVE2: // %bb.0:
150+
; SHA3-SVE2-NEXT: eor3 v0.16b, v0.16b, v1.16b, v2.16b
151+
; SHA3-SVE2-NEXT: ret
127152
%4 = xor <4 x i32> %0, %1
128153
%5 = xor <4 x i32> %2, %4
129154
ret <4 x i32> %5
@@ -149,6 +174,11 @@ define <4 x i32> @eor3_4x32_right(<4 x i32> %0, <4 x i32> %1, <4 x i32> %2) {
149174
; SVE2-NEXT: eor3 z1.d, z1.d, z2.d, z0.d
150175
; SVE2-NEXT: mov v0.16b, v1.16b
151176
; SVE2-NEXT: ret
177+
;
178+
; SHA3-SVE2-LABEL: eor3_4x32_right:
179+
; SHA3-SVE2: // %bb.0:
180+
; SHA3-SVE2-NEXT: eor3 v0.16b, v1.16b, v2.16b, v0.16b
181+
; SHA3-SVE2-NEXT: ret
152182
%4 = xor <4 x i32> %1, %2
153183
%5 = xor <4 x i32> %4, %0
154184
ret <4 x i32> %5
@@ -174,6 +204,11 @@ define <2 x i64> @eor3_2x64_left(<2 x i64> %0, <2 x i64> %1, <2 x i64> %2) {
174204
; SVE2-NEXT: eor3 z2.d, z2.d, z0.d, z1.d
175205
; SVE2-NEXT: mov v0.16b, v2.16b
176206
; SVE2-NEXT: ret
207+
;
208+
; SHA3-SVE2-LABEL: eor3_2x64_left:
209+
; SHA3-SVE2: // %bb.0:
210+
; SHA3-SVE2-NEXT: eor3 v0.16b, v0.16b, v1.16b, v2.16b
211+
; SHA3-SVE2-NEXT: ret
177212
%4 = xor <2 x i64> %0, %1
178213
%5 = xor <2 x i64> %2, %4
179214
ret <2 x i64> %5
@@ -199,6 +234,11 @@ define <2 x i64> @eor3_2x64_right(<2 x i64> %0, <2 x i64> %1, <2 x i64> %2) {
199234
; SVE2-NEXT: eor3 z1.d, z1.d, z2.d, z0.d
200235
; SVE2-NEXT: mov v0.16b, v1.16b
201236
; SVE2-NEXT: ret
237+
;
238+
; SHA3-SVE2-LABEL: eor3_2x64_right:
239+
; SHA3-SVE2: // %bb.0:
240+
; SHA3-SVE2-NEXT: eor3 v0.16b, v1.16b, v2.16b, v0.16b
241+
; SHA3-SVE2-NEXT: ret
202242
%4 = xor <2 x i64> %1, %2
203243
%5 = xor <2 x i64> %4, %0
204244
ret <2 x i64> %5
@@ -219,9 +259,19 @@ define <2 x i64> @eor3_vnot(<2 x i64> %0, <2 x i64> %1) {
219259
;
220260
; SVE2-LABEL: eor3_vnot:
221261
; SVE2: // %bb.0:
222-
; SVE2-NEXT: eor v0.16b, v0.16b, v1.16b
223-
; SVE2-NEXT: mvn v0.16b, v0.16b
262+
; SVE2-NEXT: // kill: def $q0 killed $q0 def $z0
263+
; SVE2-NEXT: // kill: def $q1 killed $q1 def $z1
264+
; SVE2-NEXT: bsl2n z0.d, z0.d, z0.d, z1.d
265+
; SVE2-NEXT: // kill: def $q0 killed $q0 killed $z0
224266
; SVE2-NEXT: ret
267+
;
268+
; SHA3-SVE2-LABEL: eor3_vnot:
269+
; SHA3-SVE2: // %bb.0:
270+
; SHA3-SVE2-NEXT: // kill: def $q0 killed $q0 def $z0
271+
; SHA3-SVE2-NEXT: // kill: def $q1 killed $q1 def $z1
272+
; SHA3-SVE2-NEXT: bsl2n z0.d, z0.d, z0.d, z1.d
273+
; SHA3-SVE2-NEXT: // kill: def $q0 killed $q0 killed $z0
274+
; SHA3-SVE2-NEXT: ret
225275
%3 = xor <2 x i64> %0, <i64 -1, i64 -1>
226276
%4 = xor <2 x i64> %3, %1
227277
ret <2 x i64> %4

llvm/test/CodeGen/AArch64/sve-pred-selectop.ll

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -322,11 +322,9 @@ entry:
322322
define <vscale x 4 x i32> @ornot_v4i32(<vscale x 4 x i32> %z, <vscale x 4 x i32> %x, <vscale x 4 x i32> %y) {
323323
; CHECK-LABEL: ornot_v4i32:
324324
; CHECK: // %bb.0: // %entry
325-
; CHECK-NEXT: mov z3.s, #-1 // =0xffffffffffffffff
326325
; CHECK-NEXT: ptrue p0.s
326+
; CHECK-NEXT: bsl2n z1.d, z1.d, z2.d, z1.d
327327
; CHECK-NEXT: cmpeq p0.s, p0/z, z0.s, #0
328-
; CHECK-NEXT: eor z2.d, z2.d, z3.d
329-
; CHECK-NEXT: orr z1.d, z1.d, z2.d
330328
; CHECK-NEXT: mov z0.s, p0/m, z1.s
331329
; CHECK-NEXT: ret
332330
entry:
@@ -340,11 +338,9 @@ entry:
340338
define <vscale x 8 x i16> @ornot_v8i16(<vscale x 8 x i16> %z, <vscale x 8 x i16> %x, <vscale x 8 x i16> %y) {
341339
; CHECK-LABEL: ornot_v8i16:
342340
; CHECK: // %bb.0: // %entry
343-
; CHECK-NEXT: mov z3.h, #-1 // =0xffffffffffffffff
344341
; CHECK-NEXT: ptrue p0.h
342+
; CHECK-NEXT: bsl2n z1.d, z1.d, z2.d, z1.d
345343
; CHECK-NEXT: cmpeq p0.h, p0/z, z0.h, #0
346-
; CHECK-NEXT: eor z2.d, z2.d, z3.d
347-
; CHECK-NEXT: orr z1.d, z1.d, z2.d
348344
; CHECK-NEXT: mov z0.h, p0/m, z1.h
349345
; CHECK-NEXT: ret
350346
entry:
@@ -358,11 +354,9 @@ entry:
358354
define <vscale x 16 x i8> @ornot_v16i8(<vscale x 16 x i8> %z, <vscale x 16 x i8> %x, <vscale x 16 x i8> %y) {
359355
; CHECK-LABEL: ornot_v16i8:
360356
; CHECK: // %bb.0: // %entry
361-
; CHECK-NEXT: mov z3.b, #-1 // =0xffffffffffffffff
362357
; CHECK-NEXT: ptrue p0.b
358+
; CHECK-NEXT: bsl2n z1.d, z1.d, z2.d, z1.d
363359
; CHECK-NEXT: cmpeq p0.b, p0/z, z0.b, #0
364-
; CHECK-NEXT: eor z2.d, z2.d, z3.d
365-
; CHECK-NEXT: orr z1.d, z1.d, z2.d
366360
; CHECK-NEXT: mov z0.b, p0/m, z1.b
367361
; CHECK-NEXT: ret
368362
entry:

llvm/test/CodeGen/AArch64/sve2-bsl.ll

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,3 +312,60 @@ entry:
312312
%t3 = xor <vscale x 4 x i32> %t2, %b
313313
ret <vscale x 4 x i32> %t3
314314
}
315+
316+
; NOT (a) = NBSL (a, a, a).
317+
; We don't have a pattern for this right now because the tied register
318+
; constraint can lead to worse code gen.
319+
define <vscale x 2 x i64> @not(<vscale x 2 x i64> %0) #0 {
320+
; CHECK-LABEL: not:
321+
; CHECK: // %bb.0:
322+
; CHECK-NEXT: mov z1.d, #-1 // =0xffffffffffffffff
323+
; CHECK-NEXT: eor z0.d, z0.d, z1.d
324+
; CHECK-NEXT: ret
325+
%2 = xor <vscale x 2 x i64> %0, splat (i64 -1)
326+
ret <vscale x 2 x i64> %2
327+
}
328+
329+
; NAND (a, b) = NBSL (a, b, b) = NBSL (b, a, a).
330+
define <vscale x 2 x i64> @nand(<vscale x 2 x i64> %0, <vscale x 2 x i64> %1) #0 {
331+
; CHECK-LABEL: nand:
332+
; CHECK: // %bb.0:
333+
; CHECK-NEXT: nbsl z0.d, z0.d, z1.d, z1.d
334+
; CHECK-NEXT: ret
335+
%3 = and <vscale x 2 x i64> %1, %0
336+
%4 = xor <vscale x 2 x i64> %3, splat (i64 -1)
337+
ret <vscale x 2 x i64> %4
338+
}
339+
340+
; NOR (a, b) = NBSL (a, b, a) = NBSL (b, a, b).
341+
define <vscale x 2 x i64> @nor(<vscale x 2 x i64> %0, <vscale x 2 x i64> %1) #0 {
342+
; CHECK-LABEL: nor:
343+
; CHECK: // %bb.0:
344+
; CHECK-NEXT: nbsl z0.d, z0.d, z1.d, z0.d
345+
; CHECK-NEXT: ret
346+
%3 = or <vscale x 2 x i64> %1, %0
347+
%4 = xor <vscale x 2 x i64> %3, splat (i64 -1)
348+
ret <vscale x 2 x i64> %4
349+
}
350+
351+
; EON (a, b) = BSL2N (a, a, b) = BSL2N (b, b, a).
352+
define <vscale x 2 x i64> @eon(<vscale x 2 x i64> %0, <vscale x 2 x i64> %1) #0 {
353+
; CHECK-LABEL: eon:
354+
; CHECK: // %bb.0:
355+
; CHECK-NEXT: bsl2n z0.d, z0.d, z0.d, z1.d
356+
; CHECK-NEXT: ret
357+
%3 = xor <vscale x 2 x i64> %0, %1
358+
%4 = xor <vscale x 2 x i64> %3, splat (i64 -1)
359+
ret <vscale x 2 x i64> %4
360+
}
361+
362+
; ORN (a, b) = BSL2N (a, b, a).
363+
define <vscale x 2 x i64> @orn(<vscale x 2 x i64> %0, <vscale x 2 x i64> %1) #0 {
364+
; CHECK-LABEL: orn:
365+
; CHECK: // %bb.0:
366+
; CHECK-NEXT: bsl2n z0.d, z0.d, z1.d, z0.d
367+
; CHECK-NEXT: ret
368+
%3 = xor <vscale x 2 x i64> %1, splat (i64 -1)
369+
%4 = or <vscale x 2 x i64> %0, %3
370+
ret <vscale x 2 x i64> %4
371+
}

0 commit comments

Comments
 (0)