diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index 22b9a9ce5037..0ccd8e1c06a6 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -105,8 +105,11 @@ namespace ISD { BUILD_PAIR, - // Simple binary arithmetic operators. + // Simple integer binary arithmetic operators. ADD, SUB, MUL, SDIV, UDIV, SREM, UREM, + + // Simple binary floating point operators. + FADD, FSUB, FMUL, FDIV, FREM, // MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing // an unsigned/signed value of type i[2*n], then return the top part. diff --git a/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp b/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp index 73e9e2f4dbc2..8cbbabf57c9e 100644 --- a/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp +++ b/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp @@ -1133,40 +1133,40 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) { return Result; case ISD::ADD: - if (!MVT::isInteger(DestType)) { - if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL && - N.getOperand(0).Val->hasOneUse()) { - ++FusedFP; // Statistic - Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); - Tmp3 = SelectExpr(N.getOperand(1)); - Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS; - BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); - return Result; - } - if (!NoExcessFPPrecision && N.getOperand(1).getOpcode() == ISD::MUL && - N.getOperand(1).Val->hasOneUse()) { - ++FusedFP; // Statistic - Tmp1 = SelectExpr(N.getOperand(1).getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1).getOperand(1)); - Tmp3 = SelectExpr(N.getOperand(0)); - Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS; - BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); - return Result; - } - Opc = DestType == MVT::f64 ? PPC::FADD : PPC::FADDS; - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); - return Result; - } if (SelectIntImmediateExpr(N, Result, PPC::ADDIS, PPC::ADDI, true)) return Result; Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); BuildMI(BB, PPC::ADD, 2, Result).addReg(Tmp1).addReg(Tmp2); return Result; - + + case ISD::FADD: + if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::FMUL && + N.getOperand(0).Val->hasOneUse()) { + ++FusedFP; // Statistic + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(1)); + Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS; + BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + return Result; + } + if (!NoExcessFPPrecision && N.getOperand(1).getOpcode() == ISD::FMUL && + N.getOperand(1).Val->hasOneUse()) { + ++FusedFP; // Statistic + Tmp1 = SelectExpr(N.getOperand(1).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(0)); + Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS; + BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + return Result; + } + Opc = DestType == MVT::f64 ? PPC::FADD : PPC::FADDS; + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + case ISD::AND: if (isIntImmediate(N.getOperand(1), Tmp2)) { if (isShiftedMask_32(Tmp2) || isShiftedMask_32(~Tmp2)) { @@ -1290,34 +1290,33 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) { return Result; } - case ISD::SUB: - if (!MVT::isInteger(DestType)) { - if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL && - N.getOperand(0).Val->hasOneUse()) { - ++FusedFP; // Statistic - Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); - Tmp3 = SelectExpr(N.getOperand(1)); - Opc = DestType == MVT::f64 ? PPC::FMSUB : PPC::FMSUBS; - BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); - return Result; - } - if (!NoExcessFPPrecision && N.getOperand(1).getOpcode() == ISD::MUL && - N.getOperand(1).Val->hasOneUse()) { - ++FusedFP; // Statistic - Tmp1 = SelectExpr(N.getOperand(1).getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1).getOperand(1)); - Tmp3 = SelectExpr(N.getOperand(0)); - Opc = DestType == MVT::f64 ? PPC::FNMSUB : PPC::FNMSUBS; - BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); - return Result; - } - Opc = DestType == MVT::f64 ? PPC::FSUB : PPC::FSUBS; - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + case ISD::FSUB: + if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::FMUL && + N.getOperand(0).Val->hasOneUse()) { + ++FusedFP; // Statistic + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(1)); + Opc = DestType == MVT::f64 ? PPC::FMSUB : PPC::FMSUBS; + BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); return Result; } + if (!NoExcessFPPrecision && N.getOperand(1).getOpcode() == ISD::FMUL && + N.getOperand(1).Val->hasOneUse()) { + ++FusedFP; // Statistic + Tmp1 = SelectExpr(N.getOperand(1).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(0)); + Opc = DestType == MVT::f64 ? PPC::FNMSUB : PPC::FNMSUBS; + BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + return Result; + } + Opc = DestType == MVT::f64 ? PPC::FSUB : PPC::FSUBS; + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + case ISD::SUB: if (isIntImmediate(N.getOperand(0), Tmp1) && isInt16(Tmp1)) { Tmp1 = Lo16(Tmp1); Tmp2 = SelectExpr(N.getOperand(1)); @@ -1334,6 +1333,13 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) { BuildMI(BB, PPC::SUBF, 2, Result).addReg(Tmp2).addReg(Tmp1); return Result; + case ISD::FMUL: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, DestType == MVT::f32 ? PPC::FMULS : PPC::FMUL, 2, + Result).addReg(Tmp1).addReg(Tmp2); + return Result; + case ISD::MUL: Tmp1 = SelectExpr(N.getOperand(0)); if (isIntImmediate(N.getOperand(1), Tmp2) && isInt16(Tmp2)) { @@ -1341,13 +1347,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) { BuildMI(BB, PPC::MULLI, 2, Result).addReg(Tmp1).addSImm(Tmp2); } else { Tmp2 = SelectExpr(N.getOperand(1)); - switch (DestType) { - default: assert(0 && "Unknown type to ISD::MUL"); break; - case MVT::i32: Opc = PPC::MULLW; break; - case MVT::f32: Opc = PPC::FMULS; break; - case MVT::f64: Opc = PPC::FMUL; break; - } - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + BuildMI(BB, PPC::MULLW, 2, Result).addReg(Tmp1).addReg(Tmp2); } return Result; @@ -1359,6 +1359,17 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) { BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); return Result; + case ISD::FDIV: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + switch (DestType) { + default: assert(0 && "Unknown type to ISD::FDIV"); break; + case MVT::f32: Opc = PPC::FDIVS; break; + case MVT::f64: Opc = PPC::FDIV; break; + } + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + case ISD::SDIV: if (isIntImmediate(N.getOperand(1), Tmp3)) { if ((signed)Tmp3 > 0 && isPowerOf2_32(Tmp3)) { @@ -1392,12 +1403,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) { } Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); - switch (DestType) { - default: assert(0 && "Unknown type to ISD::DIV"); break; - case MVT::i32: Opc = (ISD::UDIV == opcode) ? PPC::DIVWU : PPC::DIVW; break; - case MVT::f32: Opc = PPC::FDIVS; break; - case MVT::f64: Opc = PPC::FDIV; break; - } + Opc = (ISD::UDIV == opcode) ? PPC::DIVWU : PPC::DIVW; break; BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); return Result; @@ -1624,9 +1630,9 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) { case ISD::FNEG: if (!NoExcessFPPrecision && - ISD::ADD == N.getOperand(0).getOpcode() && + ISD::FADD == N.getOperand(0).getOpcode() && N.getOperand(0).Val->hasOneUse() && - ISD::MUL == N.getOperand(0).getOperand(0).getOpcode() && + ISD::FMUL == N.getOperand(0).getOperand(0).getOpcode() && N.getOperand(0).getOperand(0).Val->hasOneUse()) { ++FusedFP; // Statistic Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0)); @@ -1635,9 +1641,9 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) { Opc = DestType == MVT::f64 ? PPC::FNMADD : PPC::FNMADDS; BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); } else if (!NoExcessFPPrecision && - ISD::ADD == N.getOperand(0).getOpcode() && + ISD::FADD == N.getOperand(0).getOpcode() && N.getOperand(0).Val->hasOneUse() && - ISD::MUL == N.getOperand(0).getOperand(1).getOpcode() && + ISD::FMUL == N.getOperand(0).getOperand(1).getOpcode() && N.getOperand(0).getOperand(1).Val->hasOneUse()) { ++FusedFP; // Statistic Tmp1 = SelectExpr(N.getOperand(0).getOperand(1).getOperand(0)); diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 9a436ee98ff2..40f9945d5861 100644 --- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -767,22 +767,20 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) { CurDAG->SelectNodeTo(N, PPC::FCTIWZ, N->getValueType(0), Select(N->getOperand(0))); return SDOperand(N, 0); - case ISD::ADD: { - MVT::ValueType Ty = N->getValueType(0); - if (Ty == MVT::i32) { - if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0), N->getOperand(1), - PPC::ADDIS, PPC::ADDI, true)) { - CurDAG->ReplaceAllUsesWith(Op, SDOperand(I, 0)); - N = I; - } else { - CurDAG->SelectNodeTo(N, PPC::ADD, MVT::i32, Select(N->getOperand(0)), - Select(N->getOperand(1))); - } - return SDOperand(N, 0); + case ISD::ADD: + if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0), N->getOperand(1), + PPC::ADDIS, PPC::ADDI, true)) { + CurDAG->ReplaceAllUsesWith(Op, SDOperand(I, 0)); + N = I; + } else { + CurDAG->SelectNodeTo(N, PPC::ADD, MVT::i32, Select(N->getOperand(0)), + Select(N->getOperand(1))); } - + return SDOperand(N, 0); + case ISD::FADD: { + MVT::ValueType Ty = N->getValueType(0); if (!NoExcessFPPrecision) { // Match FMA ops - if (N->getOperand(0).getOpcode() == ISD::MUL && + if (N->getOperand(0).getOpcode() == ISD::FMUL && N->getOperand(0).Val->hasOneUse()) { ++FusedFP; // Statistic CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FMADD : PPC::FMADDS, Ty, @@ -790,7 +788,7 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) { Select(N->getOperand(0).getOperand(1)), Select(N->getOperand(1))); return SDOperand(N, 0); - } else if (N->getOperand(1).getOpcode() == ISD::MUL && + } else if (N->getOperand(1).getOpcode() == ISD::FMUL && N->getOperand(1).hasOneUse()) { ++FusedFP; // Statistic CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FMADD : PPC::FMADDS, Ty, @@ -806,30 +804,30 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) { return SDOperand(N, 0); } case ISD::SUB: { - MVT::ValueType Ty = N->getValueType(0); - if (Ty == MVT::i32) { - unsigned Imm; - if (isIntImmediate(N->getOperand(0), Imm) && isInt16(Imm)) { - if (0 == Imm) - CurDAG->SelectNodeTo(N, PPC::NEG, Ty, Select(N->getOperand(1))); - else - CurDAG->SelectNodeTo(N, PPC::SUBFIC, Ty, Select(N->getOperand(1)), - getI32Imm(Lo16(Imm))); - return SDOperand(N, 0); - } - if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0), N->getOperand(1), - PPC::ADDIS, PPC::ADDI, true, true)) { - CurDAG->ReplaceAllUsesWith(Op, SDOperand(I, 0)); - N = I; - } else { - CurDAG->SelectNodeTo(N, PPC::SUBF, Ty, Select(N->getOperand(1)), - Select(N->getOperand(0))); - } + unsigned Imm; + if (isIntImmediate(N->getOperand(0), Imm) && isInt16(Imm)) { + if (0 == Imm) + CurDAG->SelectNodeTo(N, PPC::NEG, MVT::i32, Select(N->getOperand(1))); + else + CurDAG->SelectNodeTo(N, PPC::SUBFIC, MVT::i32, Select(N->getOperand(1)), + getI32Imm(Lo16(Imm))); return SDOperand(N, 0); } + if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0), N->getOperand(1), + PPC::ADDIS, PPC::ADDI, true, true)) { + CurDAG->ReplaceAllUsesWith(Op, SDOperand(I, 0)); + N = I; + } else { + CurDAG->SelectNodeTo(N, PPC::SUBF, MVT::i32, Select(N->getOperand(1)), + Select(N->getOperand(0))); + } + return SDOperand(N, 0); + } + case ISD::FSUB: { + MVT::ValueType Ty = N->getValueType(0); if (!NoExcessFPPrecision) { // Match FMA ops - if (N->getOperand(0).getOpcode() == ISD::MUL && + if (N->getOperand(0).getOpcode() == ISD::FMUL && N->getOperand(0).Val->hasOneUse()) { ++FusedFP; // Statistic CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FMSUB : PPC::FMSUBS, Ty, @@ -837,7 +835,7 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) { Select(N->getOperand(0).getOperand(1)), Select(N->getOperand(1))); return SDOperand(N, 0); - } else if (N->getOperand(1).getOpcode() == ISD::MUL && + } else if (N->getOperand(1).getOpcode() == ISD::FMUL && N->getOperand(1).Val->hasOneUse()) { ++FusedFP; // Statistic CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FNMSUB : PPC::FNMSUBS, Ty, @@ -852,6 +850,7 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) { Select(N->getOperand(1))); return SDOperand(N, 0); } + case ISD::FMUL: case ISD::MUL: { unsigned Imm, Opc; if (isIntImmediate(N->getOperand(1), Imm) && isInt16(Imm)) { @@ -869,7 +868,8 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) { Select(N->getOperand(1))); return SDOperand(N, 0); } - case ISD::SDIV: { + case ISD::SDIV: + case ISD::FDIV: { unsigned Imm; if (isIntImmediate(N->getOperand(1), Imm)) { if ((signed)Imm > 0 && isPowerOf2_32(Imm)) { diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index f3b7f64f1910..23d796600c70 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -52,10 +52,10 @@ PPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM) // We don't support sin/cos/sqrt/fmod setOperationAction(ISD::FSIN , MVT::f64, Expand); setOperationAction(ISD::FCOS , 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::SREM , MVT::f32, Expand); + setOperationAction(ISD::FREM , MVT::f32, Expand); // If we're enabling GP optimizations, use hardware square root if (!TM.getSubtarget().hasFSQRT()) { @@ -208,19 +208,19 @@ SDOperand PPC32TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { case ISD::SETULT: case ISD::SETLT: return DAG.getNode(PPCISD::FSEL, ResVT, - DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), FV, TV); + DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS), FV, TV); case ISD::SETUGE: case ISD::SETGE: return DAG.getNode(PPCISD::FSEL, ResVT, - DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), TV, FV); + DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS), TV, FV); case ISD::SETUGT: case ISD::SETGT: return DAG.getNode(PPCISD::FSEL, ResVT, - DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), FV, TV); + DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS), FV, TV); case ISD::SETULE: case ISD::SETLE: return DAG.getNode(PPCISD::FSEL, ResVT, - DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), TV, FV); + DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS), TV, FV); } break; }