[llvm-branch-commits] [llvm-branch] r165013 - in /llvm/branches/R600: lib/Target/AMDGPU/R600ISelLowering.cpp lib/Target/AMDGPU/R600ISelLowering.h lib/Target/AMDGPU/R600Instructions.td test/CodeGen/R600/selectcc_cnde.ll test/CodeGen/R600/selectcc_cnde_int.ll

Tom Stellard thomas.stellard at amd.com
Tue Oct 2 07:15:45 PDT 2012


Author: tstellar
Date: Tue Oct  2 09:15:45 2012
New Revision: 165013

URL: http://llvm.org/viewvc/llvm-project?rev=165013&view=rev
Log:
R600: improve select_cc lowering to generate CND* more often

Patch by: Vincent Lejeune

v2: - Simplify isZero()
    - Remove a unused function prototype
    - Clean whitespace trails

Reviewed-by: Tom Stellard <thomas.stellard at amd.com>

Added:
    llvm/branches/R600/test/CodeGen/R600/selectcc_cnde.ll
    llvm/branches/R600/test/CodeGen/R600/selectcc_cnde_int.ll
Modified:
    llvm/branches/R600/lib/Target/AMDGPU/R600ISelLowering.cpp
    llvm/branches/R600/lib/Target/AMDGPU/R600ISelLowering.h
    llvm/branches/R600/lib/Target/AMDGPU/R600Instructions.td

Modified: llvm/branches/R600/lib/Target/AMDGPU/R600ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/R600/lib/Target/AMDGPU/R600ISelLowering.cpp?rev=165013&r1=165012&r2=165013&view=diff
==============================================================================
--- llvm/branches/R600/lib/Target/AMDGPU/R600ISelLowering.cpp (original)
+++ llvm/branches/R600/lib/Target/AMDGPU/R600ISelLowering.cpp Tue Oct  2 09:15:45 2012
@@ -516,6 +516,17 @@
                                  Op.getOperand(1)));
 }
 
