[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. llvm-svn: 350082
This commit is contained in:
		
							parent
							
								
									4f1ef9fc0f
								
							
						
					
					
						commit
						a8f07e51f9
					
				| 
						 | 
					@ -18482,7 +18482,8 @@ static SDValue getSETCC(X86::CondCode Cond, SDValue EFLAGS, const SDLoc &dl,
 | 
				
			||||||
// Check whether an OR'd tree is PTEST-able.
 | 
					// Check whether an OR'd tree is PTEST-able.
 | 
				
			||||||
static SDValue LowerVectorAllZeroTest(SDValue Op, ISD::CondCode CC,
 | 
					static SDValue LowerVectorAllZeroTest(SDValue Op, ISD::CondCode CC,
 | 
				
			||||||
                                      const X86Subtarget &Subtarget,
 | 
					                                      const X86Subtarget &Subtarget,
 | 
				
			||||||
                                      SelectionDAG &DAG) {
 | 
					                                      SelectionDAG &DAG,
 | 
				
			||||||
 | 
					                                      SDValue &X86CC) {
 | 
				
			||||||
  assert(Op.getOpcode() == ISD::OR && "Only check OR'd tree.");
 | 
					  assert(Op.getOpcode() == ISD::OR && "Only check OR'd tree.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!Subtarget.hasSSE41())
 | 
					  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));
 | 
					    VecIns.push_back(DAG.getNode(ISD::OR, DL, TestVT, LHS, RHS));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SDValue Res = DAG.getNode(X86ISD::PTEST, DL, MVT::i32,
 | 
					  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());
 | 
					                     VecIns.back(), VecIns.back());
 | 
				
			||||||
  return getSETCC(CC == ISD::SETEQ ? X86::COND_E : X86::COND_NE, Res, DL, DAG);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// return true if \c Op has a use that doesn't just read flags.
 | 
					/// 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.
 | 
					// Try to select this as a KORTEST+SETCC if possible.
 | 
				
			||||||
static SDValue EmitKORTEST(SDValue Op0, SDValue Op1, ISD::CondCode CC,
 | 
					static SDValue EmitKORTEST(SDValue Op0, SDValue Op1, ISD::CondCode CC,
 | 
				
			||||||
                           const SDLoc &dl, SelectionDAG &DAG,
 | 
					                           const SDLoc &dl, SelectionDAG &DAG,
 | 
				
			||||||
                           const X86Subtarget &Subtarget) {
 | 
					                           const X86Subtarget &Subtarget,
 | 
				
			||||||
 | 
					                           SDValue &X86CC) {
 | 
				
			||||||
  // Only support equality comparisons.
 | 
					  // Only support equality comparisons.
 | 
				
			||||||
  if (CC != ISD::SETEQ && CC != ISD::SETNE)
 | 
					  if (CC != ISD::SETEQ && CC != ISD::SETNE)
 | 
				
			||||||
    return SDValue();
 | 
					    return SDValue();
 | 
				
			||||||
| 
						 | 
					@ -19466,12 +19469,12 @@ static SDValue EmitKORTEST(SDValue Op0, SDValue Op1, ISD::CondCode CC,
 | 
				
			||||||
      !(Subtarget.hasBWI() && (VT == MVT::v32i1 || VT == MVT::v64i1)))
 | 
					      !(Subtarget.hasBWI() && (VT == MVT::v32i1 || VT == MVT::v64i1)))
 | 
				
			||||||
    return SDValue();
 | 
					    return SDValue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  X86::CondCode X86CC;
 | 
					  X86::CondCode X86Cond;
 | 
				
			||||||
  if (isNullConstant(Op1)) {
 | 
					  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)) {
 | 
					  } else if (isAllOnesConstant(Op1)) {
 | 
				
			||||||
    // C flag is set for all ones.
 | 
					    // 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
 | 
					  } else
 | 
				
			||||||
    return SDValue();
 | 
					    return SDValue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19483,8 +19486,67 @@ static SDValue EmitKORTEST(SDValue Op0, SDValue Op1, ISD::CondCode CC,
 | 
				
			||||||
    RHS = Op0.getOperand(1);
 | 
					    RHS = Op0.getOperand(1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SDValue KORTEST = DAG.getNode(X86ISD::KORTEST, dl, MVT::i32, LHS, RHS);
 | 
					  X86CC = DAG.getConstant(X86Cond, dl, MVT::i8);
 | 
				
			||||||
  return getSETCC(X86CC, KORTEST, dl, DAG);
 | 
					  return DAG.getNode(X86ISD::KORTEST, dl, MVT::i32, LHS, RHS);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// 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)) {
 | 
				
			||||||
 | 
					    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 PTEST = LowerVectorAllZeroTest(Op0, CC, Subtarget, DAG, X86CC))
 | 
				
			||||||
 | 
					      return PTEST;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Try to lower using KORTEST.
 | 
				
			||||||
 | 
					  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) {
 | 
				
			||||||
 | 
					      bool Invert = (CC == ISD::SETNE) ^ isNullConstant(Op1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      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 CondCode = TranslateX86CC(CC, dl, IsFP, Op0, Op1, DAG);
 | 
				
			||||||
 | 
					  if (CondCode == X86::COND_INVALID)
 | 
				
			||||||
 | 
					    return SDValue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  SDValue EFLAGS = EmitCmp(Op0, Op1, CondCode, dl, DAG);
 | 
				
			||||||
 | 
					  EFLAGS = ConvertCmpIfNecessary(EFLAGS, DAG);
 | 
				
			||||||
 | 
					  X86CC = DAG.getConstant(CondCode, dl, MVT::i8);
 | 
				
			||||||
 | 
					  return EFLAGS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
 | 
					SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
 | 
				
			||||||
| 
						 | 
					@ -19499,55 +19561,12 @@ SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
 | 
				
			||||||
  SDLoc dl(Op);
 | 
					  SDLoc dl(Op);
 | 
				
			||||||
  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
 | 
					  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Optimize to BT if possible.
 | 
					  SDValue X86CC;
 | 
				
			||||||
  // Lower (X & (1 << N)) == 0 to BT(X, N).
 | 
					  SDValue EFLAGS = emitFlagsForSetcc(Op0, Op1, CC, dl, DAG, X86CC);
 | 
				
			||||||
  // Lower ((X >>u N) & 1) != 0 to BT(X, N).
 | 
					  if (!EFLAGS)
 | 
				
			||||||
  // 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);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // 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;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Try to lower using KORTEST.
 | 
					 | 
				
			||||||
  if (SDValue NewSetCC = EmitKORTEST(Op0, Op1, CC, dl, DAG, Subtarget))
 | 
					 | 
				
			||||||
    return NewSetCC;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // 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);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  bool IsFP = Op1.getSimpleValueType().isFloatingPoint();
 | 
					 | 
				
			||||||
  X86::CondCode X86CC = TranslateX86CC(CC, dl, IsFP, Op0, Op1, DAG);
 | 
					 | 
				
			||||||
  if (X86CC == X86::COND_INVALID)
 | 
					 | 
				
			||||||
    return SDValue();
 | 
					    return SDValue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SDValue EFLAGS = EmitCmp(Op0, Op1, X86CC, dl, DAG);
 | 
					  return DAG.getNode(X86ISD::SETCC, dl, MVT::i8, X86CC, EFLAGS);
 | 
				
			||||||
  EFLAGS = ConvertCmpIfNecessary(EFLAGS, DAG);
 | 
					 | 
				
			||||||
  return getSETCC(X86CC, EFLAGS, dl, DAG);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SDValue X86TargetLowering::LowerSETCCCARRY(SDValue Op, SelectionDAG &DAG) const {
 | 
					SDValue X86TargetLowering::LowerSETCCCARRY(SDValue Op, SelectionDAG &DAG) const {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1363,6 +1363,13 @@ namespace llvm {
 | 
				
			||||||
    /// Convert a comparison if required by the subtarget.
 | 
					    /// Convert a comparison if required by the subtarget.
 | 
				
			||||||
    SDValue ConvertCmpIfNecessary(SDValue Cmp, SelectionDAG &DAG) const;
 | 
					    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.
 | 
					    /// Check if replacement of SQRT with RSQRT should be disabled.
 | 
				
			||||||
    bool isFsqrtCheap(SDValue Operand, SelectionDAG &DAG) const override;
 | 
					    bool isFsqrtCheap(SDValue Operand, SelectionDAG &DAG) const override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue