From 0b1e4e508b1fb76408a2c6a434b0f4df3cad3578 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 26 Aug 2005 17:36:52 +0000 Subject: [PATCH] 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 --- lib/Target/PowerPC/PPCISelLowering.cpp | 53 ++++++++++++++++++-------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index ae44ff07981..7d46477b339 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 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(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(Op.getOperand(1))) + if (ConstantFP *CFP = dyn_cast(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: