llvm.org GIT mirror llvm / 57760d9
Fix darwin ppc llvm-gcc build breakage: intercept ppcf128 to i32 conversion and expand it into a code sequence like in LegalizeDAG. This needs custom ppc lowering of FP_ROUND_INREG, so turn that on and make it work with LegalizeTypes. Probably PPC should simply custom lower the original conversion. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58329 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan Sands 11 years ago
3 changed file(s) with 75 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
901901
902902 SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) {
903903 MVT RVT = N->getValueType(0);
904
905 // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
906 // PPC (the libcall is not available). FIXME: Do this in a less hacky way.
907 if (RVT == MVT::i32) {
908 assert(N->getOperand(0).getValueType() == MVT::ppcf128 &&
909 "Logic only correct for ppcf128!");
910 SDValue Res = DAG.getNode(ISD::FP_ROUND_INREG, MVT::ppcf128,
911 N->getOperand(0), DAG.getValueType(MVT::f64));
912 Res = DAG.getNode(ISD::FP_ROUND, MVT::f64, Res, DAG.getIntPtrConstant(1));
913 return DAG.getNode(ISD::FP_TO_SINT, MVT::i32, Res);
914 }
915
904916 RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT);
905917 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!");
906918 return MakeLibCall(LC, RVT, &N->getOperand(0), 1, false);
908920
909921 SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) {
910922 MVT RVT = N->getValueType(0);
923
924 // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
925 // PPC (the libcall is not available). FIXME: Do this in a less hacky way.
926 if (RVT == MVT::i32) {
927 assert(N->getOperand(0).getValueType() == MVT::ppcf128 &&
928 "Logic only correct for ppcf128!");
929 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
930 APFloat APF = APFloat(APInt(128, 2, TwoE31));
931 SDValue Tmp = DAG.getConstantFP(APF, MVT::ppcf128);
932 // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X
933 // FIXME: generated code sucks.
934 return DAG.getNode(ISD::SELECT_CC, MVT::i32, N->getOperand(0), Tmp,
935 DAG.getNode(ISD::ADD, MVT::i32,
936 DAG.getNode(ISD::FP_TO_SINT, MVT::i32,
937 DAG.getNode(ISD::FSUB,
938 MVT::ppcf128,
939 N->getOperand(0),
940 Tmp)),
941 DAG.getConstant(0x80000000, MVT::i32)),
942 DAG.getNode(ISD::FP_TO_SINT, MVT::i32, N->getOperand(0)),
943 DAG.getCondCode(ISD::SETGE));
944 }
945
911946 RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT);
912947 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!");
913948 return MakeLibCall(LC, N->getValueType(0), &N->getOperand(0), 1, false);
28642864 assert(Op.getValueType() == MVT::ppcf128);
28652865 SDNode *Node = Op.getNode();
28662866 assert(Node->getOperand(0).getValueType() == MVT::ppcf128);
2867 assert(Node->getOperand(0).getNode()->getOpcode() == ISD::BUILD_PAIR);
2868 SDValue Lo = Node->getOperand(0).getNode()->getOperand(0);
2869 SDValue Hi = Node->getOperand(0).getNode()->getOperand(1);
2867 SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::f64, Node->getOperand(0),
2868 DAG.getIntPtrConstant(0));
2869 SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::f64, Node->getOperand(0),
2870 DAG.getIntPtrConstant(1));
28702871
28712872 // This sequence changes FPSCR to do round-to-zero, adds the two halves
28722873 // of the long double, and puts FPSCR back the way it was. We do not
29152916
29162917 // We know the low half is about to be thrown away, so just use something
29172918 // convenient.
2918 return DAG.getNode(ISD::BUILD_PAIR, Lo.getValueType(), FPreg, FPreg);
2919 return DAG.getNode(ISD::BUILD_PAIR, MVT::ppcf128, FPreg, FPreg);
29192920 }
29202921
29212922 SDValue PPCTargetLowering::LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
38823883
38833884 SDNode *PPCTargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) {
38843885 switch (N->getOpcode()) {
3885 default: assert(0 && "Wasn't expecting to be able to lower this!");
3886 default:
3887 return PPCTargetLowering::LowerOperation(SDValue (N, 0), DAG).getNode();
38863888 case ISD::FP_TO_SINT: {
38873889 SDValue Res = LowerFP_TO_SINT(SDValue(N, 0), DAG);
38883890 // Use MERGE_VALUES to drop the chain result value and get a node with one
0 ; RUN: llvm-as < %s | llc -march=ppc32 -o - | not grep fixunstfsi
1
2 define i64 @__fixunstfdi(ppc_fp128 %a) nounwind readnone {
3 entry:
4 %0 = fcmp olt ppc_fp128 %a, 0xM00000000000000000000000000000000 ; [#uses=1]
5 br i1 %0, label %bb5, label %bb1
6
7 bb1: ; preds = %entry
8 %1 = mul ppc_fp128 %a, 0xM3DF00000000000000000000000000000 ; [#uses=1]
9 %2 = fptoui ppc_fp128 %1 to i32 ; [#uses=1]
10 %3 = zext i32 %2 to i64 ; [#uses=1]
11 %4 = shl i64 %3, 32 ; [#uses=3]
12 %5 = uitofp i64 %4 to ppc_fp128 ; [#uses=1]
13 %6 = sub ppc_fp128 %a, %5 ; [#uses=3]
14 %7 = fcmp olt ppc_fp128 %6, 0xM00000000000000000000000000000000 ; [#uses=1]
15 br i1 %7, label %bb2, label %bb3
16
17 bb2: ; preds = %bb1
18 %8 = sub ppc_fp128 0xM80000000000000000000000000000000, %6 ; [#uses=1]
19 %9 = fptoui ppc_fp128 %8 to i32 ; [#uses=1]
20 %10 = zext i32 %9 to i64 ; [#uses=1]
21 %11 = sub i64 %4, %10 ; [#uses=1]
22 ret i64 %11
23
24 bb3: ; preds = %bb1
25 %12 = fptoui ppc_fp128 %6 to i32 ; [#uses=1]
26 %13 = zext i32 %12 to i64 ; [#uses=1]
27 %14 = or i64 %13, %4 ; [#uses=1]
28 ret i64 %14
29
30 bb5: ; preds = %entry
31 ret i64 0
32 }