forked from OSchip/llvm-project
ARM: fix yet another stack-folding bug
We were trying to fold the stack adjustment into the wrong instruction in the situation where the entire basic-block was epilogue code. Really, it can only ever be valid to do the folding precisely where the "add sp, ..." would be placed so there's no need for a separate iterator to track that. Should fix PR18136. llvm-svn: 196493
This commit is contained in:
parent
58e44a3447
commit
e4def5e228
|
@ -380,15 +380,10 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
|
||||||
if (NumBytes != 0)
|
if (NumBytes != 0)
|
||||||
emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
|
emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
|
||||||
} else {
|
} else {
|
||||||
MachineBasicBlock::iterator FirstPop = MBBI;
|
|
||||||
|
|
||||||
// Unwind MBBI to point to first LDR / VLDRD.
|
// Unwind MBBI to point to first LDR / VLDRD.
|
||||||
const uint16_t *CSRegs = RegInfo->getCalleeSavedRegs(&MF);
|
const uint16_t *CSRegs = RegInfo->getCalleeSavedRegs(&MF);
|
||||||
if (MBBI != MBB.begin()) {
|
if (MBBI != MBB.begin()) {
|
||||||
do {
|
do {
|
||||||
if (isPopOpcode(MBBI->getOpcode()))
|
|
||||||
FirstPop = MBBI;
|
|
||||||
|
|
||||||
--MBBI;
|
--MBBI;
|
||||||
} while (MBBI != MBB.begin() && isCSRestore(MBBI, TII, CSRegs));
|
} while (MBBI != MBB.begin() && isCSRestore(MBBI, TII, CSRegs));
|
||||||
if (!isCSRestore(MBBI, TII, CSRegs))
|
if (!isCSRestore(MBBI, TII, CSRegs))
|
||||||
|
@ -435,7 +430,7 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
|
||||||
.addReg(FramePtr));
|
.addReg(FramePtr));
|
||||||
}
|
}
|
||||||
} else if (NumBytes &&
|
} else if (NumBytes &&
|
||||||
!tryFoldSPUpdateIntoPushPop(STI, MF, FirstPop, NumBytes))
|
!tryFoldSPUpdateIntoPushPop(STI, MF, MBBI, NumBytes))
|
||||||
emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
|
emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
|
||||||
|
|
||||||
// Increment past our save areas.
|
// Increment past our save areas.
|
||||||
|
|
|
@ -124,3 +124,32 @@ define arm_aapcs_vfpcc double @check_vfp_no_return_clobber() minsize {
|
||||||
|
|
||||||
ret double 1.0
|
ret double 1.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@dbl = global double 0.0
|
||||||
|
|
||||||
|
; PR18136: there was a bug determining where the first eligible pop in a
|
||||||
|
; basic-block was when the entire block was epilogue code.
|
||||||
|
define void @test_fold_point(i1 %tst) minsize {
|
||||||
|
; CHECK-LABEL: test_fold_point:
|
||||||
|
|
||||||
|
; Important to check for beginning of basic block, because if it gets
|
||||||
|
; if-converted the test is probably no longer checking what it should.
|
||||||
|
; CHECK: {{LBB[0-9]+_2}}:
|
||||||
|
; CHECK-NEXT: vpop {d7, d8}
|
||||||
|
; CHECK-NEXT: pop {r4, pc}
|
||||||
|
; We want some memory so there's a stack adjustment to fold...
|
||||||
|
%var = alloca i8, i32 8
|
||||||
|
|
||||||
|
; We want a long-lived floating register so that a callee-saved dN is used and
|
||||||
|
; there's both a vpop and a pop.
|
||||||
|
%live_val = load double* @dbl
|
||||||
|
br i1 %tst, label %true, label %end
|
||||||
|
true:
|
||||||
|
call void @bar(i8* %var)
|
||||||
|
store double %live_val, double* @dbl
|
||||||
|
br label %end
|
||||||
|
end:
|
||||||
|
; We want the epilogue to be the only thing in a basic block so that we hit
|
||||||
|
; the correct edge-case (first inst in block is correct one to adjust).
|
||||||
|
ret void
|
||||||
|
}
|
Loading…
Reference in New Issue