From 3fafd935607844085a23c012e2a8778fa97206a0 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Wed, 26 Nov 2008 22:37:40 +0000 Subject: [PATCH] Generate something sensible for an [SU]ADDO op when the overflow/carry flag is the conditional for the BRCOND statement. For instance, it will generate: addl %eax, %ecx jo LOF instead of addl %eax, %ecx ; About 10 instructions to compare the signs of LHS, RHS, and sum. jl LOF git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60123 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 20 ++++++++++++++++++++ lib/Target/X86/X86InstrInfo.cpp | 6 ++++++ lib/Target/X86/X86InstrInfo.h | 8 +++++--- lib/Target/X86/X86InstrInfo.td | 12 +++++++++--- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index efe7bac72eb..13bbf53ebb6 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -6150,6 +6150,26 @@ SDValue X86TargetLowering::LowerCTTZ(SDValue Op, SelectionDAG &DAG) { SDValue X86TargetLowering::LowerXADDO(SDValue Op, SelectionDAG &DAG, ISD::NodeType NTy) { + SDNode *N = Op.getNode(); + + for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) { + SDNode *UseNode = *I; + + if (UseNode->getOpcode() == ISD::BRCOND) { + // Lower a branch on the overflow/carry flag into a "JO"/"JC" + // instruction. Convert the addition into an actual addition, not just a + // pseudo node. + SDValue LHS = N->getOperand(0); + SDValue RHS = N->getOperand(1); + SDValue Sum = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, RHS); + + SDValue Ops[] = { UseNode->getOperand(2), UseNode->getOperand(0) }; + DAG.SelectNodeTo(UseNode, (NTy == ISD::SADDO) ? X86::JO : X86::JC, + MVT::Other, Ops, 2); + return Sum; + } + } + return SDValue(); } diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index 2e449b99316..ba73f49f883 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -1382,6 +1382,8 @@ static X86::CondCode GetCondFromBranchOpc(unsigned BrOpc) { case X86::JNP: return X86::COND_NP; case X86::JO: return X86::COND_O; case X86::JNO: return X86::COND_NO; + case X86::JC: return X86::COND_C; + case X86::JNC: return X86::COND_NC; } } @@ -1404,6 +1406,8 @@ unsigned X86::GetCondBranchFromCond(X86::CondCode CC) { case X86::COND_NP: return X86::JNP; case X86::COND_O: return X86::JO; case X86::COND_NO: return X86::JNO; + case X86::COND_C: return X86::JC; + case X86::COND_NC: return X86::JNC; } } @@ -1428,6 +1432,8 @@ X86::CondCode X86::GetOppositeBranchCondition(X86::CondCode CC) { case X86::COND_NP: return X86::COND_P; case X86::COND_O: return X86::COND_NO; case X86::COND_NO: return X86::COND_O; + case X86::COND_C: return X86::COND_NC; + case X86::COND_NC: return X86::COND_C; } } diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h index cf8be96b0b3..a0e0124676a 100644 --- a/lib/Target/X86/X86InstrInfo.h +++ b/lib/Target/X86/X86InstrInfo.h @@ -41,9 +41,11 @@ namespace X86 { COND_NO = 10, COND_NP = 11, COND_NS = 12, - COND_O = 13, - COND_P = 14, - COND_S = 15, + COND_NC = 13, + COND_O = 14, + COND_P = 15, + COND_S = 16, + COND_C = 17, // Artificial condition codes. These are used by AnalyzeBranch // to indicate a block terminated with two conditional branches to diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index fd463973fda..e6ec25be133 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -235,9 +235,11 @@ def X86_COND_NE : PatLeaf<(i8 9)>; def X86_COND_NO : PatLeaf<(i8 10)>; def X86_COND_NP : PatLeaf<(i8 11)>; def X86_COND_NS : PatLeaf<(i8 12)>; -def X86_COND_O : PatLeaf<(i8 13)>; -def X86_COND_P : PatLeaf<(i8 14)>; -def X86_COND_S : PatLeaf<(i8 15)>; +def X86_COND_NC : PatLeaf<(i8 13)>; +def X86_COND_O : PatLeaf<(i8 14)>; +def X86_COND_P : PatLeaf<(i8 15)>; +def X86_COND_S : PatLeaf<(i8 16)>; +def X86_COND_C : PatLeaf<(i8 17)>; def i16immSExt8 : PatLeaf<(i16 imm), [{ // i16immSExt8 predicate - True if the 16-bit immediate fits in a 8-bit @@ -449,6 +451,10 @@ def JO : IBr<0x80, (ins brtarget:$dst), "jo\t$dst", [(X86brcond bb:$dst, X86_COND_O, EFLAGS)]>, TB; def JNO : IBr<0x81, (ins brtarget:$dst), "jno\t$dst", [(X86brcond bb:$dst, X86_COND_NO, EFLAGS)]>, TB; +def JC : IBr<0x82, (ins brtarget:$dst), "jc\t$dst", + [(X86brcond bb:$dst, X86_COND_C, EFLAGS)]>, TB; +def JNC : IBr<0x83, (ins brtarget:$dst), "jnc\t$dst", + [(X86brcond bb:$dst, X86_COND_NC, EFLAGS)]>, TB; } // Uses = [EFLAGS] //===----------------------------------------------------------------------===//