diff --git a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index 2773e8b245e..8f928747fca 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -759,6 +759,7 @@ void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) { case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break; case ISD::ConstantFP: ExpandFloatRes_ConstantFP(N, Lo, Hi); break; + case ISD::FABS: ExpandFloatRes_FABS(N, Lo, Hi); break; case ISD::FADD: ExpandFloatRes_FADD(N, Lo, Hi); break; case ISD::FDIV: ExpandFloatRes_FDIV(N, Lo, Hi); break; case ISD::FMUL: ExpandFloatRes_FMUL(N, Lo, Hi); break; @@ -799,6 +800,19 @@ void DAGTypeLegalizer::ExpandFloatRes_FADD(SDNode *N, SDOperand &Lo, Lo = Call.getOperand(0); Hi = Call.getOperand(1); } +void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode *N, SDOperand &Lo, + SDOperand &Hi) { + assert(N->getValueType(0) == MVT::ppcf128 && + "Logic only correct for ppcf128!"); + SDOperand Tmp; + GetExpandedFloat(N->getOperand(0), Lo, Tmp); + Hi = DAG.getNode(ISD::FABS, Tmp.getValueType(), Tmp); + // Lo = Hi==fabs(Hi) ? Lo : -Lo; + Lo = DAG.getNode(ISD::SELECT_CC, Lo.getValueType(), Tmp, Hi, Lo, + DAG.getNode(ISD::FNEG, Lo.getValueType(), Lo), + DAG.getCondCode(ISD::SETEQ)); +} + void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode *N, SDOperand &Lo, SDOperand &Hi) { SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) }; diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 3aa5ca297c5..3eaaaeeb24c 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -367,6 +367,7 @@ private: // Float Result Expansion. void ExpandFloatResult(SDNode *N, unsigned ResNo); void ExpandFloatRes_ConstantFP(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandFloatRes_FABS (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandFloatRes_FADD (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandFloatRes_FDIV (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandFloatRes_FMUL (SDNode *N, SDOperand &Lo, SDOperand &Hi); diff --git a/test/CodeGen/PowerPC/2008-07-15-Fabs.ll b/test/CodeGen/PowerPC/2008-07-15-Fabs.ll new file mode 100644 index 00000000000..7d86434d24e --- /dev/null +++ b/test/CodeGen/PowerPC/2008-07-15-Fabs.ll @@ -0,0 +1,19 @@ +; RUN: llvm-as < %s | llc +target datalayout = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f128:64:128" +target triple = "powerpc-apple-darwin9" + +define hidden i256 @__divtc3(ppc_fp128 %a, ppc_fp128 %b, ppc_fp128 %c, ppc_fp128 %d) nounwind readnone { +entry: + call ppc_fp128 @fabsl( ppc_fp128 %d ) nounwind readnone ; :0 [#uses=1] + fcmp olt ppc_fp128 0xM00000000000000000000000000000000, %0 ; :1 [#uses=1] + %.pn106 = select i1 %1, ppc_fp128 %a, ppc_fp128 0xM00000000000000000000000000000000 ; [#uses=1] + %.pn = sub ppc_fp128 0xM00000000000000000000000000000000, %.pn106 ; [#uses=1] + %y.0 = fdiv ppc_fp128 %.pn, 0xM00000000000000000000000000000000 ; [#uses=1] + mul ppc_fp128 %y.0, 0xM3FF00000000000000000000000000000 ; :2 [#uses=1] + add ppc_fp128 %2, mul (ppc_fp128 0xM00000000000000000000000000000000, ppc_fp128 0xM00000000000000000000000000000000) ; :3 [#uses=1] + %tmpi = add ppc_fp128 %3, 0xM00000000000000000000000000000000 ; [#uses=1] + store ppc_fp128 %tmpi, ppc_fp128* null, align 16 + ret i256 0 +} + +declare ppc_fp128 @fabsl(ppc_fp128) nounwind readnone