add initial support for converting select_cc -> fsel in the legalizer
authorChris Lattner <sabre@nondot.org>
Fri, 26 Aug 2005 00:52:45 +0000 (00:52 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 26 Aug 2005 00:52:45 +0000 (00:52 +0000)
instead of in the backend.  This currently handles fsel cases with registers,
but doesn't have the 0.0 and -0.0 optimization enabled yet.

Once this is finished, special hack for fp immediates can go away.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23075 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCISelLowering.cpp
lib/Target/PowerPC/PPCISelLowering.h
lib/Target/PowerPC/PPCISelPattern.cpp

index 644a73f6d1bec1d4b142fb724c9915196d39ed75..ae44ff079817ae48df647c84a1739e766ed77a65 100644 (file)
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/SelectionDAG.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) {
     
@@ -65,6 +72,12 @@ PPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM)
   setOperationAction(ISD::SELECT, MVT::i32, Expand);
   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 does not have BRCOND* which requires SetCC
   setOperationAction(ISD::BRCOND,       MVT::Other, Expand);
@@ -78,12 +91,54 @@ PPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM)
   setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
 
   setSetCCResultContents(ZeroOrOneSetCCResult);
-  addLegalFPImmediate(+0.0); // Necessary for FSEL
-  addLegalFPImmediate(-0.0); //
+  if (!FSELTMP) {
+    addLegalFPImmediate(+0.0); // Necessary for FSEL
+    addLegalFPImmediate(-0.0); //
+  }
   
   computeRegisterProperties();
 }
 
+/// LowerOperation - Provide custom lowering hooks for some operations.
+///
+SDOperand PPC32TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
+  switch (Op.getOpcode()) {
+  default: assert(0 && "Wasn't expecting to be able to lower this!"); 
+  case ISD::SELECT_CC:
+    // Turn FP only select_cc's into fsel instructions.
+    if (MVT::isFloatingPoint(Op.getOperand(0).getValueType()) &&
+        MVT::isFloatingPoint(Op.getOperand(2).getValueType())) {
+      ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
+      MVT::ValueType ResVT = Op.getValueType();
+      MVT::ValueType CmpVT = Op.getOperand(0).getValueType();
+      SDOperand LHS = Op.getOperand(0), RHS = Op.getOperand(1);
+      SDOperand TV  = Op.getOperand(2), FV  = Op.getOperand(3);
+
+      switch (CC) {
+      default: assert(0 && "Invalid FSEL condition"); abort();
+      case ISD::SETULT:
+      case ISD::SETLT:
+        return DAG.getTargetNode(PPC::FSEL, ResVT,
+                                 DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), FV,TV);
+      case ISD::SETUGE:
+      case ISD::SETGE:
+        return DAG.getTargetNode(PPC::FSEL, ResVT,
+                                 DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), TV,FV);
+      case ISD::SETUGT:
+      case ISD::SETGT:
+        return DAG.getTargetNode(PPC::FSEL, ResVT,
+                                 DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), FV,TV);
+      case ISD::SETULE:
+      case ISD::SETLE:
+        return DAG.getTargetNode(PPC::FSEL, ResVT,
+                                 DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), TV,FV);
+      }
+    }
+    break;    
+  }
+  return SDOperand();
+}
+
 std::vector<SDOperand>
 PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
   //
index 4198e2637bcc4710bfec4d336b13643e9f0c63f5..aa01934aa1e30d9303bab59d04dc87a74ff9dfb2 100644 (file)
@@ -24,6 +24,10 @@ namespace llvm {
   public:
     PPC32TargetLowering(TargetMachine &TM);
     
+    /// LowerOperation - Provide custom lowering hooks for some operations.
+    ///
+    virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
+    
     /// LowerArguments - This hook must be implemented to indicate how we should
     /// lower the arguments for the specified function, into the specified DAG.
     virtual std::vector<SDOperand>
index 07529c7e0171247b052f40940f81ef6c87db2651..102b4b3845d7239dd984f5a5bf7bff5e4eeb5542 100644 (file)
@@ -829,6 +829,12 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
   default:
     Node->dump(); std::cerr << '\n';
     assert(0 && "Node not handled!\n");
+  case ISD::BUILTIN_OP_END+PPC::FSEL:
+    Tmp1 = SelectExpr(N.getOperand(0));
+    Tmp2 = SelectExpr(N.getOperand(1));
+    Tmp3 = SelectExpr(N.getOperand(2));
+    BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
+    return Result;
   case ISD::UNDEF:
     if (Node->getValueType(0) == MVT::i32)
       BuildMI(BB, PPC::IMPLICIT_DEF_GPR, 0, Result);