[llvm] [AArch64][ISel] Add custom lowering for clmul nxv8i16 (PR #195893)
Matthew Devereau via llvm-commits
llvm-commits at lists.llvm.org
Mon May 11 08:04:13 PDT 2026
https://github.com/MDevereau updated https://github.com/llvm/llvm-project/pull/195893
>From 72620a635e56f05da2f69f4557725dd00b23108b Mon Sep 17 00:00:00 2001
From: Matthew Devereau <matthew.devereau at arm.com>
Date: Tue, 5 May 2026 16:24:01 +0000
Subject: [PATCH 1/3] [AArch64][ISel] Add custom lowering for clmul nxv8i16
When sve2 is available, this operation provides a faster implementation than
the current lowering:
clmul.i16(a, b) = xor(pmullb(a_lo, b_lo),
lsl(xor(pmul(a_hi, b_lo),
pmul(a_lo, b_hi)),
8))
Assisted-by: Codex with gpt-5.5
---
.../Target/AArch64/AArch64ISelLowering.cpp | 47 +-
llvm/test/CodeGen/AArch64/clmul-scalable.ll | 412 +++---------------
2 files changed, 116 insertions(+), 343 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index e3c12b9ebd3ed..27fe5776a14fb 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -2051,6 +2051,7 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
setPartialReduceMLAAction(MLAOps, MVT::nxv8i16, MVT::nxv16i8, Legal);
setOperationAction(ISD::CLMUL, {MVT::nxv16i8, MVT::nxv4i32}, Legal);
+ setOperationAction(ISD::CLMUL, {MVT::nxv8i16}, Custom);
setPartialReduceMLAAction(ISD::PARTIAL_REDUCE_FMLA, MVT::nxv4f32,
MVT::nxv8f16, Legal);
@@ -8089,10 +8090,50 @@ SDValue AArch64TargetLowering::LowerFMA(SDValue Op, SelectionDAG &DAG) const {
static SDValue LowerCLMUL(SDValue Op, SelectionDAG &DAG) {
EVT VT = Op.getValueType();
- assert(
- (VT == MVT::i64 || VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8) &&
- "Unexpected Type");
SDLoc DL(Op);
+ assert((VT == MVT::i64 || VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8 ||
+ VT == MVT::nxv8i16) &&
+ "Unexpected Type");
+
+ if (VT == MVT::nxv8i16) {
+ // clmul.i16(a, b) = xor(pmullb(a_lo, b_lo),
+ // lsl(xor(pmul(a_hi, b_lo),
+ // pmul(a_lo, b_hi)),
+ // 8))
+
+ SDValue OpA = Op.getOperand(0);
+ SDValue OpB = Op.getOperand(1);
+ SDValue SplatEight =
+ DAG.getSplatVector(VT, DL, DAG.getConstant(8, DL, MVT::i16));
+
+ // Shift >> 8 and bitcast to i8 for pmul
+ SDValue OpAHi = DAG.getNode(ISD::SRL, DL, VT, OpA, SplatEight);
+ OpAHi = DAG.getNode(ISD::BITCAST, DL, MVT::nxv16i8, OpAHi);
+ SDValue OpBHi = DAG.getNode(ISD::SRL, DL, VT, OpB, SplatEight);
+ OpBHi = DAG.getNode(ISD::BITCAST, DL, MVT::nxv16i8, OpBHi);
+
+ // Bitcast to i8 for pmullb
+ OpA = DAG.getNode(ISD::BITCAST, DL, MVT::nxv16i8, OpA);
+ OpB = DAG.getNode(ISD::BITCAST, DL, MVT::nxv16i8, OpB);
+
+ SDValue PMULLB =
+ DAG.getTargetConstant(Intrinsic::aarch64_sve_pmullb_pair, DL, MVT::i64);
+ PMULLB = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::nxv16i8, PMULLB, OpA,
+ OpB);
+ PMULLB = DAG.getNode(ISD::BITCAST, DL, VT, PMULLB);
+
+ SDValue PMUL_OpALo_OpBHi =
+ DAG.getNode(ISD::CLMUL, DL, MVT::nxv16i8, OpA, OpBHi);
+ SDValue PMUL_OpAHi_OpBLo =
+ DAG.getNode(ISD::CLMUL, DL, MVT::nxv16i8, OpAHi, OpB);
+ SDValue Cross = DAG.getNode(ISD::XOR, DL, MVT::nxv16i8, PMUL_OpALo_OpBHi,
+ PMUL_OpAHi_OpBLo);
+ Cross = DAG.getNode(ISD::SHL, DL, VT,
+ DAG.getNode(ISD::BITCAST, DL, VT, Cross), SplatEight);
+
+ return DAG.getNode(ISD::XOR, DL, VT, PMULLB, Cross);
+ }
+
EVT VecVT = EVT::getVectorVT(*DAG.getContext(), VT, 64 / VT.getSizeInBits());
EVT CLMULTy = VT == MVT::i8 ? MVT::v8i8 : MVT::v1i64;
EVT ExtractTy = VT == MVT::i64 ? MVT::i64 : MVT::i32;
diff --git a/llvm/test/CodeGen/AArch64/clmul-scalable.ll b/llvm/test/CodeGen/AArch64/clmul-scalable.ll
index ef903902b9e65..04114e1dc1807 100644
--- a/llvm/test/CodeGen/AArch64/clmul-scalable.ll
+++ b/llvm/test/CodeGen/AArch64/clmul-scalable.ll
@@ -237,242 +237,50 @@ define <vscale x 8 x i16> @clmul_nxv8i16(<vscale x 8 x i16> %x, <vscale x 8 x i1
;
; CHECK-SME-STREAMING-LABEL: clmul_nxv8i16:
; CHECK-SME-STREAMING: // %bb.0:
-; CHECK-SME-STREAMING-NEXT: movprfx z2, z1
-; CHECK-SME-STREAMING-NEXT: and z2.h, z2.h, #0x2
-; CHECK-SME-STREAMING-NEXT: movprfx z3, z1
-; CHECK-SME-STREAMING-NEXT: and z3.h, z3.h, #0x1
-; CHECK-SME-STREAMING-NEXT: movprfx z4, z1
-; CHECK-SME-STREAMING-NEXT: and z4.h, z4.h, #0x8
-; CHECK-SME-STREAMING-NEXT: movprfx z5, z1
-; CHECK-SME-STREAMING-NEXT: and z5.h, z5.h, #0x4
-; CHECK-SME-STREAMING-NEXT: movprfx z6, z1
-; CHECK-SME-STREAMING-NEXT: and z6.h, z6.h, #0x10
-; CHECK-SME-STREAMING-NEXT: mul z2.h, z0.h, z2.h
-; CHECK-SME-STREAMING-NEXT: mul z3.h, z0.h, z3.h
-; CHECK-SME-STREAMING-NEXT: mul z4.h, z0.h, z4.h
-; CHECK-SME-STREAMING-NEXT: mul z5.h, z0.h, z5.h
-; CHECK-SME-STREAMING-NEXT: eor z2.d, z3.d, z2.d
-; CHECK-SME-STREAMING-NEXT: movprfx z3, z1
-; CHECK-SME-STREAMING-NEXT: and z3.h, z3.h, #0x20
-; CHECK-SME-STREAMING-NEXT: eor3 z2.d, z2.d, z5.d, z4.d
-; CHECK-SME-STREAMING-NEXT: mul z3.h, z0.h, z3.h
-; CHECK-SME-STREAMING-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SME-STREAMING-NEXT: movprfx z5, z1
-; CHECK-SME-STREAMING-NEXT: and z5.h, z5.h, #0x80
-; CHECK-SME-STREAMING-NEXT: movprfx z6, z1
-; CHECK-SME-STREAMING-NEXT: and z6.h, z6.h, #0x40
-; CHECK-SME-STREAMING-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SME-STREAMING-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SME-STREAMING-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SME-STREAMING-NEXT: movprfx z5, z1
-; CHECK-SME-STREAMING-NEXT: and z5.h, z5.h, #0x200
-; CHECK-SME-STREAMING-NEXT: movprfx z6, z1
-; CHECK-SME-STREAMING-NEXT: and z6.h, z6.h, #0x100
-; CHECK-SME-STREAMING-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SME-STREAMING-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SME-STREAMING-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SME-STREAMING-NEXT: movprfx z5, z1
-; CHECK-SME-STREAMING-NEXT: and z5.h, z5.h, #0x800
-; CHECK-SME-STREAMING-NEXT: movprfx z6, z1
-; CHECK-SME-STREAMING-NEXT: and z6.h, z6.h, #0x400
-; CHECK-SME-STREAMING-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SME-STREAMING-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SME-STREAMING-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SME-STREAMING-NEXT: movprfx z5, z1
-; CHECK-SME-STREAMING-NEXT: and z5.h, z5.h, #0x2000
-; CHECK-SME-STREAMING-NEXT: movprfx z6, z1
-; CHECK-SME-STREAMING-NEXT: and z6.h, z6.h, #0x1000
-; CHECK-SME-STREAMING-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SME-STREAMING-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SME-STREAMING-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SME-STREAMING-NEXT: movprfx z5, z1
-; CHECK-SME-STREAMING-NEXT: and z5.h, z5.h, #0x8000
-; CHECK-SME-STREAMING-NEXT: and z1.h, z1.h, #0x4000
-; CHECK-SME-STREAMING-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SME-STREAMING-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SME-STREAMING-NEXT: mul z0.h, z0.h, z1.h
-; CHECK-SME-STREAMING-NEXT: eor3 z2.d, z2.d, z0.d, z3.d
-; CHECK-SME-STREAMING-NEXT: mov z0.d, z2.d
+; CHECK-SME-STREAMING-NEXT: lsr z2.h, z0.h, #8
+; CHECK-SME-STREAMING-NEXT: lsr z3.h, z1.h, #8
+; CHECK-SME-STREAMING-NEXT: pmul z2.b, z2.b, z1.b
+; CHECK-SME-STREAMING-NEXT: pmul z3.b, z0.b, z3.b
+; CHECK-SME-STREAMING-NEXT: pmullb z0.h, z0.b, z1.b
+; CHECK-SME-STREAMING-NEXT: eor z1.d, z3.d, z2.d
+; CHECK-SME-STREAMING-NEXT: lsl z1.h, z1.h, #8
+; CHECK-SME-STREAMING-NEXT: eor z0.d, z0.d, z1.d
; CHECK-SME-STREAMING-NEXT: ret
;
; CHECK-SME-STREAMING-SSVE-AES-LABEL: clmul_nxv8i16:
; CHECK-SME-STREAMING-SSVE-AES: // %bb.0:
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z2, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z2.h, z2.h, #0x2
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z3, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z3.h, z3.h, #0x1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z4, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z4.h, z4.h, #0x8
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z5, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z5.h, z5.h, #0x4
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z6, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z6.h, z6.h, #0x10
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z2.h, z0.h, z2.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z3.h, z0.h, z3.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z4.h, z0.h, z4.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z5.h, z0.h, z5.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor z2.d, z3.d, z2.d
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z3, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z3.h, z3.h, #0x20
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor3 z2.d, z2.d, z5.d, z4.d
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z3.h, z0.h, z3.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z5, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z5.h, z5.h, #0x80
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z6, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z6.h, z6.h, #0x40
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z5, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z5.h, z5.h, #0x200
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z6, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z6.h, z6.h, #0x100
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z5, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z5.h, z5.h, #0x800
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z6, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z6.h, z6.h, #0x400
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z5, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z5.h, z5.h, #0x2000
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z6, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z6.h, z6.h, #0x1000
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z5, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z5.h, z5.h, #0x8000
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z1.h, z1.h, #0x4000
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z0.h, z0.h, z1.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor3 z2.d, z2.d, z0.d, z3.d
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mov z0.d, z2.d
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: lsr z2.h, z0.h, #8
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: lsr z3.h, z1.h, #8
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: pmul z2.b, z2.b, z1.b
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: pmul z3.b, z0.b, z3.b
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: pmullb z0.h, z0.b, z1.b
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor z1.d, z3.d, z2.d
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: lsl z1.h, z1.h, #8
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor z0.d, z0.d, z1.d
; CHECK-SME-STREAMING-SSVE-AES-NEXT: ret
;
; CHECK-SVE2-LABEL: clmul_nxv8i16:
; CHECK-SVE2: // %bb.0:
-; CHECK-SVE2-NEXT: movprfx z2, z1
-; CHECK-SVE2-NEXT: and z2.h, z2.h, #0x2
-; CHECK-SVE2-NEXT: movprfx z3, z1
-; CHECK-SVE2-NEXT: and z3.h, z3.h, #0x1
-; CHECK-SVE2-NEXT: movprfx z4, z1
-; CHECK-SVE2-NEXT: and z4.h, z4.h, #0x8
-; CHECK-SVE2-NEXT: movprfx z5, z1
-; CHECK-SVE2-NEXT: and z5.h, z5.h, #0x4
-; CHECK-SVE2-NEXT: movprfx z6, z1
-; CHECK-SVE2-NEXT: and z6.h, z6.h, #0x10
-; CHECK-SVE2-NEXT: mul z2.h, z0.h, z2.h
-; CHECK-SVE2-NEXT: mul z3.h, z0.h, z3.h
-; CHECK-SVE2-NEXT: mul z4.h, z0.h, z4.h
-; CHECK-SVE2-NEXT: mul z5.h, z0.h, z5.h
-; CHECK-SVE2-NEXT: eor z2.d, z3.d, z2.d
-; CHECK-SVE2-NEXT: movprfx z3, z1
-; CHECK-SVE2-NEXT: and z3.h, z3.h, #0x20
-; CHECK-SVE2-NEXT: eor3 z2.d, z2.d, z5.d, z4.d
-; CHECK-SVE2-NEXT: mul z3.h, z0.h, z3.h
-; CHECK-SVE2-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SVE2-NEXT: movprfx z5, z1
-; CHECK-SVE2-NEXT: and z5.h, z5.h, #0x80
-; CHECK-SVE2-NEXT: movprfx z6, z1
-; CHECK-SVE2-NEXT: and z6.h, z6.h, #0x40
-; CHECK-SVE2-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SVE2-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SVE2-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SVE2-NEXT: movprfx z5, z1
-; CHECK-SVE2-NEXT: and z5.h, z5.h, #0x200
-; CHECK-SVE2-NEXT: movprfx z6, z1
-; CHECK-SVE2-NEXT: and z6.h, z6.h, #0x100
-; CHECK-SVE2-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SVE2-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SVE2-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SVE2-NEXT: movprfx z5, z1
-; CHECK-SVE2-NEXT: and z5.h, z5.h, #0x800
-; CHECK-SVE2-NEXT: movprfx z6, z1
-; CHECK-SVE2-NEXT: and z6.h, z6.h, #0x400
-; CHECK-SVE2-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SVE2-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SVE2-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SVE2-NEXT: movprfx z5, z1
-; CHECK-SVE2-NEXT: and z5.h, z5.h, #0x2000
-; CHECK-SVE2-NEXT: movprfx z6, z1
-; CHECK-SVE2-NEXT: and z6.h, z6.h, #0x1000
-; CHECK-SVE2-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SVE2-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SVE2-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SVE2-NEXT: movprfx z5, z1
-; CHECK-SVE2-NEXT: and z5.h, z5.h, #0x8000
-; CHECK-SVE2-NEXT: and z1.h, z1.h, #0x4000
-; CHECK-SVE2-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SVE2-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SVE2-NEXT: mul z0.h, z0.h, z1.h
-; CHECK-SVE2-NEXT: eor3 z2.d, z2.d, z0.d, z3.d
-; CHECK-SVE2-NEXT: mov z0.d, z2.d
+; CHECK-SVE2-NEXT: lsr z2.h, z0.h, #8
+; CHECK-SVE2-NEXT: lsr z3.h, z1.h, #8
+; CHECK-SVE2-NEXT: pmul z2.b, z2.b, z1.b
+; CHECK-SVE2-NEXT: pmul z3.b, z0.b, z3.b
+; CHECK-SVE2-NEXT: pmullb z0.h, z0.b, z1.b
+; CHECK-SVE2-NEXT: eor z1.d, z3.d, z2.d
+; CHECK-SVE2-NEXT: lsl z1.h, z1.h, #8
+; CHECK-SVE2-NEXT: eor z0.d, z0.d, z1.d
; CHECK-SVE2-NEXT: ret
;
; CHECK-SVE2-AES-LABEL: clmul_nxv8i16:
; CHECK-SVE2-AES: // %bb.0:
-; CHECK-SVE2-AES-NEXT: movprfx z2, z1
-; CHECK-SVE2-AES-NEXT: and z2.h, z2.h, #0x2
-; CHECK-SVE2-AES-NEXT: movprfx z3, z1
-; CHECK-SVE2-AES-NEXT: and z3.h, z3.h, #0x1
-; CHECK-SVE2-AES-NEXT: movprfx z4, z1
-; CHECK-SVE2-AES-NEXT: and z4.h, z4.h, #0x8
-; CHECK-SVE2-AES-NEXT: movprfx z5, z1
-; CHECK-SVE2-AES-NEXT: and z5.h, z5.h, #0x4
-; CHECK-SVE2-AES-NEXT: movprfx z6, z1
-; CHECK-SVE2-AES-NEXT: and z6.h, z6.h, #0x10
-; CHECK-SVE2-AES-NEXT: mul z2.h, z0.h, z2.h
-; CHECK-SVE2-AES-NEXT: mul z3.h, z0.h, z3.h
-; CHECK-SVE2-AES-NEXT: mul z4.h, z0.h, z4.h
-; CHECK-SVE2-AES-NEXT: mul z5.h, z0.h, z5.h
-; CHECK-SVE2-AES-NEXT: eor z2.d, z3.d, z2.d
-; CHECK-SVE2-AES-NEXT: movprfx z3, z1
-; CHECK-SVE2-AES-NEXT: and z3.h, z3.h, #0x20
-; CHECK-SVE2-AES-NEXT: eor3 z2.d, z2.d, z5.d, z4.d
-; CHECK-SVE2-AES-NEXT: mul z3.h, z0.h, z3.h
-; CHECK-SVE2-AES-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SVE2-AES-NEXT: movprfx z5, z1
-; CHECK-SVE2-AES-NEXT: and z5.h, z5.h, #0x80
-; CHECK-SVE2-AES-NEXT: movprfx z6, z1
-; CHECK-SVE2-AES-NEXT: and z6.h, z6.h, #0x40
-; CHECK-SVE2-AES-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SVE2-AES-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SVE2-AES-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SVE2-AES-NEXT: movprfx z5, z1
-; CHECK-SVE2-AES-NEXT: and z5.h, z5.h, #0x200
-; CHECK-SVE2-AES-NEXT: movprfx z6, z1
-; CHECK-SVE2-AES-NEXT: and z6.h, z6.h, #0x100
-; CHECK-SVE2-AES-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SVE2-AES-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SVE2-AES-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SVE2-AES-NEXT: movprfx z5, z1
-; CHECK-SVE2-AES-NEXT: and z5.h, z5.h, #0x800
-; CHECK-SVE2-AES-NEXT: movprfx z6, z1
-; CHECK-SVE2-AES-NEXT: and z6.h, z6.h, #0x400
-; CHECK-SVE2-AES-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SVE2-AES-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SVE2-AES-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SVE2-AES-NEXT: movprfx z5, z1
-; CHECK-SVE2-AES-NEXT: and z5.h, z5.h, #0x2000
-; CHECK-SVE2-AES-NEXT: movprfx z6, z1
-; CHECK-SVE2-AES-NEXT: and z6.h, z6.h, #0x1000
-; CHECK-SVE2-AES-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SVE2-AES-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SVE2-AES-NEXT: mul z4.h, z0.h, z6.h
-; CHECK-SVE2-AES-NEXT: movprfx z5, z1
-; CHECK-SVE2-AES-NEXT: and z5.h, z5.h, #0x8000
-; CHECK-SVE2-AES-NEXT: and z1.h, z1.h, #0x4000
-; CHECK-SVE2-AES-NEXT: eor3 z2.d, z2.d, z4.d, z3.d
-; CHECK-SVE2-AES-NEXT: mul z3.h, z0.h, z5.h
-; CHECK-SVE2-AES-NEXT: mul z0.h, z0.h, z1.h
-; CHECK-SVE2-AES-NEXT: eor3 z2.d, z2.d, z0.d, z3.d
-; CHECK-SVE2-AES-NEXT: mov z0.d, z2.d
+; CHECK-SVE2-AES-NEXT: lsr z2.h, z0.h, #8
+; CHECK-SVE2-AES-NEXT: lsr z3.h, z1.h, #8
+; CHECK-SVE2-AES-NEXT: pmul z2.b, z2.b, z1.b
+; CHECK-SVE2-AES-NEXT: pmul z3.b, z0.b, z3.b
+; CHECK-SVE2-AES-NEXT: pmullb z0.h, z0.b, z1.b
+; CHECK-SVE2-AES-NEXT: eor z1.d, z3.d, z2.d
+; CHECK-SVE2-AES-NEXT: lsl z1.h, z1.h, #8
+; CHECK-SVE2-AES-NEXT: eor z0.d, z0.d, z1.d
; CHECK-SVE2-AES-NEXT: ret
%a = call <vscale x 8 x i16> @llvm.clmul.nxv8i16(<vscale x 8 x i16> %x, <vscale x 8 x i16> %y)
ret <vscale x 8 x i16> %a
@@ -1695,134 +1503,58 @@ define <vscale x 8 x i16> @clmul_nxv8i16_zext(<vscale x 8 x i8> %x, <vscale x 8
;
; CHECK-SME-STREAMING-LABEL: clmul_nxv8i16_zext:
; CHECK-SME-STREAMING: // %bb.0:
-; CHECK-SME-STREAMING-NEXT: movprfx z2, z0
-; CHECK-SME-STREAMING-NEXT: and z2.h, z2.h, #0xff
-; CHECK-SME-STREAMING-NEXT: movprfx z0, z1
-; CHECK-SME-STREAMING-NEXT: and z0.h, z0.h, #0x2
-; CHECK-SME-STREAMING-NEXT: movprfx z3, z1
-; CHECK-SME-STREAMING-NEXT: and z3.h, z3.h, #0x1
-; CHECK-SME-STREAMING-NEXT: movprfx z4, z1
-; CHECK-SME-STREAMING-NEXT: and z4.h, z4.h, #0x8
-; CHECK-SME-STREAMING-NEXT: movprfx z5, z1
-; CHECK-SME-STREAMING-NEXT: and z5.h, z5.h, #0x4
-; CHECK-SME-STREAMING-NEXT: movprfx z6, z1
-; CHECK-SME-STREAMING-NEXT: and z6.h, z6.h, #0x10
-; CHECK-SME-STREAMING-NEXT: mul z0.h, z2.h, z0.h
-; CHECK-SME-STREAMING-NEXT: mul z3.h, z2.h, z3.h
-; CHECK-SME-STREAMING-NEXT: mul z4.h, z2.h, z4.h
-; CHECK-SME-STREAMING-NEXT: mul z5.h, z2.h, z5.h
-; CHECK-SME-STREAMING-NEXT: eor z0.d, z3.d, z0.d
-; CHECK-SME-STREAMING-NEXT: movprfx z3, z1
-; CHECK-SME-STREAMING-NEXT: and z3.h, z3.h, #0x20
-; CHECK-SME-STREAMING-NEXT: eor3 z0.d, z0.d, z5.d, z4.d
-; CHECK-SME-STREAMING-NEXT: mul z3.h, z2.h, z3.h
-; CHECK-SME-STREAMING-NEXT: mul z4.h, z2.h, z6.h
-; CHECK-SME-STREAMING-NEXT: movprfx z5, z1
-; CHECK-SME-STREAMING-NEXT: and z5.h, z5.h, #0x80
-; CHECK-SME-STREAMING-NEXT: and z1.h, z1.h, #0x40
-; CHECK-SME-STREAMING-NEXT: eor3 z0.d, z0.d, z4.d, z3.d
-; CHECK-SME-STREAMING-NEXT: mul z3.h, z2.h, z5.h
-; CHECK-SME-STREAMING-NEXT: mul z1.h, z2.h, z1.h
-; CHECK-SME-STREAMING-NEXT: eor3 z0.d, z0.d, z1.d, z3.d
+; CHECK-SME-STREAMING-NEXT: and z0.h, z0.h, #0xff
+; CHECK-SME-STREAMING-NEXT: and z1.h, z1.h, #0xff
+; CHECK-SME-STREAMING-NEXT: lsr z2.h, z0.h, #8
+; CHECK-SME-STREAMING-NEXT: lsr z3.h, z1.h, #8
+; CHECK-SME-STREAMING-NEXT: pmul z2.b, z2.b, z1.b
+; CHECK-SME-STREAMING-NEXT: pmul z3.b, z0.b, z3.b
+; CHECK-SME-STREAMING-NEXT: pmullb z0.h, z0.b, z1.b
+; CHECK-SME-STREAMING-NEXT: eor z1.d, z3.d, z2.d
+; CHECK-SME-STREAMING-NEXT: lsl z1.h, z1.h, #8
+; CHECK-SME-STREAMING-NEXT: eor z0.d, z0.d, z1.d
; CHECK-SME-STREAMING-NEXT: ret
;
; CHECK-SME-STREAMING-SSVE-AES-LABEL: clmul_nxv8i16_zext:
; CHECK-SME-STREAMING-SSVE-AES: // %bb.0:
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z2, z0
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z2.h, z2.h, #0xff
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z0, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z0.h, z0.h, #0x2
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z3, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z3.h, z3.h, #0x1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z4, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z4.h, z4.h, #0x8
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z5, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z5.h, z5.h, #0x4
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z6, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z6.h, z6.h, #0x10
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z0.h, z2.h, z0.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z3.h, z2.h, z3.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z4.h, z2.h, z4.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z5.h, z2.h, z5.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor z0.d, z3.d, z0.d
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z3, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z3.h, z3.h, #0x20
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor3 z0.d, z0.d, z5.d, z4.d
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z3.h, z2.h, z3.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z4.h, z2.h, z6.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: movprfx z5, z1
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z5.h, z5.h, #0x80
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z1.h, z1.h, #0x40
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor3 z0.d, z0.d, z4.d, z3.d
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z3.h, z2.h, z5.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: mul z1.h, z2.h, z1.h
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor3 z0.d, z0.d, z1.d, z3.d
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z0.h, z0.h, #0xff
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z1.h, z1.h, #0xff
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: lsr z2.h, z0.h, #8
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: lsr z3.h, z1.h, #8
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: pmul z2.b, z2.b, z1.b
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: pmul z3.b, z0.b, z3.b
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: pmullb z0.h, z0.b, z1.b
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor z1.d, z3.d, z2.d
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: lsl z1.h, z1.h, #8
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor z0.d, z0.d, z1.d
; CHECK-SME-STREAMING-SSVE-AES-NEXT: ret
;
; CHECK-SVE2-LABEL: clmul_nxv8i16_zext:
; CHECK-SVE2: // %bb.0:
-; CHECK-SVE2-NEXT: movprfx z2, z0
-; CHECK-SVE2-NEXT: and z2.h, z2.h, #0xff
-; CHECK-SVE2-NEXT: movprfx z0, z1
-; CHECK-SVE2-NEXT: and z0.h, z0.h, #0x2
-; CHECK-SVE2-NEXT: movprfx z3, z1
-; CHECK-SVE2-NEXT: and z3.h, z3.h, #0x1
-; CHECK-SVE2-NEXT: movprfx z4, z1
-; CHECK-SVE2-NEXT: and z4.h, z4.h, #0x8
-; CHECK-SVE2-NEXT: movprfx z5, z1
-; CHECK-SVE2-NEXT: and z5.h, z5.h, #0x4
-; CHECK-SVE2-NEXT: movprfx z6, z1
-; CHECK-SVE2-NEXT: and z6.h, z6.h, #0x10
-; CHECK-SVE2-NEXT: mul z0.h, z2.h, z0.h
-; CHECK-SVE2-NEXT: mul z3.h, z2.h, z3.h
-; CHECK-SVE2-NEXT: mul z4.h, z2.h, z4.h
-; CHECK-SVE2-NEXT: mul z5.h, z2.h, z5.h
-; CHECK-SVE2-NEXT: eor z0.d, z3.d, z0.d
-; CHECK-SVE2-NEXT: movprfx z3, z1
-; CHECK-SVE2-NEXT: and z3.h, z3.h, #0x20
-; CHECK-SVE2-NEXT: eor3 z0.d, z0.d, z5.d, z4.d
-; CHECK-SVE2-NEXT: mul z3.h, z2.h, z3.h
-; CHECK-SVE2-NEXT: mul z4.h, z2.h, z6.h
-; CHECK-SVE2-NEXT: movprfx z5, z1
-; CHECK-SVE2-NEXT: and z5.h, z5.h, #0x80
-; CHECK-SVE2-NEXT: and z1.h, z1.h, #0x40
-; CHECK-SVE2-NEXT: eor3 z0.d, z0.d, z4.d, z3.d
-; CHECK-SVE2-NEXT: mul z3.h, z2.h, z5.h
-; CHECK-SVE2-NEXT: mul z1.h, z2.h, z1.h
-; CHECK-SVE2-NEXT: eor3 z0.d, z0.d, z1.d, z3.d
+; CHECK-SVE2-NEXT: and z0.h, z0.h, #0xff
+; CHECK-SVE2-NEXT: and z1.h, z1.h, #0xff
+; CHECK-SVE2-NEXT: lsr z2.h, z0.h, #8
+; CHECK-SVE2-NEXT: lsr z3.h, z1.h, #8
+; CHECK-SVE2-NEXT: pmul z2.b, z2.b, z1.b
+; CHECK-SVE2-NEXT: pmul z3.b, z0.b, z3.b
+; CHECK-SVE2-NEXT: pmullb z0.h, z0.b, z1.b
+; CHECK-SVE2-NEXT: eor z1.d, z3.d, z2.d
+; CHECK-SVE2-NEXT: lsl z1.h, z1.h, #8
+; CHECK-SVE2-NEXT: eor z0.d, z0.d, z1.d
; CHECK-SVE2-NEXT: ret
;
; CHECK-SVE2-AES-LABEL: clmul_nxv8i16_zext:
; CHECK-SVE2-AES: // %bb.0:
-; CHECK-SVE2-AES-NEXT: movprfx z2, z0
-; CHECK-SVE2-AES-NEXT: and z2.h, z2.h, #0xff
-; CHECK-SVE2-AES-NEXT: movprfx z0, z1
-; CHECK-SVE2-AES-NEXT: and z0.h, z0.h, #0x2
-; CHECK-SVE2-AES-NEXT: movprfx z3, z1
-; CHECK-SVE2-AES-NEXT: and z3.h, z3.h, #0x1
-; CHECK-SVE2-AES-NEXT: movprfx z4, z1
-; CHECK-SVE2-AES-NEXT: and z4.h, z4.h, #0x8
-; CHECK-SVE2-AES-NEXT: movprfx z5, z1
-; CHECK-SVE2-AES-NEXT: and z5.h, z5.h, #0x4
-; CHECK-SVE2-AES-NEXT: movprfx z6, z1
-; CHECK-SVE2-AES-NEXT: and z6.h, z6.h, #0x10
-; CHECK-SVE2-AES-NEXT: mul z0.h, z2.h, z0.h
-; CHECK-SVE2-AES-NEXT: mul z3.h, z2.h, z3.h
-; CHECK-SVE2-AES-NEXT: mul z4.h, z2.h, z4.h
-; CHECK-SVE2-AES-NEXT: mul z5.h, z2.h, z5.h
-; CHECK-SVE2-AES-NEXT: eor z0.d, z3.d, z0.d
-; CHECK-SVE2-AES-NEXT: movprfx z3, z1
-; CHECK-SVE2-AES-NEXT: and z3.h, z3.h, #0x20
-; CHECK-SVE2-AES-NEXT: eor3 z0.d, z0.d, z5.d, z4.d
-; CHECK-SVE2-AES-NEXT: mul z3.h, z2.h, z3.h
-; CHECK-SVE2-AES-NEXT: mul z4.h, z2.h, z6.h
-; CHECK-SVE2-AES-NEXT: movprfx z5, z1
-; CHECK-SVE2-AES-NEXT: and z5.h, z5.h, #0x80
-; CHECK-SVE2-AES-NEXT: and z1.h, z1.h, #0x40
-; CHECK-SVE2-AES-NEXT: eor3 z0.d, z0.d, z4.d, z3.d
-; CHECK-SVE2-AES-NEXT: mul z3.h, z2.h, z5.h
-; CHECK-SVE2-AES-NEXT: mul z1.h, z2.h, z1.h
-; CHECK-SVE2-AES-NEXT: eor3 z0.d, z0.d, z1.d, z3.d
+; CHECK-SVE2-AES-NEXT: and z0.h, z0.h, #0xff
+; CHECK-SVE2-AES-NEXT: and z1.h, z1.h, #0xff
+; CHECK-SVE2-AES-NEXT: lsr z2.h, z0.h, #8
+; CHECK-SVE2-AES-NEXT: lsr z3.h, z1.h, #8
+; CHECK-SVE2-AES-NEXT: pmul z2.b, z2.b, z1.b
+; CHECK-SVE2-AES-NEXT: pmul z3.b, z0.b, z3.b
+; CHECK-SVE2-AES-NEXT: pmullb z0.h, z0.b, z1.b
+; CHECK-SVE2-AES-NEXT: eor z1.d, z3.d, z2.d
+; CHECK-SVE2-AES-NEXT: lsl z1.h, z1.h, #8
+; CHECK-SVE2-AES-NEXT: eor z0.d, z0.d, z1.d
; CHECK-SVE2-AES-NEXT: ret
%zextx = zext <vscale x 8 x i8> %x to <vscale x 8 x i16>
%zexty = zext <vscale x 8 x i8> %y to <vscale x 8 x i16>
>From 9ef204e68027b971ff39244220eeaaaf42aa9c48 Mon Sep 17 00:00:00 2001
From: Matthew Devereau <matthew.devereau at arm.com>
Date: Fri, 8 May 2026 14:47:16 +0000
Subject: [PATCH 2/3] Use single pmul and eortb
---
.../Target/AArch64/AArch64ISelLowering.cpp | 50 ++++++-------
llvm/test/CodeGen/AArch64/clmul-scalable.ll | 72 +++++++++----------
2 files changed, 55 insertions(+), 67 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 27fe5776a14fb..d2603cc1e52c2 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -8097,41 +8097,37 @@ static SDValue LowerCLMUL(SDValue Op, SelectionDAG &DAG) {
if (VT == MVT::nxv8i16) {
// clmul.i16(a, b) = xor(pmullb(a_lo, b_lo),
- // lsl(xor(pmul(a_hi, b_lo),
- // pmul(a_lo, b_hi)),
+ // lsl(eorbt(pmul(trn2(a, b),
+ // trn1(b, a))),
// 8))
-
SDValue OpA = Op.getOperand(0);
SDValue OpB = Op.getOperand(1);
- SDValue SplatEight =
- DAG.getSplatVector(VT, DL, DAG.getConstant(8, DL, MVT::i16));
-
- // Shift >> 8 and bitcast to i8 for pmul
- SDValue OpAHi = DAG.getNode(ISD::SRL, DL, VT, OpA, SplatEight);
- OpAHi = DAG.getNode(ISD::BITCAST, DL, MVT::nxv16i8, OpAHi);
- SDValue OpBHi = DAG.getNode(ISD::SRL, DL, VT, OpB, SplatEight);
- OpBHi = DAG.getNode(ISD::BITCAST, DL, MVT::nxv16i8, OpBHi);
-
- // Bitcast to i8 for pmullb
- OpA = DAG.getNode(ISD::BITCAST, DL, MVT::nxv16i8, OpA);
- OpB = DAG.getNode(ISD::BITCAST, DL, MVT::nxv16i8, OpB);
+ // Bitcast to i8 for byte-wise PMUL and PMULLB.
+ OpA = DAG.getNode(AArch64ISD::NVCAST, DL, MVT::nxv16i8, OpA);
+ OpB = DAG.getNode(AArch64ISD::NVCAST, DL, MVT::nxv16i8, OpB);
+
+ // Form adjacent byte pairs {a_hi, b_hi} and {b_lo, a_lo}. PMUL then
+ // computes {a_hi * b_lo, b_hi * a_lo}, and EORTB xors those pairs into
+ // the low byte of each half-word.
+ SDValue LoBytes = DAG.getNode(AArch64ISD::TRN1, DL, MVT::nxv16i8, OpB, OpA);
+ SDValue HiBytes = DAG.getNode(AArch64ISD::TRN2, DL, MVT::nxv16i8, OpA, OpB);
+ SDValue PMUL = DAG.getNode(ISD::CLMUL, DL, MVT::nxv16i8, HiBytes, LoBytes);
+
+ SDValue EORBT =
+ DAG.getTargetConstant(Intrinsic::aarch64_sve_eorbt, DL, MVT::i64);
+ EORBT = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::nxv16i8, EORBT, OpB,
+ PMUL, PMUL);
+ SDValue SHL = DAG.getNode(ISD::SHL, DL, VT,
+ DAG.getNode(AArch64ISD::NVCAST, DL, VT, EORBT),
+ DAG.getConstant(8, DL, VT));
SDValue PMULLB =
DAG.getTargetConstant(Intrinsic::aarch64_sve_pmullb_pair, DL, MVT::i64);
PMULLB = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::nxv16i8, PMULLB, OpA,
OpB);
- PMULLB = DAG.getNode(ISD::BITCAST, DL, VT, PMULLB);
-
- SDValue PMUL_OpALo_OpBHi =
- DAG.getNode(ISD::CLMUL, DL, MVT::nxv16i8, OpA, OpBHi);
- SDValue PMUL_OpAHi_OpBLo =
- DAG.getNode(ISD::CLMUL, DL, MVT::nxv16i8, OpAHi, OpB);
- SDValue Cross = DAG.getNode(ISD::XOR, DL, MVT::nxv16i8, PMUL_OpALo_OpBHi,
- PMUL_OpAHi_OpBLo);
- Cross = DAG.getNode(ISD::SHL, DL, VT,
- DAG.getNode(ISD::BITCAST, DL, VT, Cross), SplatEight);
-
- return DAG.getNode(ISD::XOR, DL, VT, PMULLB, Cross);
+ PMULLB = DAG.getNode(AArch64ISD::NVCAST, DL, VT, PMULLB);
+
+ return DAG.getNode(ISD::XOR, DL, VT, PMULLB, SHL);
}
EVT VecVT = EVT::getVectorVT(*DAG.getContext(), VT, 64 / VT.getSizeInBits());
diff --git a/llvm/test/CodeGen/AArch64/clmul-scalable.ll b/llvm/test/CodeGen/AArch64/clmul-scalable.ll
index 04114e1dc1807..5dad96074b88b 100644
--- a/llvm/test/CodeGen/AArch64/clmul-scalable.ll
+++ b/llvm/test/CodeGen/AArch64/clmul-scalable.ll
@@ -237,48 +237,44 @@ define <vscale x 8 x i16> @clmul_nxv8i16(<vscale x 8 x i16> %x, <vscale x 8 x i1
;
; CHECK-SME-STREAMING-LABEL: clmul_nxv8i16:
; CHECK-SME-STREAMING: // %bb.0:
-; CHECK-SME-STREAMING-NEXT: lsr z2.h, z0.h, #8
-; CHECK-SME-STREAMING-NEXT: lsr z3.h, z1.h, #8
-; CHECK-SME-STREAMING-NEXT: pmul z2.b, z2.b, z1.b
-; CHECK-SME-STREAMING-NEXT: pmul z3.b, z0.b, z3.b
+; CHECK-SME-STREAMING-NEXT: trn1 z2.b, z1.b, z0.b
+; CHECK-SME-STREAMING-NEXT: trn2 z3.b, z0.b, z1.b
; CHECK-SME-STREAMING-NEXT: pmullb z0.h, z0.b, z1.b
-; CHECK-SME-STREAMING-NEXT: eor z1.d, z3.d, z2.d
+; CHECK-SME-STREAMING-NEXT: pmul z2.b, z3.b, z2.b
+; CHECK-SME-STREAMING-NEXT: eorbt z1.b, z2.b, z2.b
; CHECK-SME-STREAMING-NEXT: lsl z1.h, z1.h, #8
; CHECK-SME-STREAMING-NEXT: eor z0.d, z0.d, z1.d
; CHECK-SME-STREAMING-NEXT: ret
;
; CHECK-SME-STREAMING-SSVE-AES-LABEL: clmul_nxv8i16:
; CHECK-SME-STREAMING-SSVE-AES: // %bb.0:
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: lsr z2.h, z0.h, #8
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: lsr z3.h, z1.h, #8
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: pmul z2.b, z2.b, z1.b
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: pmul z3.b, z0.b, z3.b
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: trn1 z2.b, z1.b, z0.b
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: trn2 z3.b, z0.b, z1.b
; CHECK-SME-STREAMING-SSVE-AES-NEXT: pmullb z0.h, z0.b, z1.b
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor z1.d, z3.d, z2.d
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: pmul z2.b, z3.b, z2.b
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: eorbt z1.b, z2.b, z2.b
; CHECK-SME-STREAMING-SSVE-AES-NEXT: lsl z1.h, z1.h, #8
; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor z0.d, z0.d, z1.d
; CHECK-SME-STREAMING-SSVE-AES-NEXT: ret
;
; CHECK-SVE2-LABEL: clmul_nxv8i16:
; CHECK-SVE2: // %bb.0:
-; CHECK-SVE2-NEXT: lsr z2.h, z0.h, #8
-; CHECK-SVE2-NEXT: lsr z3.h, z1.h, #8
-; CHECK-SVE2-NEXT: pmul z2.b, z2.b, z1.b
-; CHECK-SVE2-NEXT: pmul z3.b, z0.b, z3.b
+; CHECK-SVE2-NEXT: trn1 z2.b, z1.b, z0.b
+; CHECK-SVE2-NEXT: trn2 z3.b, z0.b, z1.b
; CHECK-SVE2-NEXT: pmullb z0.h, z0.b, z1.b
-; CHECK-SVE2-NEXT: eor z1.d, z3.d, z2.d
+; CHECK-SVE2-NEXT: pmul z2.b, z3.b, z2.b
+; CHECK-SVE2-NEXT: eorbt z1.b, z2.b, z2.b
; CHECK-SVE2-NEXT: lsl z1.h, z1.h, #8
; CHECK-SVE2-NEXT: eor z0.d, z0.d, z1.d
; CHECK-SVE2-NEXT: ret
;
; CHECK-SVE2-AES-LABEL: clmul_nxv8i16:
; CHECK-SVE2-AES: // %bb.0:
-; CHECK-SVE2-AES-NEXT: lsr z2.h, z0.h, #8
-; CHECK-SVE2-AES-NEXT: lsr z3.h, z1.h, #8
-; CHECK-SVE2-AES-NEXT: pmul z2.b, z2.b, z1.b
-; CHECK-SVE2-AES-NEXT: pmul z3.b, z0.b, z3.b
+; CHECK-SVE2-AES-NEXT: trn1 z2.b, z1.b, z0.b
+; CHECK-SVE2-AES-NEXT: trn2 z3.b, z0.b, z1.b
; CHECK-SVE2-AES-NEXT: pmullb z0.h, z0.b, z1.b
-; CHECK-SVE2-AES-NEXT: eor z1.d, z3.d, z2.d
+; CHECK-SVE2-AES-NEXT: pmul z2.b, z3.b, z2.b
+; CHECK-SVE2-AES-NEXT: eorbt z1.b, z2.b, z2.b
; CHECK-SVE2-AES-NEXT: lsl z1.h, z1.h, #8
; CHECK-SVE2-AES-NEXT: eor z0.d, z0.d, z1.d
; CHECK-SVE2-AES-NEXT: ret
@@ -1505,12 +1501,11 @@ define <vscale x 8 x i16> @clmul_nxv8i16_zext(<vscale x 8 x i8> %x, <vscale x 8
; CHECK-SME-STREAMING: // %bb.0:
; CHECK-SME-STREAMING-NEXT: and z0.h, z0.h, #0xff
; CHECK-SME-STREAMING-NEXT: and z1.h, z1.h, #0xff
-; CHECK-SME-STREAMING-NEXT: lsr z2.h, z0.h, #8
-; CHECK-SME-STREAMING-NEXT: lsr z3.h, z1.h, #8
-; CHECK-SME-STREAMING-NEXT: pmul z2.b, z2.b, z1.b
-; CHECK-SME-STREAMING-NEXT: pmul z3.b, z0.b, z3.b
+; CHECK-SME-STREAMING-NEXT: trn1 z2.b, z1.b, z0.b
+; CHECK-SME-STREAMING-NEXT: trn2 z3.b, z0.b, z1.b
; CHECK-SME-STREAMING-NEXT: pmullb z0.h, z0.b, z1.b
-; CHECK-SME-STREAMING-NEXT: eor z1.d, z3.d, z2.d
+; CHECK-SME-STREAMING-NEXT: pmul z2.b, z3.b, z2.b
+; CHECK-SME-STREAMING-NEXT: eorbt z1.b, z2.b, z2.b
; CHECK-SME-STREAMING-NEXT: lsl z1.h, z1.h, #8
; CHECK-SME-STREAMING-NEXT: eor z0.d, z0.d, z1.d
; CHECK-SME-STREAMING-NEXT: ret
@@ -1519,12 +1514,11 @@ define <vscale x 8 x i16> @clmul_nxv8i16_zext(<vscale x 8 x i8> %x, <vscale x 8
; CHECK-SME-STREAMING-SSVE-AES: // %bb.0:
; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z0.h, z0.h, #0xff
; CHECK-SME-STREAMING-SSVE-AES-NEXT: and z1.h, z1.h, #0xff
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: lsr z2.h, z0.h, #8
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: lsr z3.h, z1.h, #8
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: pmul z2.b, z2.b, z1.b
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: pmul z3.b, z0.b, z3.b
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: trn1 z2.b, z1.b, z0.b
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: trn2 z3.b, z0.b, z1.b
; CHECK-SME-STREAMING-SSVE-AES-NEXT: pmullb z0.h, z0.b, z1.b
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor z1.d, z3.d, z2.d
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: pmul z2.b, z3.b, z2.b
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: eorbt z1.b, z2.b, z2.b
; CHECK-SME-STREAMING-SSVE-AES-NEXT: lsl z1.h, z1.h, #8
; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor z0.d, z0.d, z1.d
; CHECK-SME-STREAMING-SSVE-AES-NEXT: ret
@@ -1533,12 +1527,11 @@ define <vscale x 8 x i16> @clmul_nxv8i16_zext(<vscale x 8 x i8> %x, <vscale x 8
; CHECK-SVE2: // %bb.0:
; CHECK-SVE2-NEXT: and z0.h, z0.h, #0xff
; CHECK-SVE2-NEXT: and z1.h, z1.h, #0xff
-; CHECK-SVE2-NEXT: lsr z2.h, z0.h, #8
-; CHECK-SVE2-NEXT: lsr z3.h, z1.h, #8
-; CHECK-SVE2-NEXT: pmul z2.b, z2.b, z1.b
-; CHECK-SVE2-NEXT: pmul z3.b, z0.b, z3.b
+; CHECK-SVE2-NEXT: trn1 z2.b, z1.b, z0.b
+; CHECK-SVE2-NEXT: trn2 z3.b, z0.b, z1.b
; CHECK-SVE2-NEXT: pmullb z0.h, z0.b, z1.b
-; CHECK-SVE2-NEXT: eor z1.d, z3.d, z2.d
+; CHECK-SVE2-NEXT: pmul z2.b, z3.b, z2.b
+; CHECK-SVE2-NEXT: eorbt z1.b, z2.b, z2.b
; CHECK-SVE2-NEXT: lsl z1.h, z1.h, #8
; CHECK-SVE2-NEXT: eor z0.d, z0.d, z1.d
; CHECK-SVE2-NEXT: ret
@@ -1547,12 +1540,11 @@ define <vscale x 8 x i16> @clmul_nxv8i16_zext(<vscale x 8 x i8> %x, <vscale x 8
; CHECK-SVE2-AES: // %bb.0:
; CHECK-SVE2-AES-NEXT: and z0.h, z0.h, #0xff
; CHECK-SVE2-AES-NEXT: and z1.h, z1.h, #0xff
-; CHECK-SVE2-AES-NEXT: lsr z2.h, z0.h, #8
-; CHECK-SVE2-AES-NEXT: lsr z3.h, z1.h, #8
-; CHECK-SVE2-AES-NEXT: pmul z2.b, z2.b, z1.b
-; CHECK-SVE2-AES-NEXT: pmul z3.b, z0.b, z3.b
+; CHECK-SVE2-AES-NEXT: trn1 z2.b, z1.b, z0.b
+; CHECK-SVE2-AES-NEXT: trn2 z3.b, z0.b, z1.b
; CHECK-SVE2-AES-NEXT: pmullb z0.h, z0.b, z1.b
-; CHECK-SVE2-AES-NEXT: eor z1.d, z3.d, z2.d
+; CHECK-SVE2-AES-NEXT: pmul z2.b, z3.b, z2.b
+; CHECK-SVE2-AES-NEXT: eorbt z1.b, z2.b, z2.b
; CHECK-SVE2-AES-NEXT: lsl z1.h, z1.h, #8
; CHECK-SVE2-AES-NEXT: eor z0.d, z0.d, z1.d
; CHECK-SVE2-AES-NEXT: ret
>From 6df3e2228f02056d73de0b4ccdb080610a48d115 Mon Sep 17 00:00:00 2001
From: Matthew Devereau <matthew.devereau at arm.com>
Date: Mon, 11 May 2026 14:41:49 +0000
Subject: [PATCH 3/3] use eortb
---
.../Target/AArch64/AArch64ISelLowering.cpp | 19 +++++++--------
llvm/test/CodeGen/AArch64/clmul-scalable.ll | 24 +++++++------------
2 files changed, 16 insertions(+), 27 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index d2603cc1e52c2..448e74ecd3413 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -8096,10 +8096,8 @@ static SDValue LowerCLMUL(SDValue Op, SelectionDAG &DAG) {
"Unexpected Type");
if (VT == MVT::nxv8i16) {
- // clmul.i16(a, b) = xor(pmullb(a_lo, b_lo),
- // lsl(eorbt(pmul(trn2(a, b),
- // trn1(b, a))),
- // 8))
+ // clmul.i16(a, b) = eortb(pmullb(a_lo, b_lo),
+ // pmul(trn2(a, b), trn1(b, a)))
SDValue OpA = Op.getOperand(0);
SDValue OpB = Op.getOperand(1);
// Bitcast to i8 for byte-wise PMUL and PMULLB.
@@ -8107,8 +8105,7 @@ static SDValue LowerCLMUL(SDValue Op, SelectionDAG &DAG) {
OpB = DAG.getNode(AArch64ISD::NVCAST, DL, MVT::nxv16i8, OpB);
// Form adjacent byte pairs {a_hi, b_hi} and {b_lo, a_lo}. PMUL then
- // computes {a_hi * b_lo, b_hi * a_lo}, and EORTB xors those pairs into
- // the low byte of each half-word.
+ // computes {a_hi * b_lo, b_hi * a_lo}, and EORBT xors those pairs.
SDValue LoBytes = DAG.getNode(AArch64ISD::TRN1, DL, MVT::nxv16i8, OpB, OpA);
SDValue HiBytes = DAG.getNode(AArch64ISD::TRN2, DL, MVT::nxv16i8, OpA, OpB);
SDValue PMUL = DAG.getNode(ISD::CLMUL, DL, MVT::nxv16i8, HiBytes, LoBytes);
@@ -8117,17 +8114,17 @@ static SDValue LowerCLMUL(SDValue Op, SelectionDAG &DAG) {
DAG.getTargetConstant(Intrinsic::aarch64_sve_eorbt, DL, MVT::i64);
EORBT = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::nxv16i8, EORBT, OpB,
PMUL, PMUL);
- SDValue SHL = DAG.getNode(ISD::SHL, DL, VT,
- DAG.getNode(AArch64ISD::NVCAST, DL, VT, EORBT),
- DAG.getConstant(8, DL, VT));
SDValue PMULLB =
DAG.getTargetConstant(Intrinsic::aarch64_sve_pmullb_pair, DL, MVT::i64);
PMULLB = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::nxv16i8, PMULLB, OpA,
OpB);
- PMULLB = DAG.getNode(AArch64ISD::NVCAST, DL, VT, PMULLB);
- return DAG.getNode(ISD::XOR, DL, VT, PMULLB, SHL);
+ SDValue EORTB =
+ DAG.getTargetConstant(Intrinsic::aarch64_sve_eortb, DL, MVT::i64);
+ EORTB = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::nxv16i8, EORTB,
+ PMULLB, PMULLB, EORBT);
+ return DAG.getNode(AArch64ISD::NVCAST, DL, MVT::nxv8i16, EORTB);
}
EVT VecVT = EVT::getVectorVT(*DAG.getContext(), VT, 64 / VT.getSizeInBits());
diff --git a/llvm/test/CodeGen/AArch64/clmul-scalable.ll b/llvm/test/CodeGen/AArch64/clmul-scalable.ll
index 5dad96074b88b..202d1b6c2daae 100644
--- a/llvm/test/CodeGen/AArch64/clmul-scalable.ll
+++ b/llvm/test/CodeGen/AArch64/clmul-scalable.ll
@@ -242,8 +242,7 @@ define <vscale x 8 x i16> @clmul_nxv8i16(<vscale x 8 x i16> %x, <vscale x 8 x i1
; CHECK-SME-STREAMING-NEXT: pmullb z0.h, z0.b, z1.b
; CHECK-SME-STREAMING-NEXT: pmul z2.b, z3.b, z2.b
; CHECK-SME-STREAMING-NEXT: eorbt z1.b, z2.b, z2.b
-; CHECK-SME-STREAMING-NEXT: lsl z1.h, z1.h, #8
-; CHECK-SME-STREAMING-NEXT: eor z0.d, z0.d, z1.d
+; CHECK-SME-STREAMING-NEXT: eortb z0.b, z0.b, z1.b
; CHECK-SME-STREAMING-NEXT: ret
;
; CHECK-SME-STREAMING-SSVE-AES-LABEL: clmul_nxv8i16:
@@ -253,8 +252,7 @@ define <vscale x 8 x i16> @clmul_nxv8i16(<vscale x 8 x i16> %x, <vscale x 8 x i1
; CHECK-SME-STREAMING-SSVE-AES-NEXT: pmullb z0.h, z0.b, z1.b
; CHECK-SME-STREAMING-SSVE-AES-NEXT: pmul z2.b, z3.b, z2.b
; CHECK-SME-STREAMING-SSVE-AES-NEXT: eorbt z1.b, z2.b, z2.b
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: lsl z1.h, z1.h, #8
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor z0.d, z0.d, z1.d
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: eortb z0.b, z0.b, z1.b
; CHECK-SME-STREAMING-SSVE-AES-NEXT: ret
;
; CHECK-SVE2-LABEL: clmul_nxv8i16:
@@ -264,8 +262,7 @@ define <vscale x 8 x i16> @clmul_nxv8i16(<vscale x 8 x i16> %x, <vscale x 8 x i1
; CHECK-SVE2-NEXT: pmullb z0.h, z0.b, z1.b
; CHECK-SVE2-NEXT: pmul z2.b, z3.b, z2.b
; CHECK-SVE2-NEXT: eorbt z1.b, z2.b, z2.b
-; CHECK-SVE2-NEXT: lsl z1.h, z1.h, #8
-; CHECK-SVE2-NEXT: eor z0.d, z0.d, z1.d
+; CHECK-SVE2-NEXT: eortb z0.b, z0.b, z1.b
; CHECK-SVE2-NEXT: ret
;
; CHECK-SVE2-AES-LABEL: clmul_nxv8i16:
@@ -275,8 +272,7 @@ define <vscale x 8 x i16> @clmul_nxv8i16(<vscale x 8 x i16> %x, <vscale x 8 x i1
; CHECK-SVE2-AES-NEXT: pmullb z0.h, z0.b, z1.b
; CHECK-SVE2-AES-NEXT: pmul z2.b, z3.b, z2.b
; CHECK-SVE2-AES-NEXT: eorbt z1.b, z2.b, z2.b
-; CHECK-SVE2-AES-NEXT: lsl z1.h, z1.h, #8
-; CHECK-SVE2-AES-NEXT: eor z0.d, z0.d, z1.d
+; CHECK-SVE2-AES-NEXT: eortb z0.b, z0.b, z1.b
; CHECK-SVE2-AES-NEXT: ret
%a = call <vscale x 8 x i16> @llvm.clmul.nxv8i16(<vscale x 8 x i16> %x, <vscale x 8 x i16> %y)
ret <vscale x 8 x i16> %a
@@ -1506,8 +1502,7 @@ define <vscale x 8 x i16> @clmul_nxv8i16_zext(<vscale x 8 x i8> %x, <vscale x 8
; CHECK-SME-STREAMING-NEXT: pmullb z0.h, z0.b, z1.b
; CHECK-SME-STREAMING-NEXT: pmul z2.b, z3.b, z2.b
; CHECK-SME-STREAMING-NEXT: eorbt z1.b, z2.b, z2.b
-; CHECK-SME-STREAMING-NEXT: lsl z1.h, z1.h, #8
-; CHECK-SME-STREAMING-NEXT: eor z0.d, z0.d, z1.d
+; CHECK-SME-STREAMING-NEXT: eortb z0.b, z0.b, z1.b
; CHECK-SME-STREAMING-NEXT: ret
;
; CHECK-SME-STREAMING-SSVE-AES-LABEL: clmul_nxv8i16_zext:
@@ -1519,8 +1514,7 @@ define <vscale x 8 x i16> @clmul_nxv8i16_zext(<vscale x 8 x i8> %x, <vscale x 8
; CHECK-SME-STREAMING-SSVE-AES-NEXT: pmullb z0.h, z0.b, z1.b
; CHECK-SME-STREAMING-SSVE-AES-NEXT: pmul z2.b, z3.b, z2.b
; CHECK-SME-STREAMING-SSVE-AES-NEXT: eorbt z1.b, z2.b, z2.b
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: lsl z1.h, z1.h, #8
-; CHECK-SME-STREAMING-SSVE-AES-NEXT: eor z0.d, z0.d, z1.d
+; CHECK-SME-STREAMING-SSVE-AES-NEXT: eortb z0.b, z0.b, z1.b
; CHECK-SME-STREAMING-SSVE-AES-NEXT: ret
;
; CHECK-SVE2-LABEL: clmul_nxv8i16_zext:
@@ -1532,8 +1526,7 @@ define <vscale x 8 x i16> @clmul_nxv8i16_zext(<vscale x 8 x i8> %x, <vscale x 8
; CHECK-SVE2-NEXT: pmullb z0.h, z0.b, z1.b
; CHECK-SVE2-NEXT: pmul z2.b, z3.b, z2.b
; CHECK-SVE2-NEXT: eorbt z1.b, z2.b, z2.b
-; CHECK-SVE2-NEXT: lsl z1.h, z1.h, #8
-; CHECK-SVE2-NEXT: eor z0.d, z0.d, z1.d
+; CHECK-SVE2-NEXT: eortb z0.b, z0.b, z1.b
; CHECK-SVE2-NEXT: ret
;
; CHECK-SVE2-AES-LABEL: clmul_nxv8i16_zext:
@@ -1545,8 +1538,7 @@ define <vscale x 8 x i16> @clmul_nxv8i16_zext(<vscale x 8 x i8> %x, <vscale x 8
; CHECK-SVE2-AES-NEXT: pmullb z0.h, z0.b, z1.b
; CHECK-SVE2-AES-NEXT: pmul z2.b, z3.b, z2.b
; CHECK-SVE2-AES-NEXT: eorbt z1.b, z2.b, z2.b
-; CHECK-SVE2-AES-NEXT: lsl z1.h, z1.h, #8
-; CHECK-SVE2-AES-NEXT: eor z0.d, z0.d, z1.d
+; CHECK-SVE2-AES-NEXT: eortb z0.b, z0.b, z1.b
; CHECK-SVE2-AES-NEXT: ret
%zextx = zext <vscale x 8 x i8> %x to <vscale x 8 x i16>
%zexty = zext <vscale x 8 x i8> %y to <vscale x 8 x i16>
More information about the llvm-commits
mailing list