Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | ||
---|---|---|
1102 | Not sure I understand the logic here. Can we just make CFI directives a scheduling barrier, like we do for SEH directives? Why are instructions that modify the frame pointer special? |
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | ||
---|---|---|
1102 | The CFI instructions are already a scheduling barrier (MachineIntsr::isPosition()), but that's not enough, as the PostRA scheduler can still reorder non-CFI instructions in a way that makes the unwind info not instruction precise. As an example, on int g(int); int f(int x) { __asm__(""::: "x20", "x21", "x22"); return 1 + g(x - 1); } After PEI we get bb.0.entry: liveins: $w0, $lr, $x22, $x20, $x21 early-clobber $sp = frame-setup STPXpre killed $fp, killed $lr, $sp(tied-def 0), -6 :: (store (s64) into %stack.4), (store (s64) into %stack.3) frame-setup STRXui killed $x22, $sp, 2 :: (store (s64) into %stack.2) frame-setup STPXi killed $x21, killed $x20, $sp, 4 :: (store (s64) into %stack.1), (store (s64) into %stack.0) $fp = frame-setup ADDXri $sp, 0, 0 frame-setup CFI_INSTRUCTION def_cfa $w29, 48 ... but then after the PostRA scheduling one of the stores and the assignment to FP get reordered bb.0.entry: liveins: $w0, $lr, $x22, $x20, $x21 early-clobber $sp = frame-setup STPXpre $fp, killed $lr, $sp(tied-def 0), -6 :: (store (s64) into %stack.4), (store (s64) into %stack.3) frame-setup STRXui killed $x22, $sp, 2 :: (store (s64) into %stack.2) $fp = frame-setup ADDXri $sp, 0, 0 frame-setup STPXi killed $x21, killed $x20, $sp, 4 :: (store (s64) into %stack.1), (store (s64) into %stack.0) frame-setup CFI_INSTRUCTION def_cfa $w29, 48 ... or f: // @f .cfi_startproc // %bb.0: // %entry stp x29, x30, [sp, #-48]! // 16-byte Folded Spill str x22, [sp, #16] // 8-byte Folded Spill mov x29, sp stp x21, x20, [sp, #32] // 16-byte Folded Spill .cfi_def_cfa w29, 48 ... so now while the PC is at the `stp x21, x20, [sp, #32]` the unwind info tells that the CFA register is still SP and the FP has its original value. Instructions that modify FP (and SP, but it's already handled) are special in that they (potentially) affect what the current CFA is. |
Oh, I understand the issue; we need to ensure that any instruction annotated by a CFI directive is not rescheduled away from the directive. (This isn't a problem for Windows EH because there's never more than one instruction between two SEH markings.)
I don't see how this is specific to instructions that modify fp, though. We end up with inaccurate CFI if we put any instruction between an instruction and its associated CFI directive, whether or not that instruction modifies fp. Can we explicitly check for instructions followed by a CFI directive?
We end up with inaccurate CFI if we put any instruction between an instruction and its associated CFI directive, whether or not that instruction modifies fp.
No, not necessarily, but, that said ...
Can we explicitly check for instructions followed by a CFI directive?
... I think this would work. I'll give it a try.
Not sure I understand the logic here. Can we just make CFI directives a scheduling barrier, like we do for SEH directives? Why are instructions that modify the frame pointer special?