This patch sets the 'KeepReg' bit for any tied registers during the PrescanInstruction() phase of the dependency breaking algorithm. It then checks those 'KeepReg' bits during the ScanInstruction() phase to avoid changing any tied registers. For more details, please see comments in:
http://llvm.org/bugs/show_bug.cgi?id=20020
The existing code also uses the 'Classes' variable as a marker for registers that shouldn't be changed (by setting the value to -1). If someone can explain why we need two data structures to mark unusable regs, I'd love to understand that.
I added two FIXME comments for code that I think can be removed by using register iterators that include self. I don't want to include those code changes with this patch, however, to keep things as small as possible.
The test case is larger than I'd like, but I don't know how to reduce it further and still produce the failing asm.
@spatel Hi, I was debugging some miscompile issue and came across what I think is very similar bug.
Do you remember why you check against -1 here? In my test-case (which I'm trying to reduce), the Classes[Reg] is some regclass non -1 value. According to the comments for Classes:
My question is: why is this code is checking for -1 specifically, instead of != nullptr? If it's not live, would it still be OK? I have trouble following the logic in this pass.
The comments for scan indicate that
which is evidently not true in my test case (e.g. XOR has 3 same-reg operands, one pair tied, so the ScanInstruction would remove all RegRefs added by Prescan due to the 3rd non-tied reg, and skip the first tied def when adding refs back).