instead of cleaning up after. This is made possible by a previous
commit (D10174) that threaded InsertPt through foldOperandImpl.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
I think this should be done inside 'foldMemoryOperandImpl'. We shouldn't have to cleanup afterwards.
'constrainRegClass' may actually fail, so you need to check the result of this method if you use it .
lib/Target/X86/X86FastISel.cpp | ||
---|---|---|
3348 | I don't think this is correct. The index "i" must line up with the MO index in the instruction and not with AddrOps. | |
3350 | MO.isReg() is shorter :) | |
3353 | If you use TargetRegisterInfo::isVirtualRegister instead, you can even skip the MO.isReg() check. | |
3355 | This is not guaranteed to succeed - you need to check the result. See FastISel::constrainOperandRegClass for more details. |
I looked at implementing this in foldMemoryOperandImpl, but it seems like right now it can only return one instruction and does not insert it, which doesn't work if we want to insert the COPY for constraining the register class.
I did see a FIXME that says
// FIXME: change foldMemoryOperandImpl semantics to also insert NewMI.
so maybe I should just try that?
Ok, have a look at this and let me know what you think. It threads through the InsertPt and then sets the correct register class in foldMemoryOperandImpl. If this approach generally looks fine, I'll split out threading through the InsertPt into a separate commit (since it touches other backends).
Yep, looks like my fix handled this one too. I don't think this patch will handle more cases than mine. If you have a strong preference for your solution over mine, then i'm happy to see the code changed though. There's no perfect way to fix this bug so i'm happy to see the best possible solution committed.
Well, as you can see the first version of this patch was actually exactly the same as yours and @ributzka asked me to refactor it. It's been a while since I looked at this code, but it seems like I can factor out adding the InsertPt, which is the bulk of this change as an NFC commit and then only have the actual bugfix here. Does that sounds good?
Sorry, Phab is acting up, so will use email.
This was in the original, but as your moving the code anyway, can you invert this to remove indentation, i.e.,
+ if (TargetRegisterInfo::isVirtualRegister(Op)) {
…
}
return Op
to
+ if (!TargetRegisterInfo::isVirtualRegister(Op))
return Op;
…
Similarly, can you make this a foreach loop:
for (unsigned i = 0; i != NumAddrOps; ++i) {
to
for (MachineOperand MO : MOs) {
Thanks for doing all this!
Cheers,
Pete
The i in the for loop is actually required as it's passed into constrainOperandRegClass. For the other one, the success case of constrainRegClass, does also lead to the second return statement, so I think it's cleaner this way than
unsigned MachineRegisterInfo::constrainOperandRegClass( MachineFunction &MF, MachineBasicBlock::iterator InsertPt, DebugLoc DL, const MCInstrDesc &II, unsigned Op, unsigned OpNum, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI) { if (!TargetRegisterInfo::isVirtualRegister(Op)) return Op; const TargetRegisterClass *RegClass = TII.getRegClass(II, OpNum, &TRI, MF); if (constrainRegClass(Op, RegClass)) return Op; // If it's not legal to COPY between the register classes, something // has gone very wrong before we got here. unsigned NewOp = createVirtualRegister(RegClass); BuildMI(*InsertPt->getParent(), InsertPt, DL, TII.get(TargetOpcode::COPY), NewOp) .addReg(Op); return NewOp; }
but I have no strong opinion.