From: Craig Topper Date: Thu, 27 Dec 2018 01:50:40 +0000 (+0000) Subject: [X86] Factor the core code out of LowerSETCC into a helper that can create CMP/BT... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=994efbbb180fbe96a00c746857a63d0f852e361e;p=llvm [X86] Factor the core code out of LowerSETCC into a helper that can create CMP/BT/PTEST/KORTEST etc. without making an X86ISD::SETCC node. NFCI Make each of the helper functions only return their comparison node and the condition code. Leave X86ISD::SETCC creation to the LowerSETCC function itself. Looking into whether we can use this code directly in BRCOND and SELECT lowering instead of going through LowerSETCC which creates an X86ISD::SETCC node we need to look through. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350082 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 06cd45f4375..5260afb7a7f 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -18482,7 +18482,8 @@ static SDValue getSETCC(X86::CondCode Cond, SDValue EFLAGS, const SDLoc &dl, // Check whether an OR'd tree is PTEST-able. static SDValue LowerVectorAllZeroTest(SDValue Op, ISD::CondCode CC, const X86Subtarget &Subtarget, - SelectionDAG &DAG) { + SelectionDAG &DAG, + SDValue &X86CC) { assert(Op.getOpcode() == ISD::OR && "Only check OR'd tree."); if (!Subtarget.hasSSE41()) @@ -18568,9 +18569,10 @@ static SDValue LowerVectorAllZeroTest(SDValue Op, ISD::CondCode CC, VecIns.push_back(DAG.getNode(ISD::OR, DL, TestVT, LHS, RHS)); } - SDValue Res = DAG.getNode(X86ISD::PTEST, DL, MVT::i32, - VecIns.back(), VecIns.back()); - return getSETCC(CC == ISD::SETEQ ? X86::COND_E : X86::COND_NE, Res, DL, DAG); + X86CC = DAG.getConstant(CC == ISD::SETEQ ? X86::COND_E : X86::COND_NE, + DL, MVT::i8); + return DAG.getNode(X86ISD::PTEST, DL, MVT::i32, + VecIns.back(), VecIns.back()); } /// return true if \c Op has a use that doesn't just read flags. @@ -19450,7 +19452,8 @@ static SDValue LowerVSETCC(SDValue Op, const X86Subtarget &Subtarget, // Try to select this as a KORTEST+SETCC if possible. static SDValue EmitKORTEST(SDValue Op0, SDValue Op1, ISD::CondCode CC, const SDLoc &dl, SelectionDAG &DAG, - const X86Subtarget &Subtarget) { + const X86Subtarget &Subtarget, + SDValue &X86CC) { // Only support equality comparisons. if (CC != ISD::SETEQ && CC != ISD::SETNE) return SDValue(); @@ -19466,12 +19469,12 @@ static SDValue EmitKORTEST(SDValue Op0, SDValue Op1, ISD::CondCode CC, !(Subtarget.hasBWI() && (VT == MVT::v32i1 || VT == MVT::v64i1))) return SDValue(); - X86::CondCode X86CC; + X86::CondCode X86Cond; if (isNullConstant(Op1)) { - X86CC = CC == ISD::SETEQ ? X86::COND_E : X86::COND_NE; + X86Cond = CC == ISD::SETEQ ? X86::COND_E : X86::COND_NE; } else if (isAllOnesConstant(Op1)) { // C flag is set for all ones. - X86CC = CC == ISD::SETEQ ? X86::COND_B : X86::COND_AE; + X86Cond = CC == ISD::SETEQ ? X86::COND_B : X86::COND_AE; } else return SDValue(); @@ -19483,71 +19486,87 @@ static SDValue EmitKORTEST(SDValue Op0, SDValue Op1, ISD::CondCode CC, RHS = Op0.getOperand(1); } - SDValue KORTEST = DAG.getNode(X86ISD::KORTEST, dl, MVT::i32, LHS, RHS); - return getSETCC(X86CC, KORTEST, dl, DAG); + X86CC = DAG.getConstant(X86Cond, dl, MVT::i8); + return DAG.getNode(X86ISD::KORTEST, dl, MVT::i32, LHS, RHS); } -SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { - - MVT VT = Op.getSimpleValueType(); - - if (VT.isVector()) return LowerVSETCC(Op, Subtarget, DAG); - - assert(VT == MVT::i8 && "SetCC type must be 8-bit integer"); - SDValue Op0 = Op.getOperand(0); - SDValue Op1 = Op.getOperand(1); - SDLoc dl(Op); - ISD::CondCode CC = cast(Op.getOperand(2))->get(); - +/// Emit flags for the given setcc condition and operands. Also returns the +/// corresponding X86 condition code constant in X86CC. +SDValue X86TargetLowering::emitFlagsForSetcc(SDValue Op0, SDValue Op1, + ISD::CondCode CC, const SDLoc &dl, + SelectionDAG &DAG, + SDValue &X86CC) const { // Optimize to BT if possible. // Lower (X & (1 << N)) == 0 to BT(X, N). // Lower ((X >>u N) & 1) != 0 to BT(X, N). // Lower ((X >>s N) & 1) != 0 to BT(X, N). if (Op0.getOpcode() == ISD::AND && Op0.hasOneUse() && isNullConstant(Op1) && (CC == ISD::SETEQ || CC == ISD::SETNE)) { - SDValue BTCC; - if (SDValue BT = LowerAndToBT(Op0, CC, dl, DAG, BTCC)) - return DAG.getNode(X86ISD::SETCC, dl, MVT::i8, BTCC, BT); + if (SDValue BT = LowerAndToBT(Op0, CC, dl, DAG, X86CC)) + return BT; } // Try to use PTEST for a tree ORs equality compared with 0. // TODO: We could do AND tree with all 1s as well by using the C flag. if (Op0.getOpcode() == ISD::OR && isNullConstant(Op1) && (CC == ISD::SETEQ || CC == ISD::SETNE)) { - if (SDValue NewSetCC = LowerVectorAllZeroTest(Op0, CC, Subtarget, DAG)) - return NewSetCC; + if (SDValue PTEST = LowerVectorAllZeroTest(Op0, CC, Subtarget, DAG, X86CC)) + return PTEST; } // Try to lower using KORTEST. - if (SDValue NewSetCC = EmitKORTEST(Op0, Op1, CC, dl, DAG, Subtarget)) - return NewSetCC; + if (SDValue KORTEST = EmitKORTEST(Op0, Op1, CC, dl, DAG, Subtarget, X86CC)) + return KORTEST; // Look for X == 0, X == 1, X != 0, or X != 1. We can simplify some forms of // these. if ((isOneConstant(Op1) || isNullConstant(Op1)) && (CC == ISD::SETEQ || CC == ISD::SETNE)) { - // If the input is a setcc, then reuse the input setcc or use a new one with // the inverted condition. if (Op0.getOpcode() == X86ISD::SETCC) { - X86::CondCode CCode = (X86::CondCode)Op0.getConstantOperandVal(0); bool Invert = (CC == ISD::SETNE) ^ isNullConstant(Op1); - if (!Invert) - return Op0; - CCode = X86::GetOppositeBranchCondition(CCode); - return getSETCC(CCode, Op0.getOperand(1), dl, DAG); + X86CC = Op0.getOperand(0); + if (Invert) { + X86::CondCode CCode = (X86::CondCode)Op0.getConstantOperandVal(0); + CCode = X86::GetOppositeBranchCondition(CCode); + X86CC = DAG.getConstant(CCode, dl, MVT::i8); + } + + return Op0.getOperand(1); } } bool IsFP = Op1.getSimpleValueType().isFloatingPoint(); - X86::CondCode X86CC = TranslateX86CC(CC, dl, IsFP, Op0, Op1, DAG); - if (X86CC == X86::COND_INVALID) + X86::CondCode CondCode = TranslateX86CC(CC, dl, IsFP, Op0, Op1, DAG); + if (CondCode == X86::COND_INVALID) return SDValue(); - SDValue EFLAGS = EmitCmp(Op0, Op1, X86CC, dl, DAG); + SDValue EFLAGS = EmitCmp(Op0, Op1, CondCode, dl, DAG); EFLAGS = ConvertCmpIfNecessary(EFLAGS, DAG); - return getSETCC(X86CC, EFLAGS, dl, DAG); + X86CC = DAG.getConstant(CondCode, dl, MVT::i8); + return EFLAGS; +} + +SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { + + MVT VT = Op.getSimpleValueType(); + + if (VT.isVector()) return LowerVSETCC(Op, Subtarget, DAG); + + assert(VT == MVT::i8 && "SetCC type must be 8-bit integer"); + SDValue Op0 = Op.getOperand(0); + SDValue Op1 = Op.getOperand(1); + SDLoc dl(Op); + ISD::CondCode CC = cast(Op.getOperand(2))->get(); + + SDValue X86CC; + SDValue EFLAGS = emitFlagsForSetcc(Op0, Op1, CC, dl, DAG, X86CC); + if (!EFLAGS) + return SDValue(); + + return DAG.getNode(X86ISD::SETCC, dl, MVT::i8, X86CC, EFLAGS); } SDValue X86TargetLowering::LowerSETCCCARRY(SDValue Op, SelectionDAG &DAG) const { diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 17fd315a2b4..ad37576288f 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -1363,6 +1363,13 @@ namespace llvm { /// Convert a comparison if required by the subtarget. SDValue ConvertCmpIfNecessary(SDValue Cmp, SelectionDAG &DAG) const; + /// Emit flags for the given setcc condition and operands. Also returns the + /// corresponding X86 condition code constant in X86CC. + SDValue emitFlagsForSetcc(SDValue Op0, SDValue Op1, + ISD::CondCode CC, const SDLoc &dl, + SelectionDAG &DAG, + SDValue &X86CC) const; + /// Check if replacement of SQRT with RSQRT should be disabled. bool isFsqrtCheap(SDValue Operand, SelectionDAG &DAG) const override;