diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.cpp | 13 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/eflags-copy-expansion.mir | 67 |
2 files changed, 76 insertions, 4 deletions
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp index f6c11c80855..11c532c7d71 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -4527,8 +4527,9 @@ void X86InstrInfo::copyPhysReg(MachineBasicBlock &MBB, // first frame index. // See X86ISelLowering.cpp - X86::hasCopyImplyingStackAdjustment. + const TargetRegisterInfo *TRI = &getRegisterInfo(); MachineBasicBlock::LivenessQueryResult LQR = - MBB.computeRegisterLiveness(&getRegisterInfo(), AX, MI); + MBB.computeRegisterLiveness(TRI, AX, MI); // We do not want to save and restore AX if we do not have to. // Moreover, if we do so whereas AX is dead, we would need to set // an undef flag on the use of AX, otherwise the verifier will @@ -4536,15 +4537,19 @@ void X86InstrInfo::copyPhysReg(MachineBasicBlock &MBB, // We do not want to change the behavior of the machine verifier // as this is usually wrong to read an undef value. if (MachineBasicBlock::LQR_Unknown == LQR) { - LivePhysRegs LPR(&getRegisterInfo()); + LivePhysRegs LPR(TRI); LPR.addLiveOuts(MBB); MachineBasicBlock::iterator I = MBB.end(); while (I != MI) { --I; LPR.stepBackward(*I); } - LQR = LPR.contains(AX) ? MachineBasicBlock::LQR_Live - : MachineBasicBlock::LQR_Dead; + // AX contains the top most register in the aliasing hierarchy. + // It may not be live, but one of its aliases may be. + for (MCRegAliasIterator AI(AX, TRI, true); + AI.isValid() && LQR != MachineBasicBlock::LQR_Live; ++AI) + LQR = LPR.contains(*AI) ? MachineBasicBlock::LQR_Live + : MachineBasicBlock::LQR_Dead; } bool AXDead = (Reg == AX) || (MachineBasicBlock::LQR_Dead == LQR); if (!AXDead) diff --git a/llvm/test/CodeGen/X86/eflags-copy-expansion.mir b/llvm/test/CodeGen/X86/eflags-copy-expansion.mir new file mode 100644 index 00000000000..03f9072dc0e --- /dev/null +++ b/llvm/test/CodeGen/X86/eflags-copy-expansion.mir @@ -0,0 +1,67 @@ +# RUN: llc -run-pass postrapseudos -mtriple=i386-apple-macosx -o /dev/null %s 2>&1 | FileCheck %s + +# Verify that we correctly save and restore eax when copying eflags, +# even when only a smaller alias of eax is used. We used to check only +# eax and not its aliases. +# PR27624. + +--- | + target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" + + define void @foo() { + entry: + br label %false + false: + ret void + } + +... + +--- +name: foo +allVRegsAllocated: true +isSSA: false +tracksRegLiveness: true +liveins: + - { reg: '%edi' } +body: | + bb.0.entry: + liveins: %edi + successors: %bb.1.false + NOOP implicit-def %al + + ; The bug was triggered only when LivePhysReg is used, which + ; happens only when the heuristic for the liveness computation + ; failed. The liveness computation heuristic looks at 10 instructions + ; before and after the copy. Make sure we do not reach the definition of + ; AL in 10 instructions, otherwise the heuristic will see that it is live. + NOOP + NOOP + NOOP + NOOP + NOOP + NOOP + NOOP + NOOP + NOOP + NOOP + NOOP + NOOP + NOOP + ; Save AL. + ; CHECK: PUSH32r killed %eax + + ; Copy EDI into EFLAGS + ; CHECK-NEXT: %eax = MOV32rr %edi + ; CHECK-NEXT: %al = ADD8ri %al, 127, implicit-def %eflags + ; CHECK-NEXT: SAHF implicit-def %eflags, implicit %ah + %eflags = COPY %edi + + ; Restore AL. + ; CHECK-NEXT: %eax = POP32r + bb.1.false: + liveins: %al + NOOP implicit %al + RETQ + +... |

