diff options
Diffstat (limited to 'llvm/lib/Target/X86/X86ISelLowering.cpp')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 82d2218f0b1..7b9c3de0d44 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -508,7 +508,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM, setOperationAction(ISD::FSINCOS, VT, Expand); } - // Lower this to FGETSIGNx86 plus an AND. + // Lower this to MOVMSK plus an AND. setOperationAction(ISD::FGETSIGN, MVT::i64, Custom); setOperationAction(ISD::FGETSIGN, MVT::i32, Custom); @@ -14222,10 +14222,17 @@ static SDValue LowerFGETSIGN(SDValue Op, SelectionDAG &DAG) { SDLoc dl(Op); MVT VT = Op.getSimpleValueType(); - // Lower ISD::FGETSIGN to (AND (X86ISD::FGETSIGNx86 ...) 1). - SDValue xFGETSIGN = DAG.getNode(X86ISD::FGETSIGNx86, dl, VT, N0, - DAG.getConstant(1, dl, VT)); - return DAG.getNode(ISD::AND, dl, VT, xFGETSIGN, DAG.getConstant(1, dl, VT)); + MVT OpVT = N0.getSimpleValueType(); + assert((OpVT == MVT::f32 || OpVT == MVT::f64) && + "Unexpected type for FGETSIGN"); + + // Lower ISD::FGETSIGN to (AND (X86ISD::MOVMSK ...) 1). + MVT VecVT = (OpVT == MVT::f32 ? MVT::v4f32 : MVT::v2f64); + SDValue Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VecVT, N0); + Res = DAG.getNode(X86ISD::MOVMSK, dl, MVT::i32, Res); + Res = DAG.getZExtOrTrunc(Res, dl, VT); + Res = DAG.getNode(ISD::AND, dl, VT, Res, DAG.getConstant(1, dl, VT)); + return Res; } // Check whether an OR'd tree is PTEST-able. @@ -21616,7 +21623,6 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const { case X86ISD::SETCC: return "X86ISD::SETCC"; case X86ISD::SETCC_CARRY: return "X86ISD::SETCC_CARRY"; case X86ISD::FSETCC: return "X86ISD::FSETCC"; - case X86ISD::FGETSIGNx86: return "X86ISD::FGETSIGNx86"; case X86ISD::CMOV: return "X86ISD::CMOV"; case X86ISD::BRCOND: return "X86ISD::BRCOND"; case X86ISD::RET_FLAG: return "X86ISD::RET_FLAG"; |