mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 20:29:48 +00:00
X86: Update to peephole optimization to move Movr0 before (Sub, Cmp) pair.
When Movr0 is between sub and cmp, we move Movr0 before sub if it enables removal of Cmp. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160066 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3fef29d881
commit
84ae7e9034
@ -3110,6 +3110,7 @@ optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2,
|
||||
RE = CmpInstr->getParent() == MI->getParent() ?
|
||||
MachineBasicBlock::reverse_iterator(++Def) /* points to MI */ :
|
||||
CmpInstr->getParent()->rend();
|
||||
MachineInstr *Movr0Inst = 0;
|
||||
for (; RI != RE; ++RI) {
|
||||
MachineInstr *Instr = &*RI;
|
||||
// Check whether CmpInstr can be made redundant by the current instruction.
|
||||
@ -3119,10 +3120,24 @@ optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2,
|
||||
}
|
||||
|
||||
if (Instr->modifiesRegister(X86::EFLAGS, TRI) ||
|
||||
Instr->readsRegister(X86::EFLAGS, TRI))
|
||||
Instr->readsRegister(X86::EFLAGS, TRI)) {
|
||||
// This instruction modifies or uses EFLAGS.
|
||||
|
||||
// MOV32r0 etc. are implemented with xor which clobbers condition code.
|
||||
// They are safe to move up, if the definition to EFLAGS is dead and
|
||||
// earlier instructions do not read or write EFLAGS.
|
||||
if (!Movr0Inst && (Instr->getOpcode() == X86::MOV8r0 ||
|
||||
Instr->getOpcode() == X86::MOV16r0 ||
|
||||
Instr->getOpcode() == X86::MOV32r0 ||
|
||||
Instr->getOpcode() == X86::MOV64r0) &&
|
||||
Instr->registerDefIsDead(X86::EFLAGS, TRI)) {
|
||||
Movr0Inst = Instr;
|
||||
continue;
|
||||
}
|
||||
|
||||
// We can't remove CmpInstr.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Return false if no candidates exist.
|
||||
@ -3204,6 +3219,12 @@ optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Move Movr0Inst to the place right before Sub.
|
||||
if (Movr0Inst) {
|
||||
Sub->getParent()->remove(Movr0Inst);
|
||||
Sub->getParent()->insert(MachineBasicBlock::iterator(Sub), Movr0Inst);
|
||||
}
|
||||
|
||||
// Make sure Sub instruction defines EFLAGS.
|
||||
assert(Sub->getNumOperands() >= 4 && Sub->getOperand(3).isReg() &&
|
||||
Sub->getOperand(3).getReg() == X86::EFLAGS &&
|
||||
|
@ -137,6 +137,18 @@ if.else:
|
||||
%add = add nsw i32 %sub, 1
|
||||
ret i32 %add
|
||||
}
|
||||
; rdar://11830760
|
||||
; When Movr0 is between sub and cmp, we need to move "Movr0" before sub.
|
||||
define i32 @l4(i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
; CHECK: l4:
|
||||
; CHECK: sub
|
||||
; CHECK-NOT: cmp
|
||||
%cmp = icmp sgt i32 %b, %a
|
||||
%sub = sub i32 %a, %b
|
||||
%.sub = select i1 %cmp, i32 0, i32 %sub
|
||||
ret i32 %.sub
|
||||
}
|
||||
; rdar://11540023
|
||||
define i32 @n(i32 %x, i32 %y) nounwind {
|
||||
entry:
|
||||
|
Loading…
Reference in New Issue
Block a user