[llvm] [RISCV] Change custom promotion of riscv_clmulh/r (PR #228846)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Oct 4 00:22:35 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Craig Topper (topperc)
<details>
<summary>Changes</summary>
Instead of using shl+shl+clmul(h/r)+srl, use and+and+clmul(h/r)+srl.
This matches type promotion of ISD::CLMUL(H/R). The ands may be
able to fold into loads or removed via known bits.
ISel will convert and+and+clmul to shl+shl+clmulh if the ands
aren't removed.
This leaves some regressions for clmulr that will be dealt with
in a follow up.
This is an alternative to #<!-- -->228669.
---
Patch is 56.39 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/228846.diff
3 Files Affected:
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+6-19)
- (modified) llvm/test/CodeGen/RISCV/clmulh.ll (+368)
- (modified) llvm/test/CodeGen/RISCV/clmulr.ll (+876-161)
``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 3892e62f715cf09..6c97594ad869ef3 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -18282,28 +18282,15 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
if (!Subtarget.is64Bit() || N->getValueType(0) != MVT::i32)
return;
- // Extend inputs to XLen, and shift by 32. This will add 64 trailing zeros
- // to the full 128-bit clmul result of multiplying two xlen values.
- // Perform clmulr or clmulh on the shifted values. Finally, extract the
- // upper 32 bits.
- //
- // The alternative is to mask the inputs to 32 bits and use clmul, but
- // that requires two shifts to mask each input without zext.w.
- // FIXME: If the inputs are known zero extended or could be freely
- // zero extended, the mask form would be better.
+ // Zero extend the inputs, use a clmul, then shift the result.
SDValue NewOp0 =
- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(1));
+ DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, N->getOperand(1));
SDValue NewOp1 =
- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(2));
- NewOp0 = DAG.getNode(ISD::SHL, DL, MVT::i64, NewOp0,
- DAG.getConstant(32, DL, MVT::i64));
- NewOp1 = DAG.getNode(ISD::SHL, DL, MVT::i64, NewOp1,
- DAG.getConstant(32, DL, MVT::i64));
- unsigned Opc =
- IntNo == Intrinsic::riscv_clmulh ? ISD::CLMULH : ISD::CLMULR;
- SDValue Res = DAG.getNode(Opc, DL, MVT::i64, NewOp0, NewOp1);
+ DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, N->getOperand(2));
+ unsigned ShAmt = IntNo == Intrinsic::riscv_clmulh ? 32 : 31;
+ SDValue Res = DAG.getNode(ISD::CLMUL, DL, MVT::i64, NewOp0, NewOp1);
Res = DAG.getNode(ISD::SRL, DL, MVT::i64, Res,
- DAG.getConstant(32, DL, MVT::i64));
+ DAG.getConstant(ShAmt, DL, MVT::i64));
Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res));
return;
}
diff --git a/llvm/test/CodeGen/RISCV/clmulh.ll b/llvm/test/CodeGen/RISCV/clmulh.ll
index 5c09f34444e730e..568c18f5a162f46 100644
--- a/llvm/test/CodeGen/RISCV/clmulh.ll
+++ b/llvm/test/CodeGen/RISCV/clmulh.ll
@@ -5,6 +5,8 @@
; RUN: llc -mtriple=riscv64 -mattr=+m -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,CHECK-M,RV64IM
; RUN: llc -mtriple=riscv32 -mattr=+m,+zbs -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,CHECK-ZBS,RV32IMZBS
; RUN: llc -mtriple=riscv64 -mattr=+m,+zbs -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,CHECK-ZBS,RV64IMZBS
+; RUN: llc -mtriple=riscv32 -mattr=+m,+zbc -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,CHECK-ZBC,RV32IMZBC
+; RUN: llc -mtriple=riscv64 -mattr=+m,+zbc -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,CHECK-ZBC,RV64IMZBC
; RUN: llc -mtriple=riscv32 -mattr=+m,+zvbc -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,CHECK-ZVBC,RV32IMZVBC
; RUN: llc -mtriple=riscv64 -mattr=+m,+zvbc -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,CHECK-ZVBC,RV64IMZVBC
@@ -78,6 +80,14 @@ define i4 @clmulh_i4(i4 %a, i4 %b) nounwind {
; CHECK-ZBS-NEXT: srli a0, a0, 4
; CHECK-ZBS-NEXT: ret
;
+; CHECK-ZBC-LABEL: clmulh_i4:
+; CHECK-ZBC: # %bb.0:
+; CHECK-ZBC-NEXT: andi a1, a1, 15
+; CHECK-ZBC-NEXT: andi a0, a0, 15
+; CHECK-ZBC-NEXT: clmul a0, a0, a1
+; CHECK-ZBC-NEXT: srli a0, a0, 4
+; CHECK-ZBC-NEXT: ret
+;
; RV32IMZVBC-LABEL: clmulh_i4:
; RV32IMZVBC: # %bb.0:
; RV32IMZVBC-NEXT: andi a2, a1, 4
@@ -189,6 +199,14 @@ define i4 @clmulh_i4_bitreverse(i4 %a, i4 %b) nounwind {
; CHECK-ZBS-NEXT: srli a0, a0, 4
; CHECK-ZBS-NEXT: ret
;
+; CHECK-ZBC-LABEL: clmulh_i4_bitreverse:
+; CHECK-ZBC: # %bb.0:
+; CHECK-ZBC-NEXT: andi a1, a1, 15
+; CHECK-ZBC-NEXT: andi a0, a0, 15
+; CHECK-ZBC-NEXT: clmul a0, a0, a1
+; CHECK-ZBC-NEXT: srli a0, a0, 4
+; CHECK-ZBC-NEXT: ret
+;
; RV32IMZVBC-LABEL: clmulh_i4_bitreverse:
; RV32IMZVBC: # %bb.0:
; RV32IMZVBC-NEXT: andi a2, a1, 4
@@ -388,6 +406,14 @@ define i8 @clmulh_i8(i8 %a, i8 %b) nounwind {
; CHECK-ZBS-NEXT: srli a0, a0, 8
; CHECK-ZBS-NEXT: ret
;
+; CHECK-ZBC-LABEL: clmulh_i8:
+; CHECK-ZBC: # %bb.0:
+; CHECK-ZBC-NEXT: zext.b a1, a1
+; CHECK-ZBC-NEXT: zext.b a0, a0
+; CHECK-ZBC-NEXT: clmul a0, a0, a1
+; CHECK-ZBC-NEXT: srli a0, a0, 8
+; CHECK-ZBC-NEXT: ret
+;
; RV32IMZVBC-LABEL: clmulh_i8:
; RV32IMZVBC: # %bb.0:
; RV32IMZVBC-NEXT: zext.b a0, a0
@@ -927,6 +953,16 @@ define i16 @clmulh_i16(i16 %a, i16 %b) nounwind {
; RV64IMZBS-NEXT: srli a0, a0, 16
; RV64IMZBS-NEXT: ret
;
+; CHECK-ZBC-LABEL: clmulh_i16:
+; CHECK-ZBC: # %bb.0:
+; CHECK-ZBC-NEXT: lui a2, 16
+; CHECK-ZBC-NEXT: addi a2, a2, -1
+; CHECK-ZBC-NEXT: and a1, a1, a2
+; CHECK-ZBC-NEXT: and a0, a0, a2
+; CHECK-ZBC-NEXT: clmul a0, a0, a1
+; CHECK-ZBC-NEXT: srli a0, a0, 16
+; CHECK-ZBC-NEXT: ret
+;
; RV32IMZVBC-LABEL: clmulh_i16:
; RV32IMZVBC: # %bb.0:
; RV32IMZVBC-NEXT: addi sp, sp, -16
@@ -1994,6 +2030,19 @@ define i32 @clmulh_i32(i32 %a, i32 %b) nounwind {
; RV64IMZBS-NEXT: addi sp, sp, 32
; RV64IMZBS-NEXT: ret
;
+; RV32IMZBC-LABEL: clmulh_i32:
+; RV32IMZBC: # %bb.0:
+; RV32IMZBC-NEXT: clmulh a0, a0, a1
+; RV32IMZBC-NEXT: ret
+;
+; RV64IMZBC-LABEL: clmulh_i32:
+; RV64IMZBC: # %bb.0:
+; RV64IMZBC-NEXT: slli a1, a1, 32
+; RV64IMZBC-NEXT: slli a0, a0, 32
+; RV64IMZBC-NEXT: clmulh a0, a0, a1
+; RV64IMZBC-NEXT: srli a0, a0, 32
+; RV64IMZBC-NEXT: ret
+;
; RV32IMZVBC-LABEL: clmulh_i32:
; RV32IMZVBC: # %bb.0:
; RV32IMZVBC-NEXT: addi sp, sp, -48
@@ -2342,6 +2391,16 @@ define void @commutative_clmulh_i8(i8 %x, i8 %y, ptr %p0, ptr %p1) {
; CHECK-ZBS-NEXT: sb a0, 0(a3)
; CHECK-ZBS-NEXT: ret
;
+; CHECK-ZBC-LABEL: commutative_clmulh_i8:
+; CHECK-ZBC: # %bb.0:
+; CHECK-ZBC-NEXT: zext.b a0, a0
+; CHECK-ZBC-NEXT: zext.b a1, a1
+; CHECK-ZBC-NEXT: clmul a0, a1, a0
+; CHECK-ZBC-NEXT: srli a0, a0, 8
+; CHECK-ZBC-NEXT: sb a0, 0(a2)
+; CHECK-ZBC-NEXT: sb a0, 0(a3)
+; CHECK-ZBC-NEXT: ret
+;
; RV32IMZVBC-LABEL: commutative_clmulh_i8:
; RV32IMZVBC: # %bb.0:
; RV32IMZVBC-NEXT: zext.b a1, a1
@@ -8299,6 +8358,315 @@ define void @commutative_clmulh_v2i64(<2 x i64> %x, <2 x i64> %y, ptr %p0, ptr %
; RV64IMZBS-NEXT: addi sp, sp, 128
; RV64IMZBS-NEXT: ret
;
+; RV32IMZBC-LABEL: commutative_clmulh_v2i64:
+; RV32IMZBC: # %bb.0:
+; RV32IMZBC-NEXT: addi sp, sp, -16
+; RV32IMZBC-NEXT: sw s0, 12(sp) # 4-byte Folded Spill
+; RV32IMZBC-NEXT: sw s1, 8(sp) # 4-byte Folded Spill
+; RV32IMZBC-NEXT: sw s2, 4(sp) # 4-byte Folded Spill
+; RV32IMZBC-NEXT: sw s3, 0(sp) # 4-byte Folded Spill
+; RV32IMZBC-NEXT: lw a4, 4(a0)
+; RV32IMZBC-NEXT: lui a6, 16
+; RV32IMZBC-NEXT: lw t3, 8(a0)
+; RV32IMZBC-NEXT: lw a5, 12(a0)
+; RV32IMZBC-NEXT: lw t5, 0(a1)
+; RV32IMZBC-NEXT: addi a7, a6, -256
+; RV32IMZBC-NEXT: srli a6, a4, 8
+; RV32IMZBC-NEXT: srli t0, a4, 24
+; RV32IMZBC-NEXT: and t1, a4, a7
+; RV32IMZBC-NEXT: and a6, a6, a7
+; RV32IMZBC-NEXT: slli t1, t1, 8
+; RV32IMZBC-NEXT: slli t2, a4, 24
+; RV32IMZBC-NEXT: or a6, a6, t0
+; RV32IMZBC-NEXT: or t0, t2, t1
+; RV32IMZBC-NEXT: or a6, t0, a6
+; RV32IMZBC-NEXT: lui t0, 61681
+; RV32IMZBC-NEXT: srli t1, a6, 4
+; RV32IMZBC-NEXT: addi t0, t0, -241
+; RV32IMZBC-NEXT: and t1, t1, t0
+; RV32IMZBC-NEXT: and a6, a6, t0
+; RV32IMZBC-NEXT: slli a6, a6, 4
+; RV32IMZBC-NEXT: lui t2, 209715
+; RV32IMZBC-NEXT: or a6, t1, a6
+; RV32IMZBC-NEXT: addi t1, t2, 819
+; RV32IMZBC-NEXT: srli t2, a6, 2
+; RV32IMZBC-NEXT: and a6, a6, t1
+; RV32IMZBC-NEXT: and t2, t2, t1
+; RV32IMZBC-NEXT: slli a6, a6, 2
+; RV32IMZBC-NEXT: lw t6, 0(a0)
+; RV32IMZBC-NEXT: or s0, t2, a6
+; RV32IMZBC-NEXT: lw a6, 4(a1)
+; RV32IMZBC-NEXT: lw t4, 8(a1)
+; RV32IMZBC-NEXT: lw a0, 12(a1)
+; RV32IMZBC-NEXT: srli s1, s0, 1
+; RV32IMZBC-NEXT: lui t2, 349525
+; RV32IMZBC-NEXT: srli a1, t5, 8
+; RV32IMZBC-NEXT: and a1, a1, a7
+; RV32IMZBC-NEXT: srli s2, t5, 24
+; RV32IMZBC-NEXT: or s2, a1, s2
+; RV32IMZBC-NEXT: and a1, t5, a7
+; RV32IMZBC-NEXT: slli s3, a1, 8
+; RV32IMZBC-NEXT: slli t5, t5, 24
+; RV32IMZBC-NEXT: addi a1, t2, 1365
+; RV32IMZBC-NEXT: or t5, t5, s3
+; RV32IMZBC-NEXT: and s1, s1, a1
+; RV32IMZBC-NEXT: or t5, t5, s2
+; RV32IMZBC-NEXT: srli s2, t5, 4
+; RV32IMZBC-NEXT: and t5, t5, t0
+; RV32IMZBC-NEXT: and s2, s2, t0
+; RV32IMZBC-NEXT: slli t5, t5, 4
+; RV32IMZBC-NEXT: and s0, s0, a1
+; RV32IMZBC-NEXT: or t5, s2, t5
+; RV32IMZBC-NEXT: srli s2, t5, 2
+; RV32IMZBC-NEXT: and t5, t5, t1
+; RV32IMZBC-NEXT: and s2, s2, t1
+; RV32IMZBC-NEXT: slli t5, t5, 2
+; RV32IMZBC-NEXT: slli s0, s0, 1
+; RV32IMZBC-NEXT: or s2, s2, t5
+; RV32IMZBC-NEXT: or t5, s1, s0
+; RV32IMZBC-NEXT: srli s0, s2, 1
+; RV32IMZBC-NEXT: and s0, s0, a1
+; RV32IMZBC-NEXT: srli s1, t6, 8
+; RV32IMZBC-NEXT: and s1, s1, a7
+; RV32IMZBC-NEXT: srli s3, t6, 24
+; RV32IMZBC-NEXT: or s1, s1, s3
+; RV32IMZBC-NEXT: and s3, t6, a7
+; RV32IMZBC-NEXT: slli s3, s3, 8
+; RV32IMZBC-NEXT: slli t6, t6, 24
+; RV32IMZBC-NEXT: and s2, s2, a1
+; RV32IMZBC-NEXT: or t6, t6, s3
+; RV32IMZBC-NEXT: slli s2, s2, 1
+; RV32IMZBC-NEXT: or t6, t6, s1
+; RV32IMZBC-NEXT: srli s1, t6, 4
+; RV32IMZBC-NEXT: and t6, t6, t0
+; RV32IMZBC-NEXT: and s1, s1, t0
+; RV32IMZBC-NEXT: slli t6, t6, 4
+; RV32IMZBC-NEXT: or s0, s0, s2
+; RV32IMZBC-NEXT: or t6, s1, t6
+; RV32IMZBC-NEXT: srli s1, t6, 2
+; RV32IMZBC-NEXT: and t6, t6, t1
+; RV32IMZBC-NEXT: and s1, s1, t1
+; RV32IMZBC-NEXT: slli t6, t6, 2
+; RV32IMZBC-NEXT: or t6, s1, t6
+; RV32IMZBC-NEXT: srli s1, a6, 8
+; RV32IMZBC-NEXT: and s1, s1, a7
+; RV32IMZBC-NEXT: srli s2, a6, 24
+; RV32IMZBC-NEXT: or s1, s1, s2
+; RV32IMZBC-NEXT: and s2, a6, a7
+; RV32IMZBC-NEXT: slli s2, s2, 8
+; RV32IMZBC-NEXT: slli s3, a6, 24
+; RV32IMZBC-NEXT: or s2, s3, s2
+; RV32IMZBC-NEXT: srli s3, t6, 1
+; RV32IMZBC-NEXT: and s3, s3, a1
+; RV32IMZBC-NEXT: or s1, s2, s1
+; RV32IMZBC-NEXT: srli s2, s1, 4
+; RV32IMZBC-NEXT: and s1, s1, t0
+; RV32IMZBC-NEXT: and s2, s2, t0
+; RV32IMZBC-NEXT: slli s1, s1, 4
+; RV32IMZBC-NEXT: and t6, t6, a1
+; RV32IMZBC-NEXT: or s1, s2, s1
+; RV32IMZBC-NEXT: srli s2, s1, 2
+; RV32IMZBC-NEXT: and s1, s1, t1
+; RV32IMZBC-NEXT: and s2, s2, t1
+; RV32IMZBC-NEXT: slli s1, s1, 2
+; RV32IMZBC-NEXT: slli t6, t6, 1
+; RV32IMZBC-NEXT: or s1, s2, s1
+; RV32IMZBC-NEXT: srli s2, s1, 1
+; RV32IMZBC-NEXT: and s1, s1, a1
+; RV32IMZBC-NEXT: and s2, s2, a1
+; RV32IMZBC-NEXT: slli s1, s1, 1
+; RV32IMZBC-NEXT: or t6, s3, t6
+; RV32IMZBC-NEXT: or s1, s2, s1
+; RV32IMZBC-NEXT: clmul s0, s0, t5
+; RV32IMZBC-NEXT: clmul t6, s1, t6
+; RV32IMZBC-NEXT: clmulh t5, s1, t5
+; RV32IMZBC-NEXT: xor t6, t6, s0
+; RV32IMZBC-NEXT: xor t5, t5, t6
+; RV32IMZBC-NEXT: srli t6, t5, 8
+; RV32IMZBC-NEXT: and t6, t6, a7
+; RV32IMZBC-NEXT: srli s0, t5, 24
+; RV32IMZBC-NEXT: and s1, t5, a7
+; RV32IMZBC-NEXT: slli t5, t5, 24
+; RV32IMZBC-NEXT: slli s1, s1, 8
+; RV32IMZBC-NEXT: or t6, t6, s0
+; RV32IMZBC-NEXT: or t5, t5, s1
+; RV32IMZBC-NEXT: or t5, t5, t6
+; RV32IMZBC-NEXT: srli t6, t5, 4
+; RV32IMZBC-NEXT: and t5, t5, t0
+; RV32IMZBC-NEXT: and t6, t6, t0
+; RV32IMZBC-NEXT: slli t5, t5, 4
+; RV32IMZBC-NEXT: or t5, t6, t5
+; RV32IMZBC-NEXT: srli t6, t5, 2
+; RV32IMZBC-NEXT: and t6, t6, t1
+; RV32IMZBC-NEXT: and t5, t5, t1
+; RV32IMZBC-NEXT: srli s0, a5, 8
+; RV32IMZBC-NEXT: slli t5, t5, 2
+; RV32IMZBC-NEXT: and s0, s0, a7
+; RV32IMZBC-NEXT: srli s1, a5, 24
+; RV32IMZBC-NEXT: and s2, a5, a7
+; RV32IMZBC-NEXT: slli s2, s2, 8
+; RV32IMZBC-NEXT: slli s3, a5, 24
+; RV32IMZBC-NEXT: or s0, s0, s1
+; RV32IMZBC-NEXT: or s1, s3, s2
+; RV32IMZBC-NEXT: or t5, t6, t5
+; RV32IMZBC-NEXT: or s0, s1, s0
+; RV32IMZBC-NEXT: srli t6, s0, 4
+; RV32IMZBC-NEXT: and s0, s0, t0
+; RV32IMZBC-NEXT: and s1, t6, t0
+; RV32IMZBC-NEXT: slli s0, s0, 4
+; RV32IMZBC-NEXT: srli t6, t5, 1
+; RV32IMZBC-NEXT: or s0, s1, s0
+; RV32IMZBC-NEXT: srli s1, s0, 2
+; RV32IMZBC-NEXT: and s0, s0, t1
+; RV32IMZBC-NEXT: and s1, s1, t1
+; RV32IMZBC-NEXT: slli s0, s0, 2
+; RV32IMZBC-NEXT: or s0, s1, s0
+; RV32IMZBC-NEXT: srli s1, t4, 8
+; RV32IMZBC-NEXT: and s1, s1, a7
+; RV32IMZBC-NEXT: srli s2, t4, 24
+; RV32IMZBC-NEXT: or s1, s1, s2
+; RV32IMZBC-NEXT: and s2, t4, a7
+; RV32IMZBC-NEXT: slli s2, s2, 8
+; RV32IMZBC-NEXT: slli t4, t4, 24
+; RV32IMZBC-NEXT: srli s3, s0, 1
+; RV32IMZBC-NEXT: or t4, t4, s2
+; RV32IMZBC-NEXT: and s2, s3, a1
+; RV32IMZBC-NEXT: or t4, t4, s1
+; RV32IMZBC-NEXT: srli s1, t4, 4
+; RV32IMZBC-NEXT: and t4, t4, t0
+; RV32IMZBC-NEXT: and s1, s1, t0
+; RV32IMZBC-NEXT: slli t4, t4, 4
+; RV32IMZBC-NEXT: and s0, s0, a1
+; RV32IMZBC-NEXT: or t4, s1, t4
+; RV32IMZBC-NEXT: srli s1, t4, 2
+; RV32IMZBC-NEXT: and t4, t4, t1
+; RV32IMZBC-NEXT: and s1, s1, t1
+; RV32IMZBC-NEXT: slli t4, t4, 2
+; RV32IMZBC-NEXT: slli s0, s0, 1
+; RV32IMZBC-NEXT: or s1, s1, t4
+; RV32IMZBC-NEXT: or t4, s2, s0
+; RV32IMZBC-NEXT: srli s0, s1, 1
+; RV32IMZBC-NEXT: and s0, s0, a1
+; RV32IMZBC-NEXT: srli s2, t3, 8
+; RV32IMZBC-NEXT: and s2, s2, a7
+; RV32IMZBC-NEXT: srli s3, t3, 24
+; RV32IMZBC-NEXT: or s2, s2, s3
+; RV32IMZBC-NEXT: and s3, t3, a7
+; RV32IMZBC-NEXT: slli s3, s3, 8
+; RV32IMZBC-NEXT: slli t3, t3, 24
+; RV32IMZBC-NEXT: and s1, s1, a1
+; RV32IMZBC-NEXT: or t3, t3, s3
+; RV32IMZBC-NEXT: slli s1, s1, 1
+; RV32IMZBC-NEXT: or t3, t3, s2
+; RV32IMZBC-NEXT: srli s2, t3, 4
+; RV32IMZBC-NEXT: and t3, t3, t0
+; RV32IMZBC-NEXT: and s2, s2, t0
+; RV32IMZBC-NEXT: slli t3, t3, 4
+; RV32IMZBC-NEXT: or s0, s0, s1
+; RV32IMZBC-NEXT: or t3, s2, t3
+; RV32IMZBC-NEXT: srli s1, t3, 2
+; RV32IMZBC-NEXT: and t3, t3, t1
+; RV32IMZBC-NEXT: and s1, s1, t1
+; RV32IMZBC-NEXT: slli t3, t3, 2
+; RV32IMZBC-NEXT: or t3, s1, t3
+; RV32IMZBC-NEXT: srli s1, a0, 8
+; RV32IMZBC-NEXT: and s1, s1, a7
+; RV32IMZBC-NEXT: srli s2, a0, 24
+; RV32IMZBC-NEXT: or s1, s1, s2
+; RV32IMZBC-NEXT: and s2, a0, a7
+; RV32IMZBC-NEXT: slli s2, s2, 8
+; RV32IMZBC-NEXT: slli s3, a0, 24
+; RV32IMZBC-NEXT: or s2, s3, s2
+; RV32IMZBC-NEXT: srli s3, t3, 1
+; RV32IMZBC-NEXT: and s3, s3, a1
+; RV32IMZBC-NEXT: or s1, s2, s1
+; RV32IMZBC-NEXT: srli s2, s1, 4
+; RV32IMZBC-NEXT: and s1, s1, t0
+; RV32IMZBC-NEXT: and s2, s2, t0
+; RV32IMZBC-NEXT: slli s1, s1, 4
+; RV32IMZBC-NEXT: and t3, t3, a1
+; RV32IMZBC-NEXT: or s1, s2, s1
+; RV32IMZBC-NEXT: srli s2, s1, 2
+; RV32IMZBC-NEXT: and s1, s1, t1
+; RV32IMZBC-NEXT: and s2, s2, t1
+; RV32IMZBC-NEXT: slli s1, s1, 2
+; RV32IMZBC-NEXT: slli t3, t3, 1
+; RV32IMZBC-NEXT: or s1, s2, s1
+; RV32IMZBC-NEXT: srli s2, s1, 1
+; RV32IMZBC-NEXT: and s1, s1, a1
+; RV32IMZBC-NEXT: and s2, s2, a1
+; RV32IMZBC-NEXT: slli s1, s1, 1
+; RV32IMZBC-NEXT: or t3, s3, t3
+; RV32IMZBC-NEXT: or s1, s2, s1
+; RV32IMZBC-NEXT: clmul s0, s0, t4
+; RV32IMZBC-NEXT: clmul t3, s1, t3
+; RV32IMZBC-NEXT: addi t2, t2, 1364
+; RV32IMZBC-NEXT: clmulh t4, s1, t4
+; RV32IMZBC-NEXT: and t6, t6, t2
+; RV32IMZBC-NEXT: xor t3, t3, s0
+; RV32IMZBC-NEXT: and t5, t5, a1
+; RV32IMZBC-NEXT: xor t3, t4, t3
+; RV32IMZBC-NEXT: slli t5, t5, 1
+; RV32IMZBC-NEXT: srli t4, t3, 8
+; RV32IMZBC-NEXT: or t5, t6, t5
+; RV32IMZBC-NEXT: and t4, t4, a7
+; RV32IMZBC-NEXT: srli t6, t3, 24
+; RV32IMZBC-NEXT: and a7, t3, a7
+; RV32IMZBC-NEXT: slli t3, t3, 24
+; RV32IMZBC-NEXT: slli a7, a7, 8
+; RV32IMZBC-NEXT: or t4, t4, t6
+; RV32IMZBC-NEXT: or a7, t3, a7
+; RV32IMZBC-NEXT: srli t3, t5, 1
+; RV32IMZBC-NEXT: or a7, a7, t4
+; RV32IMZBC-NEXT: srli t4, a7, 4
+; RV32IMZBC-NEXT: and a7, a7, t0
+; RV32IMZBC-NEXT: and t0, t4, t0
+; RV32IMZBC-NEXT: slli a7, a7, 4
+; RV32IMZBC-NEXT: clmulr t4, a6, a4
+; RV32IMZBC-NEXT: or a7, t0, a7
+; RV32IMZBC-NEXT: srli t0, a7, 2
+; RV32IMZBC-NEXT: and a7, a7, t1
+; RV32IMZBC-NEXT: and t0, t0, t1
+; RV32IMZBC-NEXT: slli a7, a7, 2
+; RV32IMZBC-NEXT: slli t4, t4, 31
+; RV32IMZBC-NEXT: or a7, t0, a7
+; RV32IMZBC-NEXT: srli t0, a7, 1
+; RV32IMZBC-NEXT: and a1, a7, a1
+; RV32IMZBC-NEXT: and a7, t0, t2
+; RV32IMZBC-NEXT: slli a1, a1, 1
+; RV32IMZBC-NEXT: or a1, a7, a1
+; RV32IMZBC-NEXT: clmulr a7, a0, a5
+; RV32IMZBC-NEXT: or t0, t3, t4
+; RV32IMZBC-NEXT: srli a1, a1, 1
+; RV32IMZBC-NEXT: slli a7, a7, 31
+; RV32IMZBC-NEXT: clmulh a4, a6, a4
+; RV32IMZBC-NEXT: or a1, a1, a7
+; RV32IMZBC-NEXT: clmulh a0, a0, a5
+; RV32IMZBC-NEXT: sw t0, 0(a2)
+; RV32IMZBC-NEXT: sw a4, 4(a2)
+; RV32IMZBC-NEXT: sw a1, 8(a2)
+; RV32IMZBC-NEXT: sw a0, 12(a2)
+; RV32IMZBC-NEXT: sw t0, 0(a3)
+; RV32IMZBC-NEXT: sw a4, 4(a3)
+; RV32IMZBC-NEXT: sw a1, 8(a3)
+; RV32IMZBC-NEXT: sw a0, 12(a3)
+; RV32IMZBC-NEXT: lw s0, 12(sp) # 4-byte Folded Reload
+; RV32IMZBC-NEXT: lw s1, 8(sp) # 4-byte Folded Reload
+; RV32IMZBC-NEXT: lw s2, 4(sp) # 4-byte Folded Reload
+; RV32IMZBC-NEXT: lw s3, 0(sp) # 4-byte Folded Reload
+; RV32IMZBC-NEXT: addi sp, sp, 16
+; RV32IMZBC-NEXT: ret
+;
+; RV64IMZBC-LABEL: commutative_clmulh_v2i64:
+; RV64IMZBC: # %bb.0:
+; RV64IMZBC-NEXT: clmulh a0, a2, a0
+; RV64IMZBC-NEXT: clmulh a1, a3, a1
+; RV64IMZBC-NEXT: sd a0, 0(a4)
+; RV64IMZBC-NEXT: sd a1, 8(a4)
+; RV64IMZBC-NEXT: sd a0, 0(a5)
+; RV64IMZBC-NEXT: sd a1, 8(a5)
+; RV64IMZBC-NEXT: ret
+;
; CHECK-ZVBC-LABEL: commutative_clmulh_v2i64:
; CHECK-ZVBC: # %bb.0:
; CHECK-ZVBC-NEXT: vsetivli zero, 2, e64, m2, ta, ma
diff --git a/llvm/test/CodeGen/RISCV/clmulr.ll b/llvm/test/CodeGen/RISCV/clmulr.ll
index 229ce8df00e1597..23cf4093d99bf52 100644
--- a/llvm/test/CodeGen/RISCV/clmulr.ll
+++ b/llvm/test/CodeGen/RISCV/clmulr.ll
@@ -5,35 +5,101 @@
; RUN: llc -mtriple=riscv64 -mattr=+m -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,CHECK-M,RV64IM
; RUN: llc -mtriple=riscv32 -mattr=+m,+zbs -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,CHECK-ZBS,RV32IMZBS
; RUN: llc -mtriple=riscv64 -mattr=+m,+zbs -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,CHECK-ZBS,RV64IMZBS
+; RUN: llc -mtriple=riscv32 -mattr=+m,+zbc -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,CHECK-ZBC,RV32IMZBC
+; RUN: llc -mtriple=riscv64 -mattr=+m,+zbc -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,CHECK-ZBC,RV64IMZBC
define i4 @clmulr_i4(i4 %a, i4 %b) nounwind {
-; CHECK-LABEL: clmulr_i4:
-; CHECK: # %bb.0:
-; CHECK-NEXT: andi a0, a0, 15
-; CHECK-NEXT: andi a2, a1, 2
-; CHECK-NEXT: andi a3, a1, 1
-; CHECK-NEXT: slli a4, a0, 1
-; CHECK-NEXT: seqz a2, a2
-; CHECK-NEXT: seqz a3, a3
-; CHECK-NEXT: addi a2, a2, -1
-; CHECK-NEXT: addi a3, a3, -1
-; CHECK-NEXT: and a2, a2, a4
-; CHECK-NEXT: and a3, a3, a0
-; CHECK-NEXT: slli a4, a0, 2
-; CHECK-NEXT: andi a5, a1, 4
-; CHECK-NEXT: seqz a5, a5
-; CHECK-NEXT: andi a1, a1, 8
-; CHECK-NEXT: addi a5, a5, -1
-; CHECK-NEXT: seqz a1, a1
-; CHECK-NEXT: slli a0, a0, 3
-; CHECK-NEXT: addi a1, a1, -1
-; CHECK-NEXT: and a4, a5, a4
-; CHECK-NEXT: and a0, a1, a0
-; CHECK-NEXT: xor a2, a3, a2
-; CHECK-NEXT: xor a0, a4, a0
-; CHECK-NEXT: xor a0, a2, a0
-; CHECK-NEXT: srli a0, a0, 3
-; CHECK-NEXT: ret
+; CHECK-I-LABEL: clmulr_i4:
+; CHECK-I: # %bb.0:
+; CHECK-I-NEXT: andi a0, a0, 15
+; CHECK-I-NEXT: andi a2, a1, 2
+; CHECK-I-NEXT: andi a3, a1, 1
+; CHECK-I-NEXT: slli a4, a0, 1
+; CHECK-I-NEXT: seqz a2, a2
+; CHECK-I-NEXT: seqz a3, a3
+; CHECK-I-NEXT: addi a2, a2, -1
+; CHECK-I-NEXT: addi a3, a3, -1
+; CHECK-I-NEXT: and a2, a2, a4
+; CHECK-I-NEXT: ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/228846
More information about the llvm-commits
mailing list