diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 48 |
1 files changed, 38 insertions, 10 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 95c80e5..c1e8531 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -45449,9 +45449,9 @@ static unsigned convertIntLogicToFPLogicOpcode(unsigned Opcode) { return FPOpcode; } -/// If both input operands of a logic op are being cast from floating point -/// types, try to convert this into a floating point logic node to avoid -/// unnecessary moves from SSE to integer registers. +/// If both input operands of a logic op are being cast from floating-point +/// types or FP compares, try to convert this into a floating-point logic node +/// to avoid unnecessary moves from SSE to integer registers. static SDValue convertIntLogicToFPLogic(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const X86Subtarget &Subtarget) { @@ -45460,10 +45460,8 @@ static SDValue convertIntLogicToFPLogic(SDNode *N, SelectionDAG &DAG, SDValue N1 = N->getOperand(1); SDLoc DL(N); - if (N0.getOpcode() != ISD::BITCAST || N1.getOpcode() != ISD::BITCAST) - return SDValue(); - - if (DCI.isBeforeLegalizeOps()) + if (!((N0.getOpcode() == ISD::BITCAST && N1.getOpcode() == ISD::BITCAST) || + (N0.getOpcode() == ISD::SETCC && N1.getOpcode() == ISD::SETCC))) return SDValue(); SDValue N00 = N0.getOperand(0); @@ -45477,9 +45475,39 @@ static SDValue convertIntLogicToFPLogic(SDNode *N, SelectionDAG &DAG, (Subtarget.hasFP16() && N00Type == MVT::f16))) return SDValue(); - unsigned FPOpcode = convertIntLogicToFPLogicOpcode(N->getOpcode()); - SDValue FPLogic = DAG.getNode(FPOpcode, DL, N00Type, N00, N10); - return DAG.getBitcast(VT, FPLogic); + if (N0.getOpcode() == ISD::BITCAST && !DCI.isBeforeLegalizeOps()) { + unsigned FPOpcode = convertIntLogicToFPLogicOpcode(N->getOpcode()); + SDValue FPLogic = DAG.getNode(FPOpcode, DL, N00Type, N00, N10); + return DAG.getBitcast(VT, FPLogic); + } + + // The vector ISA for FP predicates is incomplete before AVX, so converting + // COMIS* to CMPS* may not be a win before AVX. + // TODO: Check types/predicates to see if they are available with SSE/SSE2. + if (!Subtarget.hasAVX() || VT != MVT::i1 || N0.getOpcode() != ISD::SETCC || + !N0.hasOneUse() || !N1.hasOneUse()) + return SDValue(); + + // Convert scalar FP compares and logic to vector compares (COMIS* to CMPS*) + // and vector logic: + // logic (setcc N00, N01), (setcc N10, N11) --> + // extelt (logic (setcc (s2v N00), (s2v N01)), setcc (s2v N10), (s2v N11))), 0 + unsigned NumElts = 128 / N00Type.getSizeInBits(); + EVT VecVT = EVT::getVectorVT(*DAG.getContext(), N00Type, NumElts); + EVT BoolVecVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1, NumElts); + SDValue ZeroIndex = DAG.getVectorIdxConstant(0, DL); + SDValue N01 = N0.getOperand(1); + SDValue N11 = N1.getOperand(1); + SDValue Vec00 = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VecVT, N00); + SDValue Vec01 = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VecVT, N01); + SDValue Vec10 = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VecVT, N10); + SDValue Vec11 = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VecVT, N11); + SDValue Setcc0 = DAG.getSetCC(DL, BoolVecVT, Vec00, Vec01, + cast<CondCodeSDNode>(N0.getOperand(2))->get()); + SDValue Setcc1 = DAG.getSetCC(DL, BoolVecVT, Vec10, Vec11, + cast<CondCodeSDNode>(N1.getOperand(2))->get()); + SDValue Logic = DAG.getNode(N->getOpcode(), DL, BoolVecVT, Setcc0, Setcc1); + return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Logic, ZeroIndex); } // Attempt to fold BITOP(MOVMSK(X),MOVMSK(Y)) -> MOVMSK(BITOP(X,Y)) |