From 4937adf75f024f5cbd3cc190d5bd57d1761aefc3 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 12 Dec 2018 19:20:21 +0000 Subject: [X86] Emit SBB instead of SETCC_CARRY from LowerSELECT. Break false dependency on the SBB input. I'm hoping we can just replace SETCC_CARRY with SBB. This is another step towards that. I've explicitly used zero as the input to the setcc to avoid a false dependency that we've had with the SETCC_CARRY. I changed one of the patterns that used NEG to instead use an explicit compare with 0 on the LHS. We needed the zero anyway to avoid the false dependency. The negate would clobber its input register. By using a CMP we can avoid that which could be useful. Differential Revision: https://reviews.llvm.org/D55414 llvm-svn: 348959 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 15 +++++++-------- llvm/lib/Target/X86/X86InstrCompiler.td | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 8 deletions(-) (limited to 'llvm/lib/Target') diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index d9da7363734..d61bfe54651 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -19802,22 +19802,21 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const { // (select (x == 0), 0, -1) -> neg & sbb if (isNullConstant(Y) && (isAllOnesConstant(Op1) == (CondCode == X86::COND_NE))) { - SDVTList VTs = DAG.getVTList(CmpOp0.getValueType(), MVT::i32); SDValue Zero = DAG.getConstant(0, DL, CmpOp0.getValueType()); - SDValue Neg = DAG.getNode(X86ISD::SUB, DL, VTs, Zero, CmpOp0); - SDValue Res = DAG.getNode(X86ISD::SETCC_CARRY, DL, Op.getValueType(), - DAG.getConstant(X86::COND_B, DL, MVT::i8), - SDValue(Neg.getNode(), 1)); - return Res; + SDValue Cmp = DAG.getNode(X86ISD::CMP, DL, MVT::i32, Zero, CmpOp0); + SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::i32); + Zero = DAG.getConstant(0, DL, Op.getValueType()); + return DAG.getNode(X86ISD::SBB, DL, VTs, Zero, Zero, Cmp); } Cmp = DAG.getNode(X86ISD::CMP, DL, MVT::i32, CmpOp0, DAG.getConstant(1, DL, CmpOp0.getValueType())); Cmp = ConvertCmpIfNecessary(Cmp, DAG); + SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::i32); + SDValue Zero = DAG.getConstant(0, DL, Op.getValueType()); SDValue Res = // Res = 0 or -1. - DAG.getNode(X86ISD::SETCC_CARRY, DL, Op.getValueType(), - DAG.getConstant(X86::COND_B, DL, MVT::i8), Cmp); + DAG.getNode(X86ISD::SBB, DL, VTs, Zero, Zero, Cmp); if (isAllOnesConstant(Op1) != (CondCode == X86::COND_E)) Res = DAG.getNOT(DL, Res, Res.getValueType()); diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td index 8ba6ecf78b6..529d054d081 100644 --- a/llvm/lib/Target/X86/X86InstrCompiler.td +++ b/llvm/lib/Target/X86/X86InstrCompiler.td @@ -362,6 +362,21 @@ def : Pat<(i64 (sext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), def : Pat<(and (i8 (X86setcc_c X86_COND_B, EFLAGS)), 1), (SETBr)>; +// Patterns to give priority when both inputs are zero so that we don't use +// an immediate for the RHS. +// TODO: Should we use a 32-bit sbb for 8/16 to push the extract_subreg out? +def : Pat<(X86sbb_flag (i8 0), (i8 0), EFLAGS), + (SBB8rr (EXTRACT_SUBREG (MOV32r0), sub_8bit), + (EXTRACT_SUBREG (MOV32r0), sub_8bit))>; +def : Pat<(X86sbb_flag (i16 0), (i16 0), EFLAGS), + (SBB16rr (EXTRACT_SUBREG (MOV32r0), sub_16bit), + (EXTRACT_SUBREG (MOV32r0), sub_16bit))>; +def : Pat<(X86sbb_flag (i32 0), (i32 0), EFLAGS), + (SBB32rr (MOV32r0), (MOV32r0))>; +def : Pat<(X86sbb_flag (i64 0), (i64 0), EFLAGS), + (SBB64rr (SUBREG_TO_REG (i64 0), (MOV32r0), sub_32bit), + (SUBREG_TO_REG (i64 0), (MOV32r0), sub_32bit))>; + //===----------------------------------------------------------------------===// // String Pseudo Instructions // -- cgit v1.2.3