Skip to content

Commit 03dcd88

Browse files
authored
[RISCV][ISel] Ensure 'in X' Constraints prevent X0 (#112563)
I'm not sure if this fix is required, but I've written the patch anyway. 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 659192b commit 03dcd88

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
@@ -20385,11 +20385,11 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2038520385
if (VT.isVector())
2038620386
break;
2038720387
if (VT == MVT::f16 && Subtarget.hasStdExtZhinxmin())
20388-
return std::make_pair(0U, &RISCV::GPRF16RegClass);
20388+
return std::make_pair(0U, &RISCV::GPRF16NoX0RegClass);
2038920389
if (VT == MVT::f32 && Subtarget.hasStdExtZfinx())
20390-
return std::make_pair(0U, &RISCV::GPRF32RegClass);
20390+
return std::make_pair(0U, &RISCV::GPRF32NoX0RegClass);
2039120391
if (VT == MVT::f64 && Subtarget.hasStdExtZdinx() && !Subtarget.is64Bit())
20392-
return std::make_pair(0U, &RISCV::GPRPairRegClass);
20392+
return std::make_pair(0U, &RISCV::GPRPairNoX0RegClass);
2039320393
return std::make_pair(0U, &RISCV::GPRNoX0RegClass);
2039420394
case 'f':
2039520395
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)