From 3e2bafd6402678a3fb752ddda820eaf5b75aaa83 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 28 Sep 2005 22:29:17 +0000 Subject: [PATCH] Add FP versions of the binary operators, keeping the int and fp worlds seperate. Though I have done extensive testing, it is possible that this will break things in configs I can't test. Please let me know if this causes a problem and I'll fix it ASAP. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23505 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Alpha/AlphaISelLowering.cpp | 4 +- lib/Target/Alpha/AlphaISelPattern.cpp | 51 ++++------ lib/Target/IA64/IA64ISelPattern.cpp | 123 +++++++++++++------------ lib/Target/X86/X86ISelPattern.cpp | 27 ++++-- 4 files changed, 108 insertions(+), 97 deletions(-) diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp index 910166ef6b6..2e5a832e0b0 100644 --- a/lib/Target/Alpha/AlphaISelLowering.cpp +++ b/lib/Target/Alpha/AlphaISelLowering.cpp @@ -68,8 +68,8 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand); setOperationAction(ISD::SEXTLOAD, MVT::i16, Expand); - setOperationAction(ISD::SREM, MVT::f32, Expand); - setOperationAction(ISD::SREM, MVT::f64, Expand); + setOperationAction(ISD::FREM, MVT::f32, Expand); + setOperationAction(ISD::FREM, MVT::f64, Expand); setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand); diff --git a/lib/Target/Alpha/AlphaISelPattern.cpp b/lib/Target/Alpha/AlphaISelPattern.cpp index 1a20b2951df..c30c459c904 100644 --- a/lib/Target/Alpha/AlphaISelPattern.cpp +++ b/lib/Target/Alpha/AlphaISelPattern.cpp @@ -1275,10 +1275,7 @@ unsigned AlphaISel::SelectExpr(SDOperand N) { case ISD::SHL: Opc = Alpha::SL; break; case ISD::SRL: Opc = Alpha::SRL; break; case ISD::SRA: Opc = Alpha::SRA; break; - case ISD::MUL: - Opc = isFP ? (DestType == MVT::f64 ? Alpha::MULT : Alpha::MULS) - : Alpha::MULQ; - break; + case ISD::MUL: Opc = Alpha::MULQ; break; }; Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); @@ -1288,25 +1285,7 @@ unsigned AlphaISel::SelectExpr(SDOperand N) { case ISD::ADD: case ISD::SUB: - if (isFP) { - ConstantFPSDNode *CN; - if (opcode == ISD::ADD) - Opc = DestType == MVT::f64 ? Alpha::ADDT : Alpha::ADDS; - else - Opc = DestType == MVT::f64 ? Alpha::SUBT : Alpha::SUBS; - if (opcode == ISD::SUB - && (CN = dyn_cast(N.getOperand(0))) - && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0))) - { - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, Alpha::CPYSN, 2, Result).addReg(Tmp2).addReg(Tmp2); - } else { - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); - } - return Result; - } else { + { bool isAdd = opcode == ISD::ADD; //first check for Scaled Adds and Subs! @@ -1369,15 +1348,25 @@ unsigned AlphaISel::SelectExpr(SDOperand N) { } return Result; } - + case ISD::FADD: + case ISD::FSUB: + case ISD::FMUL: + case ISD::FDIV: { + if (opcode == ISD::FADD) + Opc = DestType == MVT::f64 ? Alpha::ADDT : Alpha::ADDS; + else if (opcode == ISD::FSUB) + Opc = DestType == MVT::f64 ? Alpha::SUBT : Alpha::SUBS; + else if (opcode == ISD::FMUL) + Opc = DestType == MVT::f64 ? Alpha::MULT : Alpha::MULS; + else + Opc = DestType == MVT::f64 ? Alpha::DIVT : Alpha::DIVS; + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + } case ISD::SDIV: - if (isFP) { - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, DestType == MVT::f64 ? Alpha::DIVT : Alpha::DIVS, 2, Result) - .addReg(Tmp1).addReg(Tmp2); - return Result; - } else { + { //check if we can convert into a shift! if (isSIntImmediate(N.getOperand(1), SImm) && SImm != 0 && isPowerOf2_64(llabs(SImm))) { diff --git a/lib/Target/IA64/IA64ISelPattern.cpp b/lib/Target/IA64/IA64ISelPattern.cpp index 3af4a97945e..04b331cff00 100644 --- a/lib/Target/IA64/IA64ISelPattern.cpp +++ b/lib/Target/IA64/IA64ISelPattern.cpp @@ -72,8 +72,8 @@ namespace { setOperationAction(ISD::SEXTLOAD , MVT::i16 , Expand); setOperationAction(ISD::SEXTLOAD , MVT::i32 , Expand); - setOperationAction(ISD::SREM , MVT::f32 , Expand); - setOperationAction(ISD::SREM , MVT::f64 , Expand); + setOperationAction(ISD::FREM , MVT::f32 , Expand); + setOperationAction(ISD::FREM , MVT::f64 , Expand); setOperationAction(ISD::UREM , MVT::f32 , Expand); setOperationAction(ISD::UREM , MVT::f64 , Expand); @@ -1240,20 +1240,28 @@ unsigned ISel::SelectExpr(SDOperand N) { BuildMI(BB, IA64::GETFSIG, 1, Result).addReg(Tmp2); return Result; } - - case ISD::ADD: { - if(DestType == MVT::f64 && N.getOperand(0).getOpcode() == ISD::MUL && - N.getOperand(0).Val->hasOneUse()) { // if we can fold this add - // into an fma, do so: - // ++FusedFP; // Statistic + + case ISD::FADD: { + if (N.getOperand(0).getOpcode() == ISD::FMUL && + N.getOperand(0).Val->hasOneUse()) { // if we can fold this add + // into an fma, do so: + // ++FusedFP; // Statistic Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); Tmp3 = SelectExpr(N.getOperand(1)); BuildMI(BB, IA64::FMA, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); return Result; // early exit } + + //else, fallthrough: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, IA64::FADD, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + } - if(DestType != MVT::f64 && N.getOperand(0).getOpcode() == ISD::SHL && + case ISD::ADD: { + if (N.getOperand(0).getOpcode() == ISD::SHL && N.getOperand(0).Val->hasOneUse()) { // if we might be able to fold // this add into a shladd, try: ConstantSDNode *CSD = NULL; @@ -1273,75 +1281,71 @@ unsigned ISel::SelectExpr(SDOperand N) { //else, fallthrough: Tmp1 = SelectExpr(N.getOperand(0)); - if(DestType != MVT::f64) { // integer addition: - switch (ponderIntegerAdditionWith(N.getOperand(1), Tmp3)) { - case 1: // adding a constant that's 14 bits - BuildMI(BB, IA64::ADDIMM14, 2, Result).addReg(Tmp1).addSImm(Tmp3); - return Result; // early exit - } // fallthrough and emit a reg+reg ADD: - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, IA64::ADD, 2, Result).addReg(Tmp1).addReg(Tmp2); - } else { // this is a floating point addition - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, IA64::FADD, 2, Result).addReg(Tmp1).addReg(Tmp2); - } + switch (ponderIntegerAdditionWith(N.getOperand(1), Tmp3)) { + case 1: // adding a constant that's 14 bits + BuildMI(BB, IA64::ADDIMM14, 2, Result).addReg(Tmp1).addSImm(Tmp3); + return Result; // early exit + } // fallthrough and emit a reg+reg ADD: + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, IA64::ADD, 2, Result).addReg(Tmp1).addReg(Tmp2); return Result; } + case ISD::FMUL: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, IA64::FMPY, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + case ISD::MUL: { - if(DestType != MVT::f64) { // TODO: speed! + // TODO: speed! /* FIXME if(N.getOperand(1).getOpcode() != ISD::Constant) { // if not a const mul */ - // boring old integer multiply with xma - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - - unsigned TempFR1=MakeReg(MVT::f64); - unsigned TempFR2=MakeReg(MVT::f64); - unsigned TempFR3=MakeReg(MVT::f64); - BuildMI(BB, IA64::SETFSIG, 1, TempFR1).addReg(Tmp1); - BuildMI(BB, IA64::SETFSIG, 1, TempFR2).addReg(Tmp2); - BuildMI(BB, IA64::XMAL, 1, TempFR3).addReg(TempFR1).addReg(TempFR2) - .addReg(IA64::F0); - BuildMI(BB, IA64::GETFSIG, 1, Result).addReg(TempFR3); - return Result; // early exit - /* FIXME } else { // we are multiplying by an integer constant! yay - return Reg = SelectExpr(BuildConstmulSequence(N)); // avert your eyes! - } */ - } - else { // floating point multiply + // boring old integer multiply with xma Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, IA64::FMPY, 2, Result).addReg(Tmp1).addReg(Tmp2); - return Result; - } + + unsigned TempFR1=MakeReg(MVT::f64); + unsigned TempFR2=MakeReg(MVT::f64); + unsigned TempFR3=MakeReg(MVT::f64); + BuildMI(BB, IA64::SETFSIG, 1, TempFR1).addReg(Tmp1); + BuildMI(BB, IA64::SETFSIG, 1, TempFR2).addReg(Tmp2); + BuildMI(BB, IA64::XMAL, 1, TempFR3).addReg(TempFR1).addReg(TempFR2) + .addReg(IA64::F0); + BuildMI(BB, IA64::GETFSIG, 1, Result).addReg(TempFR3); + return Result; // early exit + /* FIXME } else { // we are multiplying by an integer constant! yay + return Reg = SelectExpr(BuildConstmulSequence(N)); // avert your eyes! + } */ } - case ISD::SUB: { - if(DestType == MVT::f64 && N.getOperand(0).getOpcode() == ISD::MUL && + case ISD::FSUB: + if(N.getOperand(0).getOpcode() == ISD::FMUL && N.getOperand(0).Val->hasOneUse()) { // if we can fold this sub // into an fms, do so: - // ++FusedFP; // Statistic + // ++FusedFP; // Statistic Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); Tmp3 = SelectExpr(N.getOperand(1)); BuildMI(BB, IA64::FMS, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); return Result; // early exit } + Tmp2 = SelectExpr(N.getOperand(1)); - if(DestType != MVT::f64) { // integer subtraction: - switch (ponderIntegerSubtractionFrom(N.getOperand(0), Tmp3)) { - case 1: // subtracting *from* an 8 bit constant: - BuildMI(BB, IA64::SUBIMM8, 2, Result).addSImm(Tmp3).addReg(Tmp2); - return Result; // early exit - } // fallthrough and emit a reg+reg SUB: - Tmp1 = SelectExpr(N.getOperand(0)); - BuildMI(BB, IA64::SUB, 2, Result).addReg(Tmp1).addReg(Tmp2); - } else { // this is a floating point subtraction - Tmp1 = SelectExpr(N.getOperand(0)); - BuildMI(BB, IA64::FSUB, 2, Result).addReg(Tmp1).addReg(Tmp2); - } + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, IA64::FSUB, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + + case ISD::SUB: { + Tmp2 = SelectExpr(N.getOperand(1)); + switch (ponderIntegerSubtractionFrom(N.getOperand(0), Tmp3)) { + case 1: // subtracting *from* an 8 bit constant: + BuildMI(BB, IA64::SUBIMM8, 2, Result).addSImm(Tmp3).addReg(Tmp2); + return Result; // early exit + } // fallthrough and emit a reg+reg SUB: + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, IA64::SUB, 2, Result).addReg(Tmp1).addReg(Tmp2); return Result; } @@ -1584,6 +1588,7 @@ pC = pA OR pB return Result; } + case ISD::FDIV: case ISD::SDIV: case ISD::UDIV: case ISD::SREM: @@ -1601,8 +1606,10 @@ pC = pA OR pB bool isSigned=false; switch(N.getOpcode()) { + case ISD::FDIV: case ISD::SDIV: isModulus=false; isSigned=true; break; case ISD::UDIV: isModulus=false; isSigned=false; break; + case ISD::FREM: case ISD::SREM: isModulus=true; isSigned=true; break; case ISD::UREM: isModulus=true; isSigned=false; break; } diff --git a/lib/Target/X86/X86ISelPattern.cpp b/lib/Target/X86/X86ISelPattern.cpp index f3ce7a73860..36596bedb1a 100644 --- a/lib/Target/X86/X86ISelPattern.cpp +++ b/lib/Target/X86/X86ISelPattern.cpp @@ -158,7 +158,7 @@ namespace { setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand); setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand); setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand); - setOperationAction(ISD::SREM , MVT::f64 , Expand); + setOperationAction(ISD::FREM , MVT::f64 , Expand); setOperationAction(ISD::CTPOP , MVT::i8 , Expand); setOperationAction(ISD::CTTZ , MVT::i8 , Expand); setOperationAction(ISD::CTLZ , MVT::i8 , Expand); @@ -205,12 +205,12 @@ namespace { setOperationAction(ISD::FCOS , MVT::f64, Expand); setOperationAction(ISD::FABS , MVT::f64, Expand); setOperationAction(ISD::FNEG , MVT::f64, Expand); - setOperationAction(ISD::SREM , MVT::f64, Expand); + setOperationAction(ISD::FREM , MVT::f64, Expand); setOperationAction(ISD::FSIN , MVT::f32, Expand); setOperationAction(ISD::FCOS , MVT::f32, Expand); setOperationAction(ISD::FABS , MVT::f32, Expand); setOperationAction(ISD::FNEG , MVT::f32, Expand); - setOperationAction(ISD::SREM , MVT::f32, Expand); + setOperationAction(ISD::FREM , MVT::f32, Expand); addLegalFPImmediate(+0.0); // xorps / xorpd } else { @@ -2513,6 +2513,7 @@ unsigned ISel::SelectExpr(SDOperand N) { } return Result; + case ISD::FADD: case ISD::ADD: Op0 = N.getOperand(0); Op1 = N.getOperand(1); @@ -2703,6 +2704,8 @@ unsigned ISel::SelectExpr(SDOperand N) { return Result; } + case ISD::FSUB: + case ISD::FMUL: case ISD::SUB: case ISD::MUL: case ISD::AND: @@ -2810,7 +2813,9 @@ unsigned ISel::SelectExpr(SDOperand N) { } switch (Node->getOpcode()) { default: assert(0 && "Unreachable!"); + case ISD::FSUB: case ISD::SUB: Opc = X86ScalarSSE ? SSE_SUBTab[Opc] : SUBTab[Opc]; break; + case ISD::FMUL: case ISD::MUL: Opc = X86ScalarSSE ? SSE_MULTab[Opc] : MULTab[Opc]; break; case ISD::AND: Opc = ANDTab[Opc]; break; case ISD::OR: Opc = ORTab[Opc]; break; @@ -2824,7 +2829,7 @@ unsigned ISel::SelectExpr(SDOperand N) { } if (isFoldableLoad(Op0, Op1, true)) - if (Node->getOpcode() != ISD::SUB) { + if (Node->getOpcode() != ISD::SUB && Node->getOpcode() != ISD::FSUB) { std::swap(Op0, Op1); goto FoldOps; } else { @@ -2860,7 +2865,9 @@ unsigned ISel::SelectExpr(SDOperand N) { } switch (Node->getOpcode()) { default: assert(0 && "Unreachable!"); + case ISD::FSUB: case ISD::SUB: Opc = X86ScalarSSE ? SSE_SUBTab[Opc] : SUBTab[Opc]; break; + case ISD::FMUL: case ISD::MUL: Opc = X86ScalarSSE ? SSE_MULTab[Opc] : MULTab[Opc]; break; case ISD::AND: Opc = ANDTab[Opc]; break; case ISD::OR: Opc = ORTab[Opc]; break; @@ -2902,7 +2909,9 @@ unsigned ISel::SelectExpr(SDOperand N) { } switch (Node->getOpcode()) { default: assert(0 && "Unreachable!"); + case ISD::FSUB: case ISD::SUB: Opc = X86ScalarSSE ? SSE_SUBTab[Opc] : SUBTab[Opc]; break; + case ISD::FMUL: case ISD::MUL: Opc = X86ScalarSSE ? SSE_MULTab[Opc] : MULTab[Opc]; break; case ISD::AND: Opc = ANDTab[Opc]; break; case ISD::OR: Opc = ORTab[Opc]; break; @@ -3006,6 +3015,8 @@ unsigned ISel::SelectExpr(SDOperand N) { N.getValueType(), Result); return Result; + case ISD::FDIV: + case ISD::FREM: case ISD::SDIV: case ISD::UDIV: case ISD::SREM: @@ -3013,7 +3024,7 @@ unsigned ISel::SelectExpr(SDOperand N) { assert((N.getOpcode() != ISD::SREM || MVT::isInteger(N.getValueType())) && "We don't support this operator!"); - if (N.getOpcode() == ISD::SDIV) { + if (N.getOpcode() == ISD::SDIV || N.getOpcode() == ISD::FDIV) { // We can fold loads into FpDIVs, but not really into any others. if (N.getValueType() == MVT::f64 && !X86ScalarSSE) { // Check for reversed and unreversed DIV. @@ -3756,9 +3767,12 @@ bool ISel::TryToFoldLoadOpStore(SDNode *Node) { default: std::cerr << "CANNOT [mem] op= val: "; StVal.Val->dump(); std::cerr << "\n"; + case ISD::FMUL: case ISD::MUL: + case ISD::FDIV: case ISD::SDIV: case ISD::UDIV: + case ISD::FREM: case ISD::SREM: case ISD::UREM: return false; @@ -3837,7 +3851,8 @@ bool ISel::TryToFoldLoadOpStore(SDNode *Node) { // If we have [mem] = V op [mem], try to turn it into: // [mem] = [mem] op V. - if (Op1 == TheLoad && StVal.getOpcode() != ISD::SUB && + if (Op1 == TheLoad && + StVal.getOpcode() != ISD::SUB && StVal.getOpcode() != ISD::FSUB && StVal.getOpcode() != ISD::SHL && StVal.getOpcode() != ISD::SRA && StVal.getOpcode() != ISD::SRL) std::swap(Op0, Op1);