+bool R600TargetLowering::isZero(SDValue Op) const
+{
+  if(ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(Op)) {
+    return Cst->isNullValue();
+  } else if(ConstantFPSDNode *CstFP = dyn_cast<ConstantFPSDNode>(Op)){
+    return CstFP->isZero();
+  } else {
+    return false;
+  }
+}
+
 SDValue R600TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
 {
   DebugLoc DL = Op.getDebugLoc();
@@ -568,48 +579,58 @@
   if (isHWTrueValue(False) && isHWFalseValue(True)) {
   }
 
-  // XXX Check if we can lower this to a SELECT or if it is supported by a native
-  // operation. (The code below does this but we don't have the Instruction
-  // selection patterns to do this yet.
-#if 0
-  ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
+  // Check if we can lower this to a native operation.
+  // CND* instructions requires all operands to have the same type,
+  // and RHS to be zero.
+
   if (isZero(LHS) || isZero(RHS)) {
     SDValue Cond = (isZero(LHS) ? RHS : LHS);
-    bool SwapTF = false;
+    SDValue Zero = (isZero(LHS) ? LHS : RHS);
+    ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
+    if (CompareVT != VT) {
+      True = DAG.getNode(ISD::BITCAST, DL, CompareVT, True);
+      False = DAG.getNode(ISD::BITCAST, DL, CompareVT, False);
+    }
+    if (isZero(LHS)) {
+      CCOpcode = ISD::getSetCCSwappedOperands(CCOpcode);
+    }
+
     switch (CCOpcode) {
-    case ISD::SETOEQ:
-    case ISD::SETUEQ:
-    case ISD::SETEQ:
-      SwapTF = true;
-      // Fall through
     case ISD::SETONE:
     case ISD::SETUNE:
     case ISD::SETNE:
-      // We can lower to select
-      if (SwapTF) {
-        Temp = True;
-        True = False;
-        False = Temp;
-      }
-      // CNDE
-      return DAG.getNode(ISD::SELECT, DL, VT, Cond, True, False);
+    case ISD::SETULE:
+    case ISD::SETULT:
+    case ISD::SETOLE:
+    case ISD::SETOLT:
+    case ISD::SETLE:
+    case ISD::SETLT:
+      CCOpcode = ISD::getSetCCInverse(CCOpcode, CompareVT == MVT::i32);
+      Temp = True;
+      True = False;
+      False = Temp;
+      break;
     default:
-      // Supported by a native operation (CNDGE, CNDGT)
-      return DAG.getNode(ISD::SELECT_CC, DL, VT, LHS, RHS, True, False, CC);
+      break;
     }
+    SDValue SelectNode = DAG.getNode(ISD::SELECT_CC, DL, CompareVT,
+        Cond, Zero,
+        True, False,
+        DAG.getCondCode(CCOpcode));
+    return DAG.getNode(ISD::BITCAST, DL, VT, SelectNode);
   }
-#endif
+
 
   // If we make it this for it means we have no native instructions to handle
   // this SELECT_CC, so we must lower it.
   SDValue HWTrue, HWFalse;
 
-  if (VT == MVT::f32) {
-    HWTrue = DAG.getConstantFP(1.0f, VT);
-    HWFalse = DAG.getConstantFP(0.0f, VT);
-  } else if (VT == MVT::i32) {
-    HWTrue = DAG.getConstant(-1, VT);
-    HWFalse = DAG.getConstant(0, VT);
+  if (CompareVT == MVT::f32) {
+    HWTrue = DAG.getConstantFP(1.0f, CompareVT);
+    HWFalse = DAG.getConstantFP(0.0f, CompareVT);
+  } else if (CompareVT == MVT::i32) {
+    HWTrue = DAG.getConstant(-1, CompareVT);
+    HWFalse = DAG.getConstant(0, CompareVT);
   }
   else {
     assert(!"Unhandled value type in LowerSELECT_CC");
@@ -617,15 +638,12 @@
 
   // Lower this unsupported SELECT_CC into a combination of two supported
   // SELECT_CC operations.
-  SDValue Cond = DAG.getNode(ISD::SELECT_CC, DL, VT, LHS, RHS, HWTrue, HWFalse, CC);
-
-  // Convert floating point condition to i1
-  if (VT == MVT::f32) {
-    Cond = DAG.getNode(ISD::FP_TO_SINT, DL, MVT::i32,
-                       DAG.getNode(ISD::FNEG, DL, VT, Cond));
-  }
+  SDValue Cond = DAG.getNode(ISD::SELECT_CC, DL, CompareVT, LHS, RHS, HWTrue, HWFalse, CC);
 
-  return DAG.getNode(ISD::SELECT, DL, VT, Cond, True, False);
+  return DAG.getNode(ISD::SELECT_CC, DL, VT,
+      Cond, HWFalse,
+      True, False,
+      DAG.getCondCode(ISD::SETNE));
 }
 
 SDValue R600TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const

Modified: llvm/branches/R600/lib/Target/AMDGPU/R600ISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/R600/lib/Target/AMDGPU/R600ISelLowering.h?rev=165013&r1=165012&r2=165013&view=diff
==============================================================================
--- llvm/branches/R600/lib/Target/AMDGPU/R600ISelLowering.h (original)
+++ llvm/branches/R600/lib/Target/AMDGPU/R600ISelLowering.h Tue Oct  2 09:15:45 2012
@@ -60,6 +60,8 @@
   SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerInputFace(SDNode *Op, SelectionDAG &DAG) const;
   SDValue LowerFPTOUINT(SDValue Op, SelectionDAG &DAG) const;
+  
+  bool isZero(SDValue Op) const;
 };
 
 } // End namespace llvm;

Modified: llvm/branches/R600/lib/Target/AMDGPU/R600Instructions.td
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/R600/lib/Target/AMDGPU/R600Instructions.td?rev=165013&r1=165012&r2=165013&view=diff
==============================================================================
--- llvm/branches/R600/lib/Target/AMDGPU/R600Instructions.td (original)
+++ llvm/branches/R600/lib/Target/AMDGPU/R600Instructions.td Tue Oct  2 09:15:45 2012
@@ -554,7 +554,25 @@
 def CNDE_INT : R600_3OP <
 	0x1C, "CNDE_INT",
   [(set (i32 R600_Reg32:$dst),
-   (select R600_Reg32:$src0, R600_Reg32:$src2, R600_Reg32:$src1))]
+   (selectcc (i32 R600_Reg32:$src0), 0,
+       (i32 R600_Reg32:$src1), (i32 R600_Reg32:$src2),
+       COND_EQ))]
+>;
+
+def CNDGE_INT : R600_3OP <
+	0x1E, "CNDGE_INT",
+  [(set (i32 R600_Reg32:$dst),
+   (selectcc (i32 R600_Reg32:$src0), 0,
+       (i32 R600_Reg32:$src1), (i32 R600_Reg32:$src2),
+       COND_GE))]
+>;
+
+def CNDGT_INT : R600_3OP <
+	0x1D, "CNDGT_INT",
+  [(set (i32 R600_Reg32:$dst),
+   (selectcc (i32 R600_Reg32:$src0), 0,
+       (i32 R600_Reg32:$src1), (i32 R600_Reg32:$src2),
+       COND_GT))]
 >;
 
 //===----------------------------------------------------------------------===//
