OSDN Git Service

Fix creating illegal setcc cond codes.
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Tue, 25 Mar 2014 16:09:21 +0000 (16:09 +0000)
committerMatt Arsenault <Matthew.Arsenault@amd.com>
Tue, 25 Mar 2014 16:09:21 +0000 (16:09 +0000)
If GT/UGT or LT/ULT were set to expand, a comparison
with a constant would replace it with the illegal
cond code.

There are several more places later in this function that
will have the same basic problem.

Theoretically R600 should hit this problem for a test,
but for some reason it doesn't.

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

lib/CodeGen/SelectionDAG/TargetLowering.cpp

index 82e5ae8..115129e 100644 (file)
@@ -1470,24 +1470,32 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
     // Canonicalize GE/LE comparisons to use GT/LT comparisons.
     if (Cond == ISD::SETGE || Cond == ISD::SETUGE) {
       if (C1 == MinVal) return DAG.getConstant(1, VT);   // X >= MIN --> true
-      // X >= C0 --> X > (C0-1)
-      APInt C = C1-1;
-      if (!N1C->isOpaque() || (N1C->isOpaque() && C.getBitWidth() <= 64 &&
-                               isLegalICmpImmediate(C.getSExtValue())))
+      // X >= C0 --> X > (C0 - 1)
+      APInt C = C1 - 1;
+      ISD::CondCode NewCC = (Cond == ISD::SETGE) ? ISD::SETGT : ISD::SETUGT;
+      if ((DCI.isBeforeLegalizeOps() ||
+           isCondCodeLegal(NewCC, VT.getSimpleVT())) &&
+          (!N1C->isOpaque() || (N1C->isOpaque() && C.getBitWidth() <= 64 &&
+                                isLegalICmpImmediate(C.getSExtValue())))) {
         return DAG.getSetCC(dl, VT, N0,
                             DAG.getConstant(C, N1.getValueType()),
-                            (Cond == ISD::SETGE) ? ISD::SETGT : ISD::SETUGT);
+                            NewCC);
+      }
     }
 
     if (Cond == ISD::SETLE || Cond == ISD::SETULE) {
       if (C1 == MaxVal) return DAG.getConstant(1, VT);   // X <= MAX --> true
-      // X <= C0 --> X < (C0+1)
-      APInt C = C1+1;
-      if (!N1C->isOpaque() || (N1C->isOpaque() && C.getBitWidth() <= 64 &&
-                               isLegalICmpImmediate(C.getSExtValue())))
+      // X <= C0 --> X < (C0 + 1)
+      APInt C = C1 + 1;
+      ISD::CondCode NewCC = (Cond == ISD::SETLE) ? ISD::SETLT : ISD::SETULT;
+      if ((DCI.isBeforeLegalizeOps() ||
+           isCondCodeLegal(NewCC, VT.getSimpleVT())) &&
+          (!N1C->isOpaque() || (N1C->isOpaque() && C.getBitWidth() <= 64 &&
+                                isLegalICmpImmediate(C.getSExtValue())))) {
         return DAG.getSetCC(dl, VT, N0,
                             DAG.getConstant(C, N1.getValueType()),
-                            (Cond == ISD::SETLE) ? ISD::SETLT : ISD::SETULT);
+                            NewCC);
+      }
     }
 
     if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C1 == MinVal)