MachineRegisterInfo::createGenericVirtualRegister sets
RegClassOrRegBank to static_cast<RegisterBank *>(nullptr).
MIParser on the other hand doesn't. When we attempt to constrain
Register Class on such VReg, additional COPY is generated.
This way we avoid COPY instructions showing in test that have MIR
input while they are not present with llvm-ir input that was used
to create given MIR for a -run-pass test.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Motivation is having same behavior for GlobalISel legalizer tests for -stop-after=legalizer (llvm-ir input) and -run-pass=legalizer (mir input created from output of same llvm-ir input by pass before legalizer), later has few extra COPY instructions.
Mips has builtin functions (not available as generic opcode) that correspond to a machine instruction, and as such can be selected during legalization.
When selected, register classes also have to be constrained because other passes leave target specific instructions as they are.
Such builtin functions turned to intrinsic and are handled in MipsLegalizerInfo::legalizeIntrinsic.
test/CodeGen/MIR/Mips/setRegClassOrRegBank.mir | ||
---|---|---|
2 ↗ | (On Diff #225022) | The parser test shouldn't be running the legalizer? -O0 and -global-isel are also unnecessary |
test/CodeGen/MIR/Mips/setRegClassOrRegBank.mir | ||
---|---|---|
2 ↗ | (On Diff #225022) | The change affects internal state of MachineRegisterInfo and is not visible if we only do the parsing ( -run-pass=none ), but is visible when we try to constrainSelectedInstRegOperands. |
I'm still not sure I mechanically follow how this ends up causing a problem? Surely the VRegInfo field was zero initialized already?
RegClassOrRegBank is a PointerUnion<const TargetRegisterClass *, const RegisterBank *>.
Plain nullptr is a const TargetRegisterClass * (the first template type)
but static_cast<RegisterBank *>(nullptr) is nullptr of const RegisterBank * type.
file: lib/CodeGen/GlobalISel/RegisterBankInfo.cpp in ...RegisterBankInfo::constrainGenericRegister(...
line :
if (RegClassOrBank.is<const TargetRegisterClass *>())
makes the difference.
if we go through IRTranslator, it uses createGenericVirtualRegister which also sets RegClassOrRegBank to nullptr RegisterBank *
file: lib/CodeGen/MachineRegisterInfo.cpp in ...MachineRegisterInfo::createGenericVirtualRegister(...
// FIXME: Should we use a dummy register class? VRegInfo[Reg].first = static_cast<RegisterBank *>(nullptr); setType(Reg, Ty);