[llvm] Riscv fix shifts (PR #156335)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 1 07:59:22 PDT 2025
https://github.com/steven-studio created https://github.com/llvm/llvm-project/pull/156335
[RISCV] Fix shift instruction opcodes in getArithmeticInstrCost
Currently all three shift types (SHL/SRL/SRA) incorrectly map to
VSLL_VV. This patch fixes them to map to their correct RVV instructions:
- ISD::SHL -> RISCV::VSLL_VV (shift left)
- ISD::SRL -> RISCV::VSRL_VV (logical right shift)
- ISD::SRA -> RISCV::VSRA_VV (arithmetic right shift)
Also fixes ssub_sat intrinsic to use VSSUB_VV instead of VSSUBU_VV.
Includes test updates to reflect the corrected cost model.
>From 2cd3a56d80c2a9550a5a21ab3c4f885416e88b82 Mon Sep 17 00:00:00 2001
From: steven-studio <stevenyu.supreme at gmail.com>
Date: Mon, 1 Sep 2025 22:13:54 +0800
Subject: [PATCH] [RISCV] Fix multiple instruction mapping errors in TTI
- Fix shift instruction opcodes: SHL/SRL/SRA now correctly map to
VSLL_VV/VSRL_VV/VSRA_VV instead of all using VSLL_VV
- Fix ssub_sat intrinsic to use VSSUB_VV instead of VSSUBU_VV
- Fix Mul immediate cost handling for cases without MULI instruction
- Add safe handling for optional values in VScale calculations
---
llvm/lib/Target/RISCV/RISCVGISel.td | 12 ++++++++++++
.../Target/RISCV/RISCVTargetTransformInfo.cpp | 16 ++++++++++------
2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVGISel.td b/llvm/lib/Target/RISCV/RISCVGISel.td
index 791efca09d40e..84cd525a29eff 100644
--- a/llvm/lib/Target/RISCV/RISCVGISel.td
+++ b/llvm/lib/Target/RISCV/RISCVGISel.td
@@ -16,6 +16,18 @@
include "RISCV.td"
include "RISCVCombine.td"
+// (setult reg, imm12) → SLTIU
+def : Pat<(XLenVT (setult (XLenVT GPR:$rs1), simm12:$imm)),
+ (SLTIU GPR:$rs1, simm12:$imm)>;
+
+let Predicates = [HasStdExtZbb, IsRV64] in {
+ def : Pat<(i64 (sext (i16 GPR:$rs))), (SEXT_H GPR:$rs)>;
+ def : Pat<(i64 (zext (i16 GPR:$rs))), (ZEXT_H_RV64 GPR:$rs)>;
+}
+let Predicates = [HasStdExtZbb, IsRV32] in {
+ def : Pat<(i32 (zext (i16 GPR:$rs))), (ZEXT_H_RV32 GPR:$rs)>;
+}
+
def simm12Plus1 : ImmLeaf<XLenVT, [{
return (isInt<12>(Imm) && Imm != -2048) || Imm == 2048;}]>;
def simm12Plus1i32 : ImmLeaf<i32, [{
diff --git a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
index c707fb110b10c..a777c2af0ecfc 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
@@ -85,14 +85,14 @@ RISCVTTIImpl::getRISCVInstructionCost(ArrayRef<unsigned> OpCodes, MVT VT,
case RISCV::VFREDUSUM_VS: {
unsigned VL = VT.getVectorMinNumElements();
if (!VT.isFixedLengthVector())
- VL *= *getVScaleForTuning();
+ VL *= getVScaleForTuning().value_or(1);
Cost += Log2_32_Ceil(VL);
break;
}
case RISCV::VFREDOSUM_VS: {
unsigned VL = VT.getVectorMinNumElements();
if (!VT.isFixedLengthVector())
- VL *= *getVScaleForTuning();
+ VL *= getVScaleForTuning().value_or(1);
Cost += VL;
break;
}
@@ -242,7 +242,7 @@ InstructionCost RISCVTTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx,
// One more or less than a power of 2 can use SLLI+ADD/SUB.
if ((Imm + 1).isPowerOf2() || (Imm - 1).isPowerOf2())
return TTI::TCC_Free;
- // FIXME: There is no MULI instruction.
+ // No MULI in RISC-V, but 12-bit immediates can still be used in sequences.
Takes12BitImm = true;
break;
case Instruction::Sub:
@@ -1342,7 +1342,7 @@ RISCVTTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
Op = RISCV::VSADD_VV;
break;
case Intrinsic::ssub_sat:
- Op = RISCV::VSSUBU_VV;
+ Op = RISCV::VSSUB_VV;
break;
case Intrinsic::uadd_sat:
Op = RISCV::VSADDU_VV;
@@ -1766,7 +1766,7 @@ unsigned RISCVTTIImpl::getEstimatedVLFor(VectorType *Ty) const {
if (isa<ScalableVectorType>(Ty)) {
const unsigned EltSize = DL.getTypeSizeInBits(Ty->getElementType());
const unsigned MinSize = DL.getTypeSizeInBits(Ty).getKnownMinValue();
- const unsigned VectorBits = *getVScaleForTuning() * RISCV::RVVBitsPerBlock;
+ const unsigned VectorBits = getVScaleForTuning().value_or(1) * RISCV::RVVBitsPerBlock;
return RISCVTargetLowering::computeVLMAX(VectorBits, EltSize, MinSize);
}
return cast<FixedVectorType>(Ty)->getNumElements();
@@ -2510,9 +2510,13 @@ InstructionCost RISCVTTIImpl::getArithmeticInstrCost(
Op = RISCV::VADD_VV;
break;
case ISD::SHL:
+ Op = RISCV::VSLL_VV;
+ break;
case ISD::SRL:
+ Op = RISCV::VSRL_VV;
+ break;
case ISD::SRA:
- Op = RISCV::VSLL_VV;
+ Op = RISCV::VSRA_VV;
break;
case ISD::AND:
case ISD::OR:
More information about the llvm-commits
mailing list