[llvm] [RISCV][GlobalISel] Lower G_SMULFIX (PR #196636)
Gábor Spaits via llvm-commits
llvm-commits at lists.llvm.org
Fri May 8 14:05:15 PDT 2026
https://github.com/spaits updated https://github.com/llvm/llvm-project/pull/196636
>From e83e716ed1b083f19a8071058359becdfcee4d1c Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Fri, 8 May 2026 22:28:19 +0200
Subject: [PATCH 1/2] [RISCV][GlobalISel] Lower G_SMULFIX
The G_SMULFIX operator was added, but no lowering was defined for it.
---
.../llvm/CodeGen/GlobalISel/LegalizerHelper.h | 1 +
.../CodeGen/GlobalISel/LegalizerHelper.cpp | 31 ++++++
.../Target/RISCV/GISel/RISCVLegalizerInfo.cpp | 2 +
.../legalizer/legalize-smulfix-rv32.mir | 97 +++++++++++++++++++
.../legalizer/legalize-smulfix-rv64.mir | 59 +++++++++++
.../RISCV/GlobalISel/smulfix-intrinsics.ll | 82 ++++++++++++++++
6 files changed, 272 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-smulfix-rv32.mir
create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-smulfix-rv64.mir
create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/smulfix-intrinsics.ll
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index 8bcae5d15ad2c..9858f5e92de7a 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -576,6 +576,7 @@ class LegalizerHelper {
LLVM_ABI LegalizeResult lowerMemCpyFamily(MachineInstr &MI,
unsigned MaxLen = 0);
LLVM_ABI LegalizeResult lowerVAArg(MachineInstr &MI);
+ LLVM_ABI LegalizeResult lowerSmulfix(MachineInstr &MI);
};
} // End namespace llvm.
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 71cda8a480dd7..d6554e4f47f47 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -4968,6 +4968,8 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
MI.eraseFromParent();
return Legalized;
}
+ case G_SMULFIX:
+ return lowerSmulfix(MI);
}
}
@@ -10656,6 +10658,35 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerVAArg(MachineInstr &MI) {
return Legalized;
}
+LegalizerHelper::LegalizeResult
+LegalizerHelper::lowerSmulfix(MachineInstr &MI) {
+ auto [Dst, LHS, RHS] = MI.getFirst3Regs();
+ LLT Ty = MRI.getType(Dst);
+ if (Ty != MRI.getType(LHS) || Ty != MRI.getType(RHS) || !Ty.isScalar())
+ return UnableToLegalize;
+
+ unsigned Scale = MI.getOperand(3).getImm();
+ if (Scale >= Ty.getSizeInBits())
+ return UnableToLegalize;
+
+ if (Scale == 0) {
+ MIRBuilder.buildMul(Dst, LHS, RHS);
+ MI.eraseFromParent();
+ return Legalized;
+ }
+
+ LLT WideTy = LLT::scalar(Ty.getSizeInBits() * 2);
+ auto SExtLHS = MIRBuilder.buildSExt(WideTy, LHS);
+ auto SExtRHS = MIRBuilder.buildSExt(WideTy, RHS);
+ auto Mul = MIRBuilder.buildMul(WideTy, SExtLHS, SExtRHS);
+ auto ShiftAmt = MIRBuilder.buildConstant(WideTy, Scale);
+ auto Shifted = MIRBuilder.buildAShr(WideTy, Mul, ShiftAmt);
+ MIRBuilder.buildTrunc(Dst, Shifted);
+
+ MI.eraseFromParent();
+ return Legalized;
+}
+
static bool shouldLowerMemFuncForSize(const MachineFunction &MF) {
// On Darwin, -Os means optimize for size without hurting performance, so
// only really optimize for size when -Oz (MinSize) is used.
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index b7efee8bf4c83..6788e8112cd2b 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -156,6 +156,8 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
.minScalar(0, sXLen)
.lower();
+ getActionDefinitionsBuilder(G_SMULFIX).lower();
+
// TODO: Use Vector Single-Width Saturating Instructions for vector types.
getActionDefinitionsBuilder(
{G_UADDSAT, G_SADDSAT, G_USUBSAT, G_SSUBSAT, G_SSHLSAT, G_USHLSAT})
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-smulfix-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-smulfix-rv32.mir
new file mode 100644
index 0000000000000..bbbb87197d0b3
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-smulfix-rv32.mir
@@ -0,0 +1,97 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+m -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s
+
+---
+name: smul_i32
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: smul_i32
+ ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[COPY]], [[C]](s32)
+ ; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[COPY1]], [[C]](s32)
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = G_MUL [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: [[MUL1:%[0-9]+]]:_(s32) = G_MUL [[ASHR]], [[COPY1]]
+ ; CHECK-NEXT: [[MUL2:%[0-9]+]]:_(s32) = G_MUL [[COPY]], [[ASHR1]]
+ ; CHECK-NEXT: [[UMULH:%[0-9]+]]:_(s32) = G_UMULH [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[MUL1]], [[MUL2]]
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[ADD]], [[UMULH]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 15
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[MUL]], [[C1]](s32)
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 17
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ADD1]], [[C2]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[LSHR]], [[SHL]]
+ ; CHECK-NEXT: $x10 = COPY [[OR]](s32)
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ %0:_(s32) = COPY $x10
+ %1:_(s32) = COPY $x11
+ %2:_(s32) = G_SMULFIX %0:_, %1:_, 15
+ $x10 = COPY %2:_(s32)
+ PseudoRET implicit $x10
+...
+---
+name: smul_i64
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: smul_i64
+ ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[COPY1]], [[C]](s32)
+ ; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[COPY3]], [[C]](s32)
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = G_MUL [[COPY]], [[COPY2]]
+ ; CHECK-NEXT: [[MUL1:%[0-9]+]]:_(s32) = G_MUL [[COPY1]], [[COPY2]]
+ ; CHECK-NEXT: [[MUL2:%[0-9]+]]:_(s32) = G_MUL [[COPY]], [[COPY3]]
+ ; CHECK-NEXT: [[UMULH:%[0-9]+]]:_(s32) = G_UMULH [[COPY]], [[COPY2]]
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[MUL1]], [[MUL2]]
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ult), [[ADD]](s32), [[MUL2]]
+ ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY [[ADD]](s32)
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[COPY4]], [[UMULH]]
+ ; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(s32) = G_ICMP intpred(ult), [[ADD1]](s32), [[UMULH]]
+ ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY [[ADD1]](s32)
+ ; CHECK-NEXT: [[ADD2:%[0-9]+]]:_(s32) = G_ADD [[ICMP]], [[ICMP1]]
+ ; CHECK-NEXT: [[MUL3:%[0-9]+]]:_(s32) = G_MUL [[ASHR]], [[COPY2]]
+ ; CHECK-NEXT: [[MUL4:%[0-9]+]]:_(s32) = G_MUL [[COPY1]], [[COPY3]]
+ ; CHECK-NEXT: [[MUL5:%[0-9]+]]:_(s32) = G_MUL [[COPY]], [[ASHR1]]
+ ; CHECK-NEXT: [[UMULH1:%[0-9]+]]:_(s32) = G_UMULH [[COPY1]], [[COPY2]]
+ ; CHECK-NEXT: [[UMULH2:%[0-9]+]]:_(s32) = G_UMULH [[COPY]], [[COPY3]]
+ ; CHECK-NEXT: [[ADD3:%[0-9]+]]:_(s32) = G_ADD [[MUL3]], [[MUL4]]
+ ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY [[ADD3]](s32)
+ ; CHECK-NEXT: [[ADD4:%[0-9]+]]:_(s32) = G_ADD [[COPY6]], [[MUL5]]
+ ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY [[ADD4]](s32)
+ ; CHECK-NEXT: [[ADD5:%[0-9]+]]:_(s32) = G_ADD [[COPY7]], [[UMULH1]]
+ ; CHECK-NEXT: [[COPY8:%[0-9]+]]:_(s32) = COPY [[ADD5]](s32)
+ ; CHECK-NEXT: [[ADD6:%[0-9]+]]:_(s32) = G_ADD [[COPY8]], [[UMULH2]]
+ ; CHECK-NEXT: [[COPY9:%[0-9]+]]:_(s32) = COPY [[ADD6]](s32)
+ ; CHECK-NEXT: [[ADD7:%[0-9]+]]:_(s32) = G_ADD [[COPY9]], [[ADD2]]
+ ; CHECK-NEXT: [[COPY10:%[0-9]+]]:_(s32) = COPY [[ADD7]](s32)
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 15
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[MUL]], [[C2]](s32)
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 17
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY5]], [[C3]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[LSHR]], [[SHL]]
+ ; CHECK-NEXT: [[LSHR1:%[0-9]+]]:_(s32) = G_LSHR [[COPY5]], [[C2]](s32)
+ ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[COPY10]], [[C3]](s32)
+ ; CHECK-NEXT: [[OR1:%[0-9]+]]:_(s32) = G_OR [[OR]], [[C1]]
+ ; CHECK-NEXT: [[OR2:%[0-9]+]]:_(s32) = G_OR [[LSHR1]], [[SHL1]]
+ ; CHECK-NEXT: $x10 = COPY [[OR1]](s32)
+ ; CHECK-NEXT: $x11 = COPY [[OR2]](s32)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ %2:_(s32) = COPY $x10
+ %3:_(s32) = COPY $x11
+ %0:_(s64) = G_MERGE_VALUES %2:_(s32), %3:_(s32)
+ %4:_(s32) = COPY $x12
+ %5:_(s32) = COPY $x13
+ %1:_(s64) = G_MERGE_VALUES %4:_(s32), %5:_(s32)
+ %6:_(s64) = G_SMULFIX %0:_, %1:_, 15
+ %7:_(s32), %8:_(s32) = G_UNMERGE_VALUES %6:_(s64)
+ $x10 = COPY %7:_(s32)
+ $x11 = COPY %8:_(s32)
+ PseudoRET implicit $x10, implicit $x11
+...
+
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-smulfix-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-smulfix-rv64.mir
new file mode 100644
index 0000000000000..9e20932cef300
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-smulfix-rv64.mir
@@ -0,0 +1,59 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -mattr=+m -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s
+
+---
+name: smul_i32
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: smul_i32
+ ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 32
+ ; CHECK-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 32
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[SEXT_INREG]], [[SEXT_INREG1]]
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 15
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[MUL]], [[C]](s64)
+ ; CHECK-NEXT: $x10 = COPY [[ASHR]](s64)
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ %2:_(s64) = COPY $x10
+ %0:_(s32) = G_TRUNC %2:_(s64)
+ %3:_(s64) = COPY $x11
+ %1:_(s32) = G_TRUNC %3:_(s64)
+ %4:_(s32) = G_SMULFIX %0:_, %1:_, 15
+ %5:_(s64) = G_ANYEXT %4:_(s32)
+ $x10 = COPY %5:_(s64)
+ PseudoRET implicit $x10
+
+...
+
+---
+name: smul_i64
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: smul_i64
+ ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 63
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[COPY]], [[C]](s64)
+ ; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s64) = G_ASHR [[COPY1]], [[C]](s64)
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: [[MUL1:%[0-9]+]]:_(s64) = G_MUL [[ASHR]], [[COPY1]]
+ ; CHECK-NEXT: [[MUL2:%[0-9]+]]:_(s64) = G_MUL [[COPY]], [[ASHR1]]
+ ; CHECK-NEXT: [[UMULH:%[0-9]+]]:_(s64) = G_UMULH [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[MUL1]], [[MUL2]]
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s64) = G_ADD [[ADD]], [[UMULH]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 15
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s64) = G_LSHR [[MUL]], [[C1]](s64)
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 49
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ADD1]], [[C2]](s64)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = G_OR [[LSHR]], [[SHL]]
+ ; CHECK-NEXT: $x10 = COPY [[OR]](s64)
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ %0:_(s64) = COPY $x10
+ %1:_(s64) = COPY $x11
+ %2:_(s64) = G_SMULFIX %0:_, %1:_, 15
+ $x10 = COPY %2:_(s64)
+ PseudoRET implicit $x10
+...
+
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/smulfix-intrinsics.ll b/llvm/test/CodeGen/RISCV/GlobalISel/smulfix-intrinsics.ll
new file mode 100644
index 0000000000000..3fce674bcf69a
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/smulfix-intrinsics.ll
@@ -0,0 +1,82 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -O3 -mtriple=riscv32 -mattr=+m -verify-machineinstrs -global-isel < %s \
+; RUN: | FileCheck %s -check-prefix=RV32I
+; RUN: llc -O3 -mtriple=riscv64 -mattr=+m -verify-machineinstrs -global-isel < %s \
+; RUN: | FileCheck %s -check-prefix=RV64I
+
+define i32 @smulfix_i32(i32 %1, i32 %2) {
+; RV32I-LABEL: smulfix_i32:
+; RV32I: # %bb.0:
+; RV32I-NEXT: srai a2, a0, 31
+; RV32I-NEXT: srai a3, a1, 31
+; RV32I-NEXT: mul a4, a0, a1
+; RV32I-NEXT: mul a2, a2, a1
+; RV32I-NEXT: mulhu a1, a0, a1
+; RV32I-NEXT: mul a0, a0, a3
+; RV32I-NEXT: add a0, a2, a0
+; RV32I-NEXT: add a0, a0, a1
+; RV32I-NEXT: srli a4, a4, 15
+; RV32I-NEXT: slli a0, a0, 17
+; RV32I-NEXT: or a0, a4, a0
+; RV32I-NEXT: ret
+;
+; RV64I-LABEL: smulfix_i32:
+; RV64I: # %bb.0:
+; RV64I-NEXT: sext.w a0, a0
+; RV64I-NEXT: sext.w a1, a1
+; RV64I-NEXT: mul a0, a0, a1
+; RV64I-NEXT: srai a0, a0, 15
+; RV64I-NEXT: ret
+ %m = call i32 @llvm.smul.fix.i32(i32 %1, i32 %2, i32 15)
+ ret i32 %m
+}
+
+define i64 @smulfix_i64(i64 %1, i64 %2) {
+; RV32I-LABEL: smulfix_i64:
+; RV32I: # %bb.0:
+; RV32I-NEXT: srai a4, a1, 31
+; RV32I-NEXT: srai a5, a3, 31
+; RV32I-NEXT: mul a6, a0, a2
+; RV32I-NEXT: mul a7, a1, a2
+; RV32I-NEXT: mul t0, a0, a3
+; RV32I-NEXT: mulhu t1, a0, a2
+; RV32I-NEXT: mul a4, a4, a2
+; RV32I-NEXT: mulhu a2, a1, a2
+; RV32I-NEXT: mul a1, a1, a3
+; RV32I-NEXT: mulhu a3, a0, a3
+; RV32I-NEXT: add a7, a7, t0
+; RV32I-NEXT: mul a0, a0, a5
+; RV32I-NEXT: srli a5, a6, 15
+; RV32I-NEXT: sltu a6, a7, t0
+; RV32I-NEXT: add a7, a7, t1
+; RV32I-NEXT: add a1, a4, a1
+; RV32I-NEXT: add a0, a0, a2
+; RV32I-NEXT: sltu a2, a7, t1
+; RV32I-NEXT: add a0, a1, a0
+; RV32I-NEXT: slli a1, a7, 17
+; RV32I-NEXT: add a2, a6, a2
+; RV32I-NEXT: add a3, a0, a3
+; RV32I-NEXT: or a0, a5, a1
+; RV32I-NEXT: add a2, a3, a2
+; RV32I-NEXT: srli a1, a7, 15
+; RV32I-NEXT: slli a2, a2, 17
+; RV32I-NEXT: or a1, a1, a2
+; RV32I-NEXT: ret
+;
+; RV64I-LABEL: smulfix_i64:
+; RV64I: # %bb.0:
+; RV64I-NEXT: srai a2, a0, 63
+; RV64I-NEXT: srai a3, a1, 63
+; RV64I-NEXT: mul a4, a0, a1
+; RV64I-NEXT: mul a2, a2, a1
+; RV64I-NEXT: mulhu a1, a0, a1
+; RV64I-NEXT: mul a0, a0, a3
+; RV64I-NEXT: add a0, a2, a0
+; RV64I-NEXT: add a0, a0, a1
+; RV64I-NEXT: srli a4, a4, 15
+; RV64I-NEXT: slli a0, a0, 49
+; RV64I-NEXT: or a0, a4, a0
+; RV64I-NEXT: ret
+ %m = call i64 @llvm.smul.fix.i64(i64 %1, i64 %2, i32 15)
+ ret i64 %m
+}
>From a4979976f9adaad7766634e6611c0b32a2e447da Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Fri, 8 May 2026 23:05:01 +0200
Subject: [PATCH 2/2] Update leg. inf. valid.
---
.../CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
index f3e00ed6521c4..32f547ecdd7b6 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
@@ -484,8 +484,8 @@
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_SMULFIX (opcode {{[0-9]+}}): 1 type index, 1 imm index
-# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
-# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
+# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_UMULFIX (opcode {{[0-9]+}}): 1 type index, 1 imm index
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
More information about the llvm-commits
mailing list