SelectionDAG: Improve legalization of SELECT_CC with illegal condition codes
authorTom Stellard <thomas.stellard@amd.com>
Sat, 28 Sep 2013 02:50:43 +0000 (02:50 +0000)
committerTom Stellard <thomas.stellard@amd.com>
Sat, 28 Sep 2013 02:50:43 +0000 (02:50 +0000)
SelectionDAG will now attempt to inverse an illegal conditon in order to
find a legal one and if that doesn't work, it will attempt to swap the
operands using the inverted condition.

There are no new test cases for this, but a nubmer of the existing R600
tests hit this path.

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

lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
lib/Target/R600/R600ISelLowering.cpp

index f6406b2a33615bfbda87fd6510498263e2818ddb..e78caba71137d4608b400a79607984049ebfb621 100644 (file)
@@ -3664,20 +3664,44 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) {
     Tmp4 = Node->getOperand(3);   // False
     SDValue CC = Node->getOperand(4);
 
-    bool Legalized = LegalizeSetCCCondCode(
-        getSetCCResultType(Tmp1.getValueType()), Tmp1, Tmp2, CC, dl);
-
-    assert(Legalized && "Can't legalize SELECT_CC with legal condition!");
-    // If we exapanded the SETCC by swapping LHS and RHS, create a new SELECT_CC
-    // node and return it.
-    if (CC.getNode()) {
-      Tmp1 = DAG.getNode(ISD::SELECT_CC, dl, Node->getValueType(0),
-                         Tmp1, Tmp2, Tmp3, Tmp4, CC);
+    bool Legalized = false;
+    // Try to legalize by inverting the condition.  This is for targets that
+    // might support an ordered version of a condition, but not the unordered
+    // version (or vice versa).
+    ISD::CondCode InvCC = ISD::getSetCCInverse(cast<CondCodeSDNode>(CC)->get(),
+                                               Tmp1.getValueType().isInteger());
+    if (TLI.isCondCodeLegal(InvCC, Tmp1.getSimpleValueType())) {
+      // Use the new condition code and swap true and false
+      Legalized = true;
+      Tmp1 = DAG.getSelectCC(dl, Tmp1, Tmp2, Tmp4, Tmp3, InvCC);
     } else {
-      Tmp2 = DAG.getConstant(0, Tmp1.getValueType());
-      CC = DAG.getCondCode(ISD::SETNE);
-      Tmp1 = DAG.getNode(ISD::SELECT_CC, dl, Node->getValueType(0), Tmp1, Tmp2,
-                         Tmp3, Tmp4, CC);
+      // If The inverse is not legal, then try to swap the arguments using
+      // the inverse condition code.
+      ISD::CondCode SwapInvCC = ISD::getSetCCSwappedOperands(InvCC);
+      if (TLI.isCondCodeLegal(SwapInvCC, Tmp1.getSimpleValueType())) {
+        // The swapped inverse condition is legal, so swap true and false,
+        // lhs and rhs.
+        Legalized = true;
+        Tmp1 = DAG.getSelectCC(dl, Tmp2, Tmp1, Tmp4, Tmp3, SwapInvCC);
+      }
+    }
+
+    if (!Legalized) {
+      Legalized = LegalizeSetCCCondCode(
+          getSetCCResultType(Tmp1.getValueType()), Tmp1, Tmp2, CC, dl);
+
+      assert(Legalized && "Can't legalize SELECT_CC with legal condition!");
+      // If we exapanded the SETCC by swapping LHS and RHS, create a new
+      // SELECT_CC node.
+      if (CC.getNode()) {
+        Tmp1 = DAG.getNode(ISD::SELECT_CC, dl, Node->getValueType(0),
+                           Tmp1, Tmp2, Tmp3, Tmp4, CC);
+      } else {
+        Tmp2 = DAG.getConstant(0, Tmp1.getValueType());
+        CC = DAG.getCondCode(ISD::SETNE);
+        Tmp1 = DAG.getNode(ISD::SELECT_CC, dl, Node->getValueType(0), Tmp1, Tmp2,
+                           Tmp3, Tmp4, CC);
+      }
     }
     Results.push_back(Tmp1);
     break;
index 1d2c5e1bda4f8d7f7b2b498dc75a06e99f8bd467..5e9048a7019c446054ff86257c9b72738335e9c7 100644 (file)
@@ -862,10 +862,18 @@ SDValue R600TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
   ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
   ISD::CondCode InverseCC =
      ISD::getSetCCInverse(CCOpcode, CompareVT == MVT::i32);
-  if (isHWTrueValue(False) && isHWFalseValue(True) &&
-      isCondCodeLegal(InverseCC, CompareVT.getSimpleVT())) {
-    std::swap(False, True);
-    CC = DAG.getCondCode(InverseCC);
+  if (isHWTrueValue(False) && isHWFalseValue(True)) {
+    if (isCondCodeLegal(InverseCC, CompareVT.getSimpleVT())) {
+      std::swap(False, True);
+      CC = DAG.getCondCode(InverseCC);
+    } else {
+      ISD::CondCode SwapInvCC = ISD::getSetCCSwappedOperands(InverseCC);
+      if (isCondCodeLegal(SwapInvCC, CompareVT.getSimpleVT())) {
+        std::swap(False, True);
+        std::swap(LHS, RHS);
+        CC = DAG.getCondCode(SwapInvCC);
+      }
+    }
   }
 
   if (isHWTrueValue(True) && isHWFalseValue(False) &&