mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-12 06:06:32 +00:00
Second stab at target-dependent lowering of everyone's favorite nodes: [SU]ADDO
- LowerXADDO lowers [SU]ADDO into an ADD with an implicit EFLAGS define. The EFLAGS are fed into a SETCC node which has the conditional COND_O or COND_C, depending on the type of ADDO requested. - LowerBRCOND now recognizes if it's coming from a SETCC node with COND_O or COND_C set. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60388 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9f24874f2e
commit
61edeb5ed2
@ -5186,6 +5186,8 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) {
|
||||
|
||||
if (Cond.getOpcode() == ISD::SETCC)
|
||||
Cond = LowerSETCC(Cond, DAG);
|
||||
else if (Cond.getOpcode() == ISD::SADDO || Cond.getOpcode() == ISD::UADDO)
|
||||
Cond = LowerXADDO(Cond, DAG);
|
||||
|
||||
// If condition flag is set by a X86ISD::CMP, then use it as the condition
|
||||
// setting operand in place of the X86ISD::SETCC.
|
||||
@ -5199,6 +5201,17 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) {
|
||||
Opc == X86ISD::UCOMI) {
|
||||
Cond = Cmp;
|
||||
addTest = false;
|
||||
} else {
|
||||
if (ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(CC.getNode())) {
|
||||
switch (CSDN->getZExtValue()) {
|
||||
default: break;
|
||||
case X86::COND_O:
|
||||
case X86::COND_C:
|
||||
Cond = Cond.getNode()->getOperand(1);
|
||||
addTest = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Also, recognize the pattern generated by an FCMP_UNE. We can emit
|
||||
// two branches instead of an explicit OR instruction with a
|
||||
@ -6102,31 +6115,27 @@ SDValue X86TargetLowering::LowerCTTZ(SDValue Op, SelectionDAG &DAG) {
|
||||
return Op;
|
||||
}
|
||||
|
||||
SDValue X86TargetLowering::LowerXADDO(SDValue Op, SelectionDAG &DAG,
|
||||
ISD::NodeType NTy) {
|
||||
#if 0
|
||||
// FIXME: Lowering XADDO should use BRCOND as well.
|
||||
SDValue X86TargetLowering::LowerXADDO(SDValue Op, SelectionDAG &DAG) {
|
||||
// Lower the "add with overflow" instruction into a regular "add" plus a
|
||||
// "setcc" instruction that checks the overflow flag. The "brcond" lowering
|
||||
// looks for this combo and may remove the "setcc" instruction if the "setcc"
|
||||
// has only one use.
|
||||
SDNode *N = Op.getNode();
|
||||
SDValue LHS = N->getOperand(0);
|
||||
SDValue RHS = N->getOperand(1);
|
||||
|
||||
for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
|
||||
SDNode *UseNode = *I;
|
||||
// Also sets EFLAGS.
|
||||
SDVTList VTs = DAG.getVTList(N->getValueType(0), MVT::i32);
|
||||
SDValue Sum = DAG.getNode(ISD::ADD, VTs, LHS, RHS);
|
||||
|
||||
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 SetCC =
|
||||
DAG.getNode(X86ISD::SETCC, N->getValueType(1),
|
||||
DAG.getConstant((Op.getOpcode() == ISD::SADDO) ?
|
||||
X86::COND_O : X86::COND_C,
|
||||
MVT::i32), SDValue(Sum.getNode(), 1));
|
||||
|
||||
SDValue Ops[] = { UseNode->getOperand(2), UseNode->getOperand(0) };
|
||||
DAG.SelectNodeTo(UseNode, (NTy == ISD::SADDO) ? X86::JO : X86::JC,
|
||||
MVT::Other, Ops, 2);
|
||||
return Sum;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return SDValue();
|
||||
DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), SetCC);
|
||||
return Sum;
|
||||
}
|
||||
|
||||
SDValue X86TargetLowering::LowerCMP_SWAP(SDValue Op, SelectionDAG &DAG) {
|
||||
@ -6143,7 +6152,7 @@ SDValue X86TargetLowering::LowerCMP_SWAP(SDValue Op, SelectionDAG &DAG) {
|
||||
assert(Subtarget->is64Bit() && "Node not type legal!");
|
||||
Reg = X86::RAX; size = 8;
|
||||
break;
|
||||
};
|
||||
}
|
||||
SDValue cpIn = DAG.getCopyToReg(Op.getOperand(0), Reg,
|
||||
Op.getOperand(2), SDValue());
|
||||
SDValue Ops[] = { cpIn.getValue(0),
|
||||
@ -6247,8 +6256,8 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
|
||||
case ISD::FLT_ROUNDS_: return LowerFLT_ROUNDS_(Op, DAG);
|
||||
case ISD::CTLZ: return LowerCTLZ(Op, DAG);
|
||||
case ISD::CTTZ: return LowerCTTZ(Op, DAG);
|
||||
case ISD::SADDO: return LowerXADDO(Op, DAG, ISD::SADDO);
|
||||
case ISD::UADDO: return LowerXADDO(Op, DAG, ISD::UADDO);
|
||||
case ISD::SADDO: return LowerXADDO(Op, DAG);
|
||||
case ISD::UADDO: return LowerXADDO(Op, DAG);
|
||||
case ISD::READCYCLECOUNTER: return LowerREADCYCLECOUNTER(Op, DAG);
|
||||
}
|
||||
}
|
||||
|
@ -593,7 +593,7 @@ namespace llvm {
|
||||
SDValue LowerFLT_ROUNDS_(SDValue Op, SelectionDAG &DAG);
|
||||
SDValue LowerCTLZ(SDValue Op, SelectionDAG &DAG);
|
||||
SDValue LowerCTTZ(SDValue Op, SelectionDAG &DAG);
|
||||
SDValue LowerXADDO(SDValue Op, SelectionDAG &DAG, ISD::NodeType NTy);
|
||||
SDValue LowerXADDO(SDValue Op, SelectionDAG &DAG);
|
||||
|
||||
SDValue LowerCMP_SWAP(SDValue Op, SelectionDAG &DAG);
|
||||
SDValue LowerLOAD_SUB(SDValue Op, SelectionDAG &DAG);
|
||||
|
@ -1,6 +1,5 @@
|
||||
; RUN: llvm-as < %s | llc -march=x86 | grep {jo} | count 1
|
||||
; RUN: llvm-as < %s | llc -march=x86 | grep {jc} | count 1
|
||||
; XFAIL: *
|
||||
|
||||
@ok = internal constant [4 x i8] c"%d\0A\00"
|
||||
@no = internal constant [4 x i8] c"no\0A\00"
|
||||
|
Loading…
Reference in New Issue
Block a user