https://github.com/topperc updated https://github.com/llvm/llvm-project/pull/227819
>From e3eb79f7ef62ca2a3bc815e4b774679d27db168a Mon Sep 17 00:00:00 2001 From: Craig Topper <[email protected]> Date: Wed, 30 Sep 2026 11:28:47 -0700 Subject: [PATCH 1/2] [RISCV] Remvoe riscv_mulh_i32/riscv_mulhu_u32 intrinsics. These are redundant with the llvm.smulh/umulh intrinsics that were recently added. This changes codegen because smulh/umulh are currently generically type legalized with extends+mul+srli instead of using pmulh(u).w. This isn't always a regression. Sometimes we are able to prove the inputs are already extended or we use mul(u).w00 and sometimes we needed a sext.w after the pmulh(u).w. --- clang/lib/CodeGen/TargetBuiltins/RISCV.cpp | 19 ++++++++++--------- clang/test/CodeGen/RISCV/rvp-intrinsics.c | 8 ++++---- .../riscv_packed_simd.c | 10 ++++++---- llvm/include/llvm/IR/IntrinsicsRISCV.td | 2 -- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 8 -------- llvm/test/CodeGen/RISCV/rvp-simd-32.ll | 10 ++++++---- 6 files changed, 26 insertions(+), 31 deletions(-) diff --git a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp index 869f71b9cdd1d..20ec751018685 100644 --- a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp @@ -1371,7 +1371,10 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, case RISCV::BI__builtin_riscv_pusati_u16x4: case RISCV::BI__builtin_riscv_pusati_u32x2: case RISCV::BI__builtin_riscv_psati_i16x4: - case RISCV::BI__builtin_riscv_psati_i32x2: { + case RISCV::BI__builtin_riscv_psati_i32x2: + // Scalar Multiply High + case RISCV::BI__builtin_riscv_mulh_i32: + case RISCV::BI__builtin_riscv_mulhu_u32: { switch (BuiltinID) { default: llvm_unreachable("unexpected builtin ID"); @@ -1622,6 +1625,12 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, case RISCV::BI__builtin_riscv_pusati_u32x2: ID = Intrinsic::riscv_pusati; break; + case RISCV::BI__builtin_riscv_mulh_i32: + ID = Intrinsic::smulh; + break; + case RISCV::BI__builtin_riscv_mulhu_u32: + ID = Intrinsic::umulh; + break; } IntrinsicTypes = {ResultType}; @@ -1629,24 +1638,16 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, } // Scalar Multiply High - case RISCV::BI__builtin_riscv_mulh_i32: case RISCV::BI__builtin_riscv_mulhr_i32: - case RISCV::BI__builtin_riscv_mulhu_u32: case RISCV::BI__builtin_riscv_mulhru_u32: case RISCV::BI__builtin_riscv_mulhsu_i32: case RISCV::BI__builtin_riscv_mulhrsu_i32: { switch (BuiltinID) { default: llvm_unreachable("unexpected builtin ID"); - case RISCV::BI__builtin_riscv_mulh_i32: - ID = Intrinsic::riscv_mulh_i32; - break; case RISCV::BI__builtin_riscv_mulhr_i32: ID = Intrinsic::riscv_mulhr_i32; break; - case RISCV::BI__builtin_riscv_mulhu_u32: - ID = Intrinsic::riscv_mulhu_u32; - break; case RISCV::BI__builtin_riscv_mulhru_u32: ID = Intrinsic::riscv_mulhru_u32; break; diff --git a/clang/test/CodeGen/RISCV/rvp-intrinsics.c b/clang/test/CodeGen/RISCV/rvp-intrinsics.c index b16415525a23a..f5a5863642331 100644 --- a/clang/test/CodeGen/RISCV/rvp-intrinsics.c +++ b/clang/test/CodeGen/RISCV/rvp-intrinsics.c @@ -137,13 +137,13 @@ uint64_t test_abs_u64(int64_t a) { // RV32-LABEL: define dso_local i32 @test_mulh_i32( // RV32-SAME: i32 noundef [[A:%.*]], i32 noundef [[B:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] -// RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.mulh.i32(i32 [[A]], i32 [[B]]) +// RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.smulh.i32(i32 [[A]], i32 [[B]]) // RV32-NEXT: ret i32 [[TMP0]] // // RV64-LABEL: define dso_local signext i32 @test_mulh_i32( // RV64-SAME: i32 noundef signext [[A:%.*]], i32 noundef signext [[B:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] -// RV64-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.mulh.i32(i32 [[A]], i32 [[B]]) +// RV64-NEXT: [[TMP0:%.*]] = call i32 @llvm.smulh.i32(i32 [[A]], i32 [[B]]) // RV64-NEXT: ret i32 [[TMP0]] // int32_t test_mulh_i32(int32_t a, int32_t b) { @@ -169,13 +169,13 @@ int32_t test_mulhr_i32(int32_t a, int32_t b) { // RV32-LABEL: define dso_local i32 @test_mulhu_u32( // RV32-SAME: i32 noundef [[A:%.*]], i32 noundef [[B:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] -// RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.mulhu.u32(i32 [[A]], i32 [[B]]) +// RV32-NEXT: [[TMP0:%.*]] = call i32 @llvm.umulh.i32(i32 [[A]], i32 [[B]]) // RV32-NEXT: ret i32 [[TMP0]] // // RV64-LABEL: define dso_local signext i32 @test_mulhu_u32( // RV64-SAME: i32 noundef signext [[A:%.*]], i32 noundef signext [[B:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] -// RV64-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.mulhu.u32(i32 [[A]], i32 [[B]]) +// RV64-NEXT: [[TMP0:%.*]] = call i32 @llvm.umulh.i32(i32 [[A]], i32 [[B]]) // RV64-NEXT: ret i32 [[TMP0]] // uint32_t test_mulhu_u32(uint32_t a, uint32_t b) { diff --git a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c index 54d7022dac80b..810ad22fa168d 100644 --- a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c +++ b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c @@ -2916,9 +2916,10 @@ int32x2_t test_pmerge_mvmn_i32x2(int32x2_t rs2, int32x2_t rs1, uint32x2_t rd) { } // Scalar multiply high -// CHECK-LABEL: test_mulh_i32: +// CHECK-LABEL: test_mulh_i32:{{.*}} // RV32: mulh -// RV64: pmulh.w +// RV64: mul +// RV64-NEXT: srai int32_t test_mulh_i32(int32_t rs1, int32_t rs2) { return __riscv_mulh_i32(rs1, rs2); } @@ -2930,9 +2931,10 @@ int32_t test_mulhr_i32(int32_t rs1, int32_t rs2) { return __riscv_mulhr_i32(rs1, rs2); } -// CHECK-LABEL: test_mulhu_u32: +// CHECK-LABEL: test_mulhu_u32:{{.*}} // RV32: mulhu -// RV64: pmulhu.w +// RV64: mulu.w00 +// RV64-NEXT: srai uint32_t test_mulhu_u32(uint32_t rs1, uint32_t rs2) { return __riscv_mulhu_u32(rs1, rs2); } diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td index 140a2397841d9..8cac40c2dc535 100644 --- a/llvm/include/llvm/IR/IntrinsicsRISCV.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td @@ -2144,9 +2144,7 @@ class RVPBinaryIntrinsic class RVPScalarMulHighIntrinsic : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem, IntrSpeculatable]>; - def int_riscv_mulh_i32 : RVPScalarMulHighIntrinsic; def int_riscv_mulhr_i32 : RVPScalarMulHighIntrinsic; - def int_riscv_mulhu_u32 : RVPScalarMulHighIntrinsic; def int_riscv_mulhru_u32 : RVPScalarMulHighIntrinsic; def int_riscv_mulhsu_i32 : RVPScalarMulHighIntrinsic; def int_riscv_mulhrsu_i32 : RVPScalarMulHighIntrinsic; diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 3a650ca20f19e..bd994fc36a704 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -12323,12 +12323,8 @@ static unsigned getRVScalarMulHighOpcode(unsigned IntNo) { switch (IntNo) { default: llvm_unreachable("Unexpected RISC-V scalar multiply high intrinsic"); - case Intrinsic::riscv_mulh_i32: - return ISD::MULHS; case Intrinsic::riscv_mulhr_i32: return RISCVISD::MULHR; - case Intrinsic::riscv_mulhu_u32: - return ISD::MULHU; case Intrinsic::riscv_mulhru_u32: return RISCVISD::MULHRU; case Intrinsic::riscv_mulhsu_i32: @@ -13282,9 +13278,7 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, return DAG.getNode(Opc, DL, VT, Op.getOperand(1), Op.getOperand(2)); } - case Intrinsic::riscv_mulh_i32: case Intrinsic::riscv_mulhr_i32: - case Intrinsic::riscv_mulhu_u32: case Intrinsic::riscv_mulhru_u32: case Intrinsic::riscv_mulhsu_i32: case Intrinsic::riscv_mulhrsu_i32: { @@ -17893,9 +17887,7 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N, Results.push_back(DAG.getExtractSubvector(DL, VT, Res, 0)); return; } - case Intrinsic::riscv_mulh_i32: case Intrinsic::riscv_mulhr_i32: - case Intrinsic::riscv_mulhu_u32: case Intrinsic::riscv_mulhru_u32: case Intrinsic::riscv_mulhsu_i32: case Intrinsic::riscv_mulhrsu_i32: { diff --git a/llvm/test/CodeGen/RISCV/rvp-simd-32.ll b/llvm/test/CodeGen/RISCV/rvp-simd-32.ll index 14afeb9c88302..2149266271707 100644 --- a/llvm/test/CodeGen/RISCV/rvp-simd-32.ll +++ b/llvm/test/CodeGen/RISCV/rvp-simd-32.ll @@ -3932,9 +3932,10 @@ define i32 @test_mulh_i32(i32 %rs1, i32 %rs2) { ; ; RV64-LABEL: test_mulh_i32: ; RV64: # %bb.0: -; RV64-NEXT: pmulh.w a0, a0, a1 +; RV64-NEXT: mul.w00 a0, a0, a1 +; RV64-NEXT: srli a0, a0, 32 ; RV64-NEXT: ret - %res = call i32 @llvm.riscv.mulh.i32(i32 %rs1, i32 %rs2) + %res = call i32 @llvm.smulh.i32(i32 %rs1, i32 %rs2) ret i32 %res } @@ -3960,9 +3961,10 @@ define i32 @test_mulhu_u32(i32 %rs1, i32 %rs2) { ; ; RV64-LABEL: test_mulhu_u32: ; RV64: # %bb.0: -; RV64-NEXT: pmulhu.w a0, a0, a1 +; RV64-NEXT: mulu.w00 a0, a0, a1 +; RV64-NEXT: srli a0, a0, 32 ; RV64-NEXT: ret - %res = call i32 @llvm.riscv.mulhu.u32(i32 %rs1, i32 %rs2) + %res = call i32 @llvm.umulh.i32(i32 %rs1, i32 %rs2) ret i32 %res } >From bcfcc7f6a5a02f624d30e356047c2c4e22449d46 Mon Sep 17 00:00:00 2001 From: Craig Topper <[email protected]> Date: Wed, 30 Sep 2026 11:54:04 -0700 Subject: [PATCH 2/2] fixup! make sure we are testing mnemonics and not function names. --- .../intrinsic-header-tests/riscv_packed_simd.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c index 810ad22fa168d..bfb76a4c11cd2 100644 --- a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c +++ b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c @@ -2916,10 +2916,10 @@ int32x2_t test_pmerge_mvmn_i32x2(int32x2_t rs2, int32x2_t rs1, uint32x2_t rd) { } // Scalar multiply high -// CHECK-LABEL: test_mulh_i32:{{.*}} -// RV32: mulh -// RV64: mul -// RV64-NEXT: srai +// CHECK-LABEL: test_mulh_i32: +// RV32: mulh{{[[:space:]]}} +// RV64: mul{{[[:space:]]}} +// RV64-NEXT: srai{{[[:space:]]}} int32_t test_mulh_i32(int32_t rs1, int32_t rs2) { return __riscv_mulh_i32(rs1, rs2); } @@ -2931,10 +2931,10 @@ int32_t test_mulhr_i32(int32_t rs1, int32_t rs2) { return __riscv_mulhr_i32(rs1, rs2); } -// CHECK-LABEL: test_mulhu_u32:{{.*}} -// RV32: mulhu -// RV64: mulu.w00 -// RV64-NEXT: srai +// CHECK-LABEL: test_mulhu_u32: +// RV32: mulhu{{[[:space:]]}} +// RV64: mulu.w00{{[[:space:]]}} +// RV64-NEXT: srai{{[[:space:]]}} uint32_t test_mulhu_u32(uint32_t rs1, uint32_t rs2) { return __riscv_mulhu_u32(rs1, rs2); } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
