Otherwise, the spill position may point to position where before
FrameSetup instructions. In which case, the spill instruction may store
to caller's frame since the stack pointer has not been adjustted.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Time | Test | |
---|---|---|
60,040 ms | x64 debian > MLIR.Examples/standalone::test.toy |
Event Timeline
If I understand correctly, the use of a vreg in the frame-setup allowed findSurvivorBackward to trigger this code
// Keep searching when we find a vreg since the spilled register will // be usefull for this other vreg as well later. bool FoundVReg = false; for (const MachineOperand &MO : MI.operands()) { if (MO.isReg() && Register::isVirtualRegister(MO.getReg())) { FoundVReg = true; break; } } if (FoundVReg) { InstrCountDown = InstrLimit; Pos = I; }
which caused the search to stop above the frame-setup. So another option might be to use T1 as the scratch register in frame-setup as was once proposed in an earlier revision of https://reviews.llvm.org/D61884
But we can't use T1 with shrink wrapping and I've confirmed the same bug exists with shrink wrapping.
Thanks for looking into shrink-wrapping! Do you mind sharing your shrink-wrapping test cases? So that I can pick them as CodeGen/RISCV test cases.
llvm/test/CodeGen/RISCV/out-of-reach-emergency-slot.mir | ||
---|---|---|
37 | This doens't look correct either. |
This was my shrink wrap case
@var = external global i32 define void @func(i1 %c) { %space = alloca i32, align 4 %stackspace = alloca[1024 x i32], align 4 br i1 %c, label %foo, label %bar bar: ;; Load values to increase register pressure. %v0 = load volatile i32, i32* @var %v1 = load volatile i32, i32* @var %v2 = load volatile i32, i32* @var %v3 = load volatile i32, i32* @var %v4 = load volatile i32, i32* @var %v5 = load volatile i32, i32* @var %v6 = load volatile i32, i32* @var %v7 = load volatile i32, i32* @var %v8 = load volatile i32, i32* @var %v9 = load volatile i32, i32* @var %v10 = load volatile i32, i32* @var %v11 = load volatile i32, i32* @var %v12 = load volatile i32, i32* @var %v13 = load volatile i32, i32* @var store volatile i32 %v0, i32* %space ;; store values so they are used. store volatile i32 %v0, i32* @var store volatile i32 %v1, i32* @var store volatile i32 %v2, i32* @var store volatile i32 %v3, i32* @var store volatile i32 %v4, i32* @var store volatile i32 %v5, i32* @var store volatile i32 %v6, i32* @var store volatile i32 %v7, i32* @var store volatile i32 %v8, i32* @var store volatile i32 %v9, i32* @var store volatile i32 %v10, i32* @var store volatile i32 %v11, i32* @var store volatile i32 %v12, i32* @var store volatile i32 %v13, i32* @var br label %foo foo: ret void }
llvm/test/CodeGen/RISCV/out-of-reach-emergency-slot.mir | ||
---|---|---|
37 | This test case is tricky and rare. We may need to implement the target hook saveScavengerRegister to fix it. So I left a FIXME. |
llvm/lib/CodeGen/RegisterScavenging.cpp | ||
---|---|---|
376 | Can this be done in the FoundTo path? Does this matter before we find To? |
llvm/lib/CodeGen/RegisterScavenging.cpp | ||
---|---|---|
376 | You are right. It doesn't matter before we find To. |
Can this be done in the FoundTo path? Does this matter before we find To?