@@ -651,18 +669,26 @@
 
 class CNDE_Common <bits<11> inst> : R600_3OP <
   inst, "CNDE",
-  [(set (f32 R600_Reg32:$dst),
-   (select (i32 (fp_to_sint (fneg R600_Reg32:$src0))), (f32 R600_Reg32:$src2), (f32 R600_Reg32:$src1)))]
+  [(set R600_Reg32:$dst,
+   (selectcc (f32 R600_Reg32:$src0), FP_ZERO,
+       (f32 R600_Reg32:$src1), (f32 R600_Reg32:$src2),
+       COND_EQ))]
 >;
 
 class CNDGT_Common <bits<11> inst> : R600_3OP <
   inst, "CNDGT",
-  []
+  [(set R600_Reg32:$dst,
+   (selectcc (f32 R600_Reg32:$src0), FP_ZERO,
+       (f32 R600_Reg32:$src1), (f32 R600_Reg32:$src2),
+       COND_GT))]
 >;
-  
+
 class CNDGE_Common <bits<11> inst> : R600_3OP <
   inst, "CNDGE",
-  [(set R600_Reg32:$dst, (int_AMDGPU_cndlt R600_Reg32:$src0, R600_Reg32:$src2, R600_Reg32:$src1))]
+  [(set R600_Reg32:$dst,
+   (selectcc (f32 R600_Reg32:$src0), FP_ZERO,
+       (f32 R600_Reg32:$src1), (f32 R600_Reg32:$src2),
+       COND_GE))]
 >;
 
 class DOT4_Common <bits<11> inst> : R600_REDUCTION <

Added: llvm/branches/R600/test/CodeGen/R600/selectcc_cnde.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/R600/test/CodeGen/R600/selectcc_cnde.ll?rev=165013&view=auto
==============================================================================
--- llvm/branches/R600/test/CodeGen/R600/selectcc_cnde.ll (added)
+++ llvm/branches/R600/test/CodeGen/R600/selectcc_cnde.ll Tue Oct  2 09:15:45 2012
@@ -0,0 +1,11 @@
+;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s
+
+;CHECK-NOT: SETE
+;CHECK: CNDE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
+define void @test(float addrspace(1)* %out, float addrspace(1)* %in) {
+  %1 = load float addrspace(1)* %in
+  %2 = fcmp oeq float %1, 0.0
+  %3 = select i1 %2, float 1.0, float 2.0
+  store float %3, float addrspace(1)* %out
+  ret void
+}

Added: llvm/branches/R600/test/CodeGen/R600/selectcc_cnde_int.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/R600/test/CodeGen/R600/selectcc_cnde_int.ll?rev=165013&view=auto
==============================================================================
--- llvm/branches/R600/test/CodeGen/R600/selectcc_cnde_int.ll (added)
+++ llvm/branches/R600/test/CodeGen/R600/selectcc_cnde_int.ll Tue Oct  2 09:15:45 2012
@@ -0,0 +1,11 @@
+;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s
+
+;CHECK-NOT: SETE_INT
+;CHECK: CNDE_INT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
+define void @test(i32 addrspace(1)* %out, i32 addrspace(1)* %in) {
+  %1 = load i32 addrspace(1)* %in
+  %2 = icmp eq i32 %1, 0
+  %3 = select i1 %2, i32 1, i32 2
+  store i32 %3, i32 addrspace(1)* %out
+  ret void
+}





More information about the llvm-branch-commits mailing list