[llvm] [AArch64][ISel] Add lowering for i8 clmul intrinsics (PR #177323)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 22 01:18:41 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: Matthew Devereau (MDevereau)

<details>
<summary>Changes</summary>

clmul added in #<!-- -->168731, can be lowered to pmul for full i8 vector types.

---
Full diff: https://github.com/llvm/llvm-project/pull/177323.diff


4 Files Affected:

- (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (+5-1) 
- (modified) llvm/lib/Target/AArch64/AArch64InstrInfo.td (+6-1) 
- (modified) llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td (+6-1) 
- (added) llvm/test/CodeGen/AArch64/clmul.ll (+20) 


``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index c81f457898d7c..e56da743b1ab3 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -1498,6 +1498,8 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
       }
     }
 
+    setOperationAction(ISD::CLMUL, MVT::v16i8, Legal);
+
   } else /* !isNeonAvailable */ {
     for (MVT VT : MVT::fixedlen_vector_valuetypes()) {
       for (unsigned Op = 0; Op < ISD::BUILTIN_OP_END; ++Op)
@@ -1984,11 +1986,13 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
                                 MVT::nxv16i8, Custom);
     }
 
-    // Wide add types
     if (Subtarget->hasSVE2() || Subtarget->hasSME()) {
+      // Wide add types
       setPartialReduceMLAAction(MLAOps, MVT::nxv2i64, MVT::nxv4i32, Legal);
       setPartialReduceMLAAction(MLAOps, MVT::nxv4i32, MVT::nxv8i16, Legal);
       setPartialReduceMLAAction(MLAOps, MVT::nxv8i16, MVT::nxv16i8, Legal);
+
+      setOperationAction(ISD::CLMUL, MVT::nxv16i8, Legal);
     }
 
     // Handle floating-point partial reduction
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 59a3b2d36e0f0..7ad77fe7d5cf0 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -1323,6 +1323,11 @@ def fminnum_nnan : PatFrag<(ops node:$Rn, node:$Rm),
   return N->getFlags().hasNoNaNs();
   }]>;
 
+def pmul_or_clmul : PatFrags<(ops node:$Rn, node:$Rm),
+                             [(int_aarch64_neon_pmul node:$Rn, node:$Rm),
+                             (clmul node:$Rn, node:$Rm)]>;
+
+
 //===----------------------------------------------------------------------===//
 
 //===----------------------------------------------------------------------===//
@@ -6062,7 +6067,7 @@ defm MLS      : SIMDThreeSameVectorBHSTied<1, 0b10010, "mls", null_frag>;
 
 defm MUL      : SIMDThreeSameVectorBHS<0, 0b10011, "mul", mul>;
 let isCommutable = 1 in
-defm PMUL     : SIMDThreeSameVectorB<1, 0b10011, "pmul", int_aarch64_neon_pmul>;
+defm PMUL     : SIMDThreeSameVectorB<1, 0b10011, "pmul", pmul_or_clmul>;
 defm SABA     : SIMDThreeSameVectorBHSTied<0, 0b01111, "saba",
       TriOpFrag<(add node:$LHS, (abds node:$MHS, node:$RHS))> >;
 defm SABD     : SIMDThreeSameVectorBHS<0,0b01110,"sabd", abds>;
diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index d290d73fd0373..1a46d63dfd6b2 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -602,6 +602,11 @@ def AArch64umulh : PatFrag<(ops node:$op1, node:$op2),
                            (AArch64umulh_p (SVEAnyPredicate), node:$op1, node:$op2)>;
 
 
+def AArch64pmul : PatFrags<(ops node:$op1, node:$op2),
+                           [(int_aarch64_sve_pmul node:$op1, node:$op2),
+                           (clmul node:$op1, node:$op2)]>;
+
+
 def AArch64bsl  : PatFrags<(ops node:$Op1, node:$Op2, node:$Op3),
                            [(AArch64bsp node:$Op3, node:$Op1, node:$Op2),
                             (or (and node:$Op1, node:$Op3), (and node:$Op2, (vnot node:$Op3)))]>;
@@ -3786,7 +3791,7 @@ let Predicates = [HasSVE2_or_SME] in {
   defm MUL_ZZZ    : sve2_int_mul<0b000,  "mul",   AArch64mul>;
   defm SMULH_ZZZ  : sve2_int_mul<0b010,  "smulh", AArch64smulh>;
   defm UMULH_ZZZ  : sve2_int_mul<0b011,  "umulh", AArch64umulh>;
-  defm PMUL_ZZZ   : sve2_int_mul_single<0b001, "pmul", int_aarch64_sve_pmul>;
+  defm PMUL_ZZZ   : sve2_int_mul_single<0b001, "pmul", AArch64pmul>;
 
   // SVE2 complex integer dot product (indexed)
   defm CDOT_ZZZI : sve2_cintx_dot_by_indexed_elem<"cdot", int_aarch64_sve_cdot_lane>;
diff --git a/llvm/test/CodeGen/AArch64/clmul.ll b/llvm/test/CodeGen/AArch64/clmul.ll
new file mode 100644
index 0000000000000..54a5b7e48a071
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/clmul.ll
@@ -0,0 +1,20 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=aarch64-linux-unknown-gnu %s -o - -mattr=+sve2 | FileCheck %s
+
+define <vscale x 16 x i8> @clmul_nxv16i8_sve(<vscale x 16 x i8> %x, <vscale x 16 x i8> %y) #0 {
+; CHECK-LABEL: clmul_nxv16i8_sve
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    pmul z0.b, z0.b, z1.b
+; CHECK-NEXT:    ret
+  %a = call <vscale x 16 x i8> @llvm.clmul.nxv16i8(<vscale x 16 x i8> %x, <vscale x 16 x i8> %y)
+  ret <vscale x 16 x i8> %a
+}
+
+define <16 x i8> @clmul_v16i8_neon(<16 x i8> %x, <16 x i8> %y) #0 {
+; CHECK-LABEL: clmul_v16i8_neon:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    pmul v0.16b, v0.16b, v1.16b
+; CHECK-NEXT:    ret
+  %a = call <16 x i8> @llvm.clmul.v16i8(<16 x i8> %x, <16 x i8> %y)
+  ret <16 x i8> %a
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/177323


More information about the llvm-commits mailing list