[SelectionDAG] ScheduleDAGFast crashes on a node blocked by two live physical registers
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
`llc -O2 -pre-RA-sched=fast` segfaults on this function; the default scheduler compiles it:
```llvm
define i108 @f(i108 %x, i108 %s) {
%r = lshr i108 %x, %s
%c = icmp ugt i108 %s, 107
%sel = select i1 %c, i108 0, i108 %r
ret i108 %sel
}
```
Reproduces on 18.1.3, 19.1.1, 20.1.2, and trunk 24.0.0git (merge-base c226860e90dc).
All are release (non-assertions) builds.
Two conditions are each necessary:
- select condition from the shift _amount_
- at i65, i96, i108, i128, etc. (i.e., not a natural type)
The type must be illegal, so legalization expands the variable shift into a sequence that pins the shift amount to CL; and that same shift amount must feed the compare that feeds the select, which pins EFLAGS. One value, two distinct physical-register-constrained consumers.
An assertions build reports the unhandled case cleanly. A release build does not: it either crashes as above or, where the out-of-bounds read happens to land on a plausible value, *emits wrong code silently*.
Contributor guide
Research direction
Start by running the embedded llc reproducer with -O2 and -pre-RA-sched=fast, then compare it with the default scheduler and an assertions build. Trace the SelectionDAG fast scheduler handling of the legalized shift amount and select condition; done means the case is handled without a crash or silently emitted wrong code.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100