[clang] [llvm] [RISCV] Replace riscv.clmul intrinsic with llvm.clmul (PR #178092)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 26 16:49:47 PST 2026
https://github.com/topperc created https://github.com/llvm/llvm-project/pull/178092
I did not replace riscv.clmulh/clmulr since those require a multiple instruction pattern match. I wanted to ensure that -O0 will select the correct instructions without relying on combines.
>From f59a877ea798f06f6f033c348a6e28e229d7a4c2 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 26 Jan 2026 16:39:58 -0800
Subject: [PATCH] [RISCV] Replace riscv.clmul intrinsic with llvm.clmul
I did not replace riscv.clmulh/clmulr since those require a
multiple instruction pattern match. I wanted to ensure that
-O0 will select the correct instructions without relying on
combines.
---
clang/lib/CodeGen/TargetBuiltins/RISCV.cpp | 2 +-
clang/test/CodeGen/RISCV/rvb-intrinsics/zbc.c | 6 +++---
clang/test/CodeGen/RISCV/rvb-intrinsics/zbkc.c | 6 +++---
llvm/include/llvm/IR/IntrinsicsRISCV.td | 1 -
llvm/lib/IR/AutoUpgrade.cpp | 8 ++++++++
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 15 ---------------
llvm/test/CodeGen/RISCV/rv32zbc-zbkc-intrinsic.ll | 1 +
llvm/test/CodeGen/RISCV/rv64zbc-zbkc-intrinsic.ll | 2 ++
8 files changed, 18 insertions(+), 23 deletions(-)
diff --git a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
index 2e11037f0dcd0..eec6d49334f5f 100644
--- a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
@@ -1155,7 +1155,7 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID,
// Zbc
case RISCV::BI__builtin_riscv_clmul_32:
case RISCV::BI__builtin_riscv_clmul_64:
- ID = Intrinsic::riscv_clmul;
+ ID = Intrinsic::clmul;
break;
case RISCV::BI__builtin_riscv_clmulh_32:
case RISCV::BI__builtin_riscv_clmulh_64:
diff --git a/clang/test/CodeGen/RISCV/rvb-intrinsics/zbc.c b/clang/test/CodeGen/RISCV/rvb-intrinsics/zbc.c
index 93db3a482ef2b..db6e5efe87fbf 100644
--- a/clang/test/CodeGen/RISCV/rvb-intrinsics/zbc.c
+++ b/clang/test/CodeGen/RISCV/rvb-intrinsics/zbc.c
@@ -11,7 +11,7 @@
#if __riscv_xlen == 64
// RV64ZBC-LABEL: @clmul_64(
// RV64ZBC-NEXT: entry:
-// RV64ZBC-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.clmul.i64(i64 [[A:%.*]], i64 [[B:%.*]])
+// RV64ZBC-NEXT: [[TMP0:%.*]] = call i64 @llvm.clmul.i64(i64 [[A:%.*]], i64 [[B:%.*]])
// RV64ZBC-NEXT: ret i64 [[TMP0]]
//
uint64_t clmul_64(uint64_t a, uint64_t b) {
@@ -39,12 +39,12 @@ uint64_t clmulr_64(uint64_t a, uint64_t b) {
// RV32ZBC-LABEL: @clmul_32(
// RV32ZBC-NEXT: entry:
-// RV32ZBC-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.clmul.i32(i32 [[A:%.*]], i32 [[B:%.*]])
+// RV32ZBC-NEXT: [[TMP0:%.*]] = call i32 @llvm.clmul.i32(i32 [[A:%.*]], i32 [[B:%.*]])
// RV32ZBC-NEXT: ret i32 [[TMP0]]
//
// RV64ZBC-LABEL: @clmul_32(
// RV64ZBC-NEXT: entry:
-// RV64ZBC-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.clmul.i32(i32 [[A:%.*]], i32 [[B:%.*]])
+// RV64ZBC-NEXT: [[TMP0:%.*]] = call i32 @llvm.clmul.i32(i32 [[A:%.*]], i32 [[B:%.*]])
// RV64ZBC-NEXT: ret i32 [[TMP0]]
//
uint32_t clmul_32(uint32_t a, uint32_t b) {
diff --git a/clang/test/CodeGen/RISCV/rvb-intrinsics/zbkc.c b/clang/test/CodeGen/RISCV/rvb-intrinsics/zbkc.c
index 38d168d4f6334..cc16a994787c6 100644
--- a/clang/test/CodeGen/RISCV/rvb-intrinsics/zbkc.c
+++ b/clang/test/CodeGen/RISCV/rvb-intrinsics/zbkc.c
@@ -11,7 +11,7 @@
#if __riscv_xlen == 64
// RV64ZBKC-LABEL: @clmul_64(
// RV64ZBKC-NEXT: entry:
-// RV64ZBKC-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.clmul.i64(i64 [[A:%.*]], i64 [[B:%.*]])
+// RV64ZBKC-NEXT: [[TMP0:%.*]] = call i64 @llvm.clmul.i64(i64 [[A:%.*]], i64 [[B:%.*]])
// RV64ZBKC-NEXT: ret i64 [[TMP0]]
//
uint64_t clmul_64(uint64_t a, uint64_t b) {
@@ -30,12 +30,12 @@ uint64_t clmulh_64(uint64_t a, uint64_t b) {
// RV32ZBKC-LABEL: @clmul_32(
// RV32ZBKC-NEXT: entry:
-// RV32ZBKC-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.clmul.i32(i32 [[A:%.*]], i32 [[B:%.*]])
+// RV32ZBKC-NEXT: [[TMP0:%.*]] = call i32 @llvm.clmul.i32(i32 [[A:%.*]], i32 [[B:%.*]])
// RV32ZBKC-NEXT: ret i32 [[TMP0]]
//
// RV64ZBKC-LABEL: @clmul_32(
// RV64ZBKC-NEXT: entry:
-// RV64ZBKC-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.clmul.i32(i32 [[A:%.*]], i32 [[B:%.*]])
+// RV64ZBKC-NEXT: [[TMP0:%.*]] = call i32 @llvm.clmul.i32(i32 [[A:%.*]], i32 [[B:%.*]])
// RV64ZBKC-NEXT: ret i32 [[TMP0]]
//
uint32_t clmul_32(uint32_t a, uint32_t b) {
diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td
index 9088e5e6a357b..f194ce99b52d1 100644
--- a/llvm/include/llvm/IR/IntrinsicsRISCV.td
+++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td
@@ -78,7 +78,6 @@ let TargetPrefix = "riscv" in {
def int_riscv_orc_b : RISCVBitManipGPRIntrinsics;
// Zbc or Zbkc
- def int_riscv_clmul : RISCVBitManipGPRGPRIntrinsics;
def int_riscv_clmulh : RISCVBitManipGPRGPRIntrinsics;
// Zbc
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 562114c355f9e..0c43c11e277da 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -1750,6 +1750,14 @@ static bool upgradeIntrinsicFunction1(Function *F, Function *&NewFn,
}
break; // No other applicable upgrades.
}
+
+ // Replace llvm.riscv.clmul with llvm.clmul.
+ if (Name == "clmul.i32" || Name == "clmul.i64") {
+ NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), Intrinsic::clmul,
+ {F->getReturnType()});
+ return true;
+ }
+
break; // No other 'riscv.*' intrinsics
}
} break;
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 436ce16784c75..013102755281c 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -11370,9 +11370,6 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
return DAG.getNode(RISCVISD::MOP_RR, DL, XLenVT, Op.getOperand(1),
Op.getOperand(2), Op.getOperand(3));
}
- case Intrinsic::riscv_clmul:
- return DAG.getNode(ISD::CLMUL, DL, XLenVT, Op.getOperand(1),
- Op.getOperand(2));
case Intrinsic::riscv_clmulh:
case Intrinsic::riscv_clmulr: {
unsigned Opc = IntNo == Intrinsic::riscv_clmulh ? ISD::CLMULH : ISD::CLMULR;
@@ -15549,18 +15546,6 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res));
return;
}
- case Intrinsic::riscv_clmul: {
- if (!Subtarget.is64Bit() || N->getValueType(0) != MVT::i32)
- return;
-
- SDValue NewOp0 =
- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(1));
- SDValue NewOp1 =
- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(2));
- SDValue Res = DAG.getNode(ISD::CLMUL, DL, MVT::i64, NewOp0, NewOp1);
- Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res));
- return;
- }
case Intrinsic::riscv_clmulh:
case Intrinsic::riscv_clmulr: {
if (!Subtarget.is64Bit() || N->getValueType(0) != MVT::i32)
diff --git a/llvm/test/CodeGen/RISCV/rv32zbc-zbkc-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv32zbc-zbkc-intrinsic.ll
index 9b30ec1f0cc99..51b647b9f21ea 100644
--- a/llvm/test/CodeGen/RISCV/rv32zbc-zbkc-intrinsic.ll
+++ b/llvm/test/CodeGen/RISCV/rv32zbc-zbkc-intrinsic.ll
@@ -4,6 +4,7 @@
; RUN: llc -mtriple=riscv32 -mattr=+zbkc -verify-machineinstrs < %s \
; RUN: | FileCheck %s -check-prefix=RV32ZBC-ZBKC
+; NOTE: This intrinsic has been removed so this tests autoupgrade to llvm.clmul.
define i32 @clmul32(i32 %a, i32 %b) nounwind {
; RV32ZBC-ZBKC-LABEL: clmul32:
; RV32ZBC-ZBKC: # %bb.0:
diff --git a/llvm/test/CodeGen/RISCV/rv64zbc-zbkc-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv64zbc-zbkc-intrinsic.ll
index 8a30fc6d36b91..d6ba6993a3b62 100644
--- a/llvm/test/CodeGen/RISCV/rv64zbc-zbkc-intrinsic.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zbc-zbkc-intrinsic.ll
@@ -4,6 +4,7 @@
; RUN: llc -mtriple=riscv64 -mattr=+zbkc -verify-machineinstrs < %s \
; RUN: | FileCheck %s -check-prefix=RV64ZBC-ZBKC
+; NOTE: This intrinsic has been removed so this tests autoupgrade to llvm.clmul.
define i64 @clmul64(i64 %a, i64 %b) nounwind {
; RV64ZBC-ZBKC-LABEL: clmul64:
; RV64ZBC-ZBKC: # %bb.0:
@@ -22,6 +23,7 @@ define i64 @clmul64h(i64 %a, i64 %b) nounwind {
ret i64 %tmp
}
+; NOTE: This intrinsic has been removed so this tests autoupgrade to llvm.clmul.
define signext i32 @clmul32(i32 signext %a, i32 signext %b) nounwind {
; RV64ZBC-ZBKC-LABEL: clmul32:
; RV64ZBC-ZBKC: # %bb.0:
More information about the llvm-commits
mailing list