mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-12 18:33:22 +00:00
Implement fast-isel conversion of a branch instruction that's branching on an
overflow/carry from the "arithmetic with overflow" intrinsics. It searches the machine basic block from bottom to top to find the SETO/SETC instruction that is its conditional. If an instruction modifies EFLAGS before it reaches the SETO/SETC instruction, then it defaults to the normal instruction emission. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60807 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
54e4c36a73
commit
30a64a7649
@ -748,6 +748,69 @@ bool X86FastISel::X86SelectBranch(Instruction *I) {
|
|||||||
MBB->addSuccessor(TrueMBB);
|
MBB->addSuccessor(TrueMBB);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
} else if (ExtractValueInst *EI =
|
||||||
|
dyn_cast<ExtractValueInst>(BI->getCondition())) {
|
||||||
|
// Check to see if the branch instruction is from an "arithmetic with
|
||||||
|
// overflow" intrinsic. The main way these intrinsics are used is:
|
||||||
|
//
|
||||||
|
// %t = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
|
||||||
|
// %sum = extractvalue { i32, i1 } %t, 0
|
||||||
|
// %obit = extractvalue { i32, i1 } %t, 1
|
||||||
|
// br i1 %obit, label %overflow, label %normal
|
||||||
|
//
|
||||||
|
// The %sum and %obit are converted in an ADD and a SETO/SETC before
|
||||||
|
// reaching the branch. Therefore, we search backwards through the MBB
|
||||||
|
// looking for the SETO/SETC instruction. If an instruction modifies the
|
||||||
|
// EFLAGS register before we reach the SETO/SETC instruction, then we can't
|
||||||
|
// convert the branch into a JO/JC instruction.
|
||||||
|
const MachineInstr *SetMI = 0;
|
||||||
|
unsigned Reg = lookUpRegForValue(EI);
|
||||||
|
|
||||||
|
for (MachineBasicBlock::const_reverse_iterator
|
||||||
|
RI = MBB->rbegin(), RE = MBB->rend(); RI != RE; ++RI) {
|
||||||
|
const MachineInstr &MI = *RI;
|
||||||
|
|
||||||
|
if (MI.modifiesRegister(Reg)) {
|
||||||
|
unsigned Src, Dst;
|
||||||
|
|
||||||
|
if (getInstrInfo()->isMoveInstr(MI, Src, Dst)) {
|
||||||
|
Reg = Src;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetMI = &MI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TargetInstrDesc &TID = MI.getDesc();
|
||||||
|
const unsigned *ImpDefs = TID.getImplicitDefs();
|
||||||
|
|
||||||
|
if (TID.hasUnmodeledSideEffects()) break;
|
||||||
|
|
||||||
|
bool ModifiesEFlags = false;
|
||||||
|
|
||||||
|
if (ImpDefs) {
|
||||||
|
for (unsigned u = 0; ImpDefs[u]; ++u)
|
||||||
|
if (ImpDefs[u] == X86::EFLAGS) {
|
||||||
|
ModifiesEFlags = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ModifiesEFlags) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SetMI) {
|
||||||
|
unsigned OpCode = SetMI->getOpcode();
|
||||||
|
|
||||||
|
if (OpCode == X86::SETOr || OpCode == X86::SETCr) {
|
||||||
|
BuildMI(MBB, TII.get((OpCode == X86::SETOr) ?
|
||||||
|
X86::JO : X86::JC)).addMBB(TrueMBB);
|
||||||
|
FastEmitBranch(FalseMBB);
|
||||||
|
MBB->addSuccessor(TrueMBB);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise do a clumsy setcc and re-test it.
|
// Otherwise do a clumsy setcc and re-test it.
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
; RUN: llvm-as < %s | llc -march=x86 | grep {jo} | count 1
|
; RUN: llvm-as < %s | llc -march=x86 | grep {jo} | count 1
|
||||||
; RUN: llvm-as < %s | llc -march=x86 | grep {jc} | count 1
|
; RUN: llvm-as < %s | llc -march=x86 | grep {jc} | count 1
|
||||||
|
; RUN: llvm-as < %s | llc -march=x86 -fast | grep {jo} | count 1
|
||||||
|
; RUN: llvm-as < %s | llc -march=x86 -fast | grep {jc} | count 1
|
||||||
|
|
||||||
@ok = internal constant [4 x i8] c"%d\0A\00"
|
@ok = internal constant [4 x i8] c"%d\0A\00"
|
||||||
@no = internal constant [4 x i8] c"no\0A\00"
|
@no = internal constant [4 x i8] c"no\0A\00"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user