[llvm-branch-commits] [llvm-branch] r165527 - in /llvm/branches/R600: lib/Target/AMDGPU/R600ISelLowering.cpp test/CodeGen/R600/fcmp-cnde-int-args.ll

Tom Stellard thomas.stellard at amd.com
Tue Oct 9 11:49:05 PDT 2012


Author: tstellar
Date: Tue Oct  9 13:49:05 2012
New Revision: 165527

URL: http://llvm.org/viewvc/llvm-project?rev=165527&view=rev
Log:
R600: Prefer lowering SELECT_CC to CND* instructions over SET* instructions

SET* instructions are more expensive, because in some cases they require
additional instructions to convert their result to the correct type.

Added:
    llvm/branches/R600/test/CodeGen/R600/fcmp-cnde-int-args.ll
Modified:
    llvm/branches/R600/lib/Target/AMDGPU/R600ISelLowering.cpp

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=165527&r1=165526&r2=165527&view=diff
==============================================================================
--- llvm/branches/R600/lib/Target/AMDGPU/R600ISelLowering.cpp (original)
+++ llvm/branches/R600/lib/Target/AMDGPU/R600ISelLowering.cpp Tue Oct  9 13:49:05 2012
@@ -550,6 +550,56 @@
   // LHS and RHS are guaranteed to be the same value type
   EVT CompareVT = LHS.getValueType();
 
+  // Check if we can lower this to a native operation.
+
+  // Try to lower to a CND* instruction:
+  // CND* instructions requires RHS to be zero.  Some SELECT_CC nodes that
+  // can be lowered to CND* instructions can also be lowered to SET*
+  // instructions.  CND* instructions are cheaper, because they dont't
+  // require additional instructions to convert their result to the correct
+  // value type, so this check should be first.
+  if (isZero(LHS) || isZero(RHS)) {
+    SDValue Cond = (isZero(LHS) ? RHS : LHS);
+    SDValue Zero = (isZero(LHS) ? LHS : RHS);
+    ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
+    if (CompareVT != VT) {
+      // Bitcast True / False to the correct types.  This will end up being
+      // a nop, but it allows us to define only a single pattern in the
+      // .TD files for each CND* instruction rather than having to have
+      // one pattern for integer True/False and one for fp True/False
+      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::SETONE:
+    case ISD::SETUNE:
+    case ISD::SETNE:
+    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:
+      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);
+  }
+
+  // Try to lower to a SET* instruction:
   // We need all the operands of SELECT_CC to have the same value type, so if
   // necessary we need to change True and False to be the same type as LHS and
   // RHS, and then convert the result of the select_cc back to the correct type.
@@ -592,48 +642,6 @@
   if (isHWTrueValue(False) && isHWFalseValue(True)) {
   }
 
-  // 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);
-    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::SETONE:
-    case ISD::SETUNE:
-    case ISD::SETNE:
-    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:
-      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);
-  }
-
-
   // 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;

Added: llvm/branches/R600/test/CodeGen/R600/fcmp-cnde-int-args.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/R600/test/CodeGen/R600/fcmp-cnde-int-args.ll?rev=165527&view=auto
==============================================================================
--- llvm/branches/R600/test/CodeGen/R600/fcmp-cnde-int-args.ll (added)
+++ llvm/branches/R600/test/CodeGen/R600/fcmp-cnde-int-args.ll Tue Oct  9 13:49:05 2012
@@ -0,0 +1,16 @@
+;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s
+
+; This test checks a bug in R600TargetLowering::LowerSELECT_CC where the
+; chance to optimize the fcmp + select instructions to CNDE was missed
+; due to the fact that the operands to fcmp and select had different types
+
+;CHECK: CNDE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
+
+define void @test(i32 addrspace(1)* %out, float addrspace(1)* %in) {
+entry:
+  %0 = load float addrspace(1)* %in
+  %cmp = fcmp oeq float %0, 0.000000e+00
+  %value = select i1 %cmp, i32 -1, i32 0
+  store i32 %value, i32 addrspace(1)* %out
+  ret void
+}





More information about the llvm-branch-commits mailing list