diff options
author | Chris Lattner <sabre@nondot.org> | 2005-08-26 17:36:52 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-08-26 17:36:52 +0000 |
commit | 0b1e4e508b1fb76408a2c6a434b0f4df3cad3578 (patch) | |
tree | 514cca4a359902e61eb02313c333c71343645af7 /lib | |
parent | 143b6753936fc8a72ba32a5b113e66ee1a390b6f (diff) |
implement the other half of the select_cc -> fsel lowering, which handles
when the RHS of the comparison is 0.0. Turn this on by default.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23083 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/PowerPC/PPCISelLowering.cpp | 53 |
1 files changed, 37 insertions, 16 deletions
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index ae44ff0798..7d46477b33 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -16,16 +16,10 @@ #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/Constants.h" #include "llvm/Function.h" -#include "llvm/Support/CommandLine.h" using namespace llvm; -namespace llvm { - cl::opt<bool> FSELTMP("ppc-fsel-custom-legalizer", cl::Hidden, - cl::desc("Use a custom expander for fsel on ppc")); -} - - PPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM) : TargetLowering(TM) { @@ -73,11 +67,9 @@ PPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM) setOperationAction(ISD::SELECT, MVT::f32, Expand); setOperationAction(ISD::SELECT, MVT::f64, Expand); - // PowerPC wants to turn select_cc of FP into fsel. - if (FSELTMP) { - setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); - setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); - } + // PowerPC wants to turn select_cc of FP into fsel when possible. + setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); + setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); // PowerPC does not have BRCOND* which requires SetCC setOperationAction(ISD::BRCOND, MVT::Other, Expand); @@ -91,14 +83,23 @@ PPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM) setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand); setSetCCResultContents(ZeroOrOneSetCCResult); - if (!FSELTMP) { - addLegalFPImmediate(+0.0); // Necessary for FSEL - addLegalFPImmediate(-0.0); // - } computeRegisterProperties(); } +/// isFloatingPointZero - Return true if this is 0.0 or -0.0. +static bool isFloatingPointZero(SDOperand Op) { + if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Op)) + return CFP->isExactlyValue(-0.0) || CFP->isExactlyValue(0.0); + else if (Op.getOpcode() == ISD::EXTLOAD || Op.getOpcode() == ISD::LOAD) { + // Maybe this has already been legalized into the constant pool? + if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op.getOperand(1))) + if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->get())) + return CFP->isExactlyValue(-0.0) || CFP->isExactlyValue(0.0); + } + return false; +} + /// LowerOperation - Provide custom lowering hooks for some operations. /// SDOperand PPC32TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { @@ -114,6 +115,26 @@ SDOperand PPC32TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { SDOperand LHS = Op.getOperand(0), RHS = Op.getOperand(1); SDOperand TV = Op.getOperand(2), FV = Op.getOperand(3); + // If the RHS of the comparison is a 0.0, we don't need to do the + // subtraction at all. + if (isFloatingPointZero(RHS)) + switch (CC) { + default: assert(0 && "Invalid FSEL condition"); abort(); + case ISD::SETULT: + case ISD::SETLT: + std::swap(TV, FV); // fsel is natively setge, swap operands for setlt + case ISD::SETUGE: + case ISD::SETGE: + return DAG.getTargetNode(PPC::FSEL, ResVT, LHS, TV, FV); + case ISD::SETUGT: + case ISD::SETGT: + std::swap(TV, FV); // fsel is natively setge, swap operands for setlt + case ISD::SETULE: + case ISD::SETLE: + return DAG.getTargetNode(PPC::FSEL, ResVT, + DAG.getNode(ISD::FNEG, ResVT, LHS), TV, FV); + } + switch (CC) { default: assert(0 && "Invalid FSEL condition"); abort(); case ISD::SETULT: |