Skip to content

Commit 7ddd0c9

Browse files
committed
[RISCV][ISel] Ensure 'in X' Constraints prevent X0
I'm not sure if this fix is required, but I've written the patch anyway. We can drop this commit if we don't think it's a bug. This does not cause test changes, but we haven't got tests that try to use all 32 registers in inline assembly. Broadly, for GPRs, we made the explicit choice that `r` constraints would never attempt to use `x0`, because `x0` isn't really usable like the other GPRs. I believe the same thing applies to `Zhinx`, `Zfinx` and `Zdinx` because they should not be allocating operands to `x0` either, so this patch introduces new `NoX0` classes for `GPRF16` and `GPRF32` registers, and uses them with inline assembly. There is also a `GPRPairNoX0` for the `Zdinx` case on rv32, avoiding use of the `x0` pair which has different behaviour to the other GPR pairs.
1 parent 6d60f09 commit 7ddd0c9

File tree

2 files changed

+6
-3
lines changed

2 files changed

+6
-3
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20248,11 +20248,11 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2024820248
if (VT.isVector())
2024920249
break;
2025020250
if (VT == MVT::f16 && Subtarget.hasStdExtZhinxmin())
20251-
return std::make_pair(0U, &RISCV::GPRF16RegClass);
20251+
return std::make_pair(0U, &RISCV::GPRF16NoX0RegClass);
2025220252
if (VT == MVT::f32 && Subtarget.hasStdExtZfinx())
20253-
return std::make_pair(0U, &RISCV::GPRF32RegClass);
20253+
return std::make_pair(0U, &RISCV::GPRF32NoX0RegClass);
2025420254
if (VT == MVT::f64 && Subtarget.hasStdExtZdinx() && !Subtarget.is64Bit())
20255-
return std::make_pair(0U, &RISCV::GPRPairRegClass);
20255+
return std::make_pair(0U, &RISCV::GPRPairNoX0RegClass);
2025620256
return std::make_pair(0U, &RISCV::GPRNoX0RegClass);
2025720257
case 'f':
2025820258
if (Subtarget.hasStdExtZfhmin() && VT == MVT::f16)

llvm/lib/Target/RISCV/RISCVRegisterInfo.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,7 @@ def GPRF16 : RISCVRegisterClass<[f16], 16, (add (sequence "X%u_H", 10, 17),
661661
(sequence "X%u_H", 0, 4))>;
662662
def GPRF16C : RISCVRegisterClass<[f16], 16, (add (sequence "X%u_H", 10, 15),
663663
(sequence "X%u_H", 8, 9))>;
664+
def GPRF16NoX0 : RISCVRegisterClass<[f16], 16, (sub GPRF16, X0_H)>;
664665

665666
def GPRF32 : RISCVRegisterClass<[f32], 32, (add (sequence "X%u_W", 10, 17),
666667
(sequence "X%u_W", 5, 7),
@@ -721,6 +722,8 @@ def GPRPair : RISCVRegisterClass<[XLenPairFVT], 64, (add
721722
def GPRPairC : RISCVRegisterClass<[XLenPairFVT], 64, (add
722723
X10_X11, X12_X13, X14_X15, X8_X9
723724
)>;
725+
726+
def GPRPairNoX0 : RISCVRegisterClass<[XLenPairFVT], 64, (sub GPRPair, X0_Pair)>;
724727
} // let RegInfos = XLenPairRI, DecoderMethod = "DecodeGPRPairRegisterClass"
725728

726729
// The register class is added for inline assembly for vector mask types.

0 commit comments

Comments
 (0)