[llvm] [AArch64] Improve v1i64/v2i64 clmulh. (PR #196694)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Mon May 11 08:07:25 PDT 2026
https://github.com/topperc updated https://github.com/llvm/llvm-project/pull/196694
>From efbb8e2f8f525829a58516106db6f2ff8efa3663 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Fri, 8 May 2026 23:45:57 -0700
Subject: [PATCH 1/2] [AArch64] Improve v1i64/v2i64 clmulh.
We can use the pmull/pmull2 to commut the full product then take
the high half.
---
.../Target/AArch64/AArch64ISelLowering.cpp | 1 +
llvm/lib/Target/AArch64/AArch64InstrInfo.td | 9 ++++
llvm/test/CodeGen/AArch64/clmul-fixed.ll | 41 ++++++-------------
3 files changed, 22 insertions(+), 29 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index b53605e917e2b..69f399646a804 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -1533,6 +1533,7 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
if (Subtarget->hasAES()) {
setOperationAction(ISD::CLMUL, {MVT::i16, MVT::i32, MVT::i64}, Custom);
setOperationAction(ISD::CLMUL, {MVT::v1i64, MVT::v2i64}, Legal);
+ setOperationAction(ISD::CLMULH, {MVT::v1i64, MVT::v2i64}, Legal);
}
} else /* !isNeonAvailable */ {
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 6c20efffb1944..54c29ce2bcf04 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -7987,6 +7987,15 @@ let Predicates = [HasAES] in {
(i64 1),
(v2i64 (PMULLv2i64 $Rn, $Rm)),
(i64 0)))>;
+
+ def : Pat<(v1i64 (clmulh V64:$Rn, V64:$Rm)),
+ (EXTRACT_SUBREG (v2i64 (EXTv16i8 (v2i64 (PMULLv1i64 V64:$Rn, V64:$Rm)),
+ (v2i64 (PMULLv1i64 V64:$Rn, V64:$Rm)),
+ 8)), dsub)>;
+ def : Pat<(v2i64 (clmulh V128:$Rn, V128:$Rm)),
+ (ZIP2v2i64 (v2i64 (PMULLv1i64 (v1i64 (EXTRACT_SUBREG V128:$Rn, dsub)),
+ (v1i64 (EXTRACT_SUBREG V128:$Rm, dsub)))),
+ (v2i64 (PMULLv2i64 V128:$Rn, V128:$Rm)))>;
}
def : Pat<(v16i8 (vec_ins_or_scal_vec GPR32:$Rn)),
diff --git a/llvm/test/CodeGen/AArch64/clmul-fixed.ll b/llvm/test/CodeGen/AArch64/clmul-fixed.ll
index 70ddde74aafbc..56753dc33db96 100644
--- a/llvm/test/CodeGen/AArch64/clmul-fixed.ll
+++ b/llvm/test/CodeGen/AArch64/clmul-fixed.ll
@@ -6536,15 +6536,13 @@ define <2 x i64> @clmulr_v2i64_neon(<2 x i64> %a, <2 x i64> %b) nounwind {
;
; CHECK-AES-LABEL: clmulr_v2i64_neon:
; CHECK-AES: // %bb.0:
-; CHECK-AES-NEXT: rev64 v1.16b, v1.16b
-; CHECK-AES-NEXT: rev64 v0.16b, v0.16b
-; CHECK-AES-NEXT: rbit v1.16b, v1.16b
-; CHECK-AES-NEXT: rbit v0.16b, v0.16b
; CHECK-AES-NEXT: pmull2 v2.1q, v0.2d, v1.2d
; CHECK-AES-NEXT: pmull v0.1q, v0.1d, v1.1d
-; CHECK-AES-NEXT: mov v0.d[1], v2.d[0]
-; CHECK-AES-NEXT: rev64 v0.16b, v0.16b
-; CHECK-AES-NEXT: rbit v0.16b, v0.16b
+; CHECK-AES-NEXT: zip2 v1.2d, v0.2d, v2.2d
+; CHECK-AES-NEXT: mov v3.16b, v0.16b
+; CHECK-AES-NEXT: mov v3.d[1], v2.d[0]
+; CHECK-AES-NEXT: add v0.2d, v1.2d, v1.2d
+; CHECK-AES-NEXT: usra v0.2d, v3.2d, #63
; CHECK-AES-NEXT: ret
%a.ext = zext <2 x i64> %a to <2 x i128>
%b.ext = zext <2 x i64> %b to <2 x i128>
@@ -7015,13 +7013,10 @@ define <1 x i64> @clmulr_v1i64_neon(<1 x i64> %a, <1 x i64> %b) nounwind {
;
; CHECK-AES-LABEL: clmulr_v1i64_neon:
; CHECK-AES: // %bb.0:
-; CHECK-AES-NEXT: rev64 v1.8b, v1.8b
-; CHECK-AES-NEXT: rev64 v0.8b, v0.8b
-; CHECK-AES-NEXT: rbit v1.8b, v1.8b
-; CHECK-AES-NEXT: rbit v0.8b, v0.8b
-; CHECK-AES-NEXT: pmull v0.1q, v0.1d, v1.1d
-; CHECK-AES-NEXT: rev64 v0.8b, v0.8b
-; CHECK-AES-NEXT: rbit v0.8b, v0.8b
+; CHECK-AES-NEXT: pmull v1.1q, v0.1d, v1.1d
+; CHECK-AES-NEXT: ext v0.16b, v1.16b, v1.16b, #8
+; CHECK-AES-NEXT: shl d0, d0, #1
+; CHECK-AES-NEXT: usra d0, d1, #63
; CHECK-AES-NEXT: ret
%a.ext = zext <1 x i64> %a to <1 x i128>
%b.ext = zext <1 x i64> %b to <1 x i128>
@@ -8089,16 +8084,9 @@ define <2 x i64> @clmulh_v2i64_neon(<2 x i64> %a, <2 x i64> %b) nounwind {
;
; CHECK-AES-LABEL: clmulh_v2i64_neon:
; CHECK-AES: // %bb.0:
-; CHECK-AES-NEXT: rev64 v1.16b, v1.16b
-; CHECK-AES-NEXT: rev64 v0.16b, v0.16b
-; CHECK-AES-NEXT: rbit v1.16b, v1.16b
-; CHECK-AES-NEXT: rbit v0.16b, v0.16b
; CHECK-AES-NEXT: pmull2 v2.1q, v0.2d, v1.2d
; CHECK-AES-NEXT: pmull v0.1q, v0.1d, v1.1d
-; CHECK-AES-NEXT: mov v0.d[1], v2.d[0]
-; CHECK-AES-NEXT: rev64 v0.16b, v0.16b
-; CHECK-AES-NEXT: rbit v0.16b, v0.16b
-; CHECK-AES-NEXT: ushr v0.2d, v0.2d, #1
+; CHECK-AES-NEXT: zip2 v0.2d, v0.2d, v2.2d
; CHECK-AES-NEXT: ret
%a.ext = zext <2 x i64> %a to <2 x i128>
%b.ext = zext <2 x i64> %b to <2 x i128>
@@ -8570,14 +8558,9 @@ define <1 x i64> @clmulh_v1i64_neon(<1 x i64> %a, <1 x i64> %b) nounwind {
;
; CHECK-AES-LABEL: clmulh_v1i64_neon:
; CHECK-AES: // %bb.0:
-; CHECK-AES-NEXT: rev64 v1.8b, v1.8b
-; CHECK-AES-NEXT: rev64 v0.8b, v0.8b
-; CHECK-AES-NEXT: rbit v1.8b, v1.8b
-; CHECK-AES-NEXT: rbit v0.8b, v0.8b
; CHECK-AES-NEXT: pmull v0.1q, v0.1d, v1.1d
-; CHECK-AES-NEXT: rev64 v0.8b, v0.8b
-; CHECK-AES-NEXT: rbit v0.8b, v0.8b
-; CHECK-AES-NEXT: ushr d0, d0, #1
+; CHECK-AES-NEXT: ext v0.16b, v0.16b, v0.16b, #8
+; CHECK-AES-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-AES-NEXT: ret
%a.ext = zext <1 x i64> %a to <1 x i128>
%b.ext = zext <1 x i64> %b to <1 x i128>
>From bd6535b4f12f00ade51e1f1d1f393008563b22a6 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 11 May 2026 08:07:16 -0700
Subject: [PATCH 2/2] Update llvm/lib/Target/AArch64/AArch64InstrInfo.td
Co-authored-by: Matthew Devereau <matthew.devereau at arm.com>
---
llvm/lib/Target/AArch64/AArch64InstrInfo.td | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 54c29ce2bcf04..ab8d6e4bffa6c 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -7988,9 +7988,9 @@ let Predicates = [HasAES] in {
(v2i64 (PMULLv2i64 $Rn, $Rm)),
(i64 0)))>;
- def : Pat<(v1i64 (clmulh V64:$Rn, V64:$Rm)),
- (EXTRACT_SUBREG (v2i64 (EXTv16i8 (v2i64 (PMULLv1i64 V64:$Rn, V64:$Rm)),
- (v2i64 (PMULLv1i64 V64:$Rn, V64:$Rm)),
+ def : Pat<(clmulh v1i64:$Rn, v1i64:$Rm),
+ (EXTRACT_SUBREG (v2i64 (EXTv16i8 (v2i64 (PMULLv1i64 $Rn, $Rm)),
+ (v2i64 (PMULLv1i64 $Rn, $Rm)),
8)), dsub)>;
def : Pat<(v2i64 (clmulh V128:$Rn, V128:$Rm)),
(ZIP2v2i64 (v2i64 (PMULLv1i64 (v1i64 (EXTRACT_SUBREG V128:$Rn, dsub)),
More information about the llvm-commits
mailing list