[SelectionDAG] add simplifySelect() to reduce code duplication; NFC
authorSanjay Patel <spatel@rotateright.com>
Mon, 19 Nov 2018 14:35:22 +0000 (14:35 +0000)
committerSanjay Patel <spatel@rotateright.com>
Mon, 19 Nov 2018 14:35:22 +0000 (14:35 +0000)
This should be extended to handle FP and vectors in follow-up patches.

llvm-svn: 347210

llvm/include/llvm/CodeGen/SelectionDAG.h
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

index 2a9763f..541abf0 100644 (file)
@@ -962,6 +962,9 @@ public:
                    False, getCondCode(Cond));
   }
 
+  /// Try to simplify a select/vselect into 1 of its operands or a constant.
+  SDValue simplifySelect(SDValue Cond, SDValue TVal, SDValue FVal);
+
   /// VAArg produces a result and token chain, and takes a pointer
   /// and a source value as input.
   SDValue getVAArg(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr,
index 0f428b7..31589fe 100644 (file)
@@ -7236,24 +7236,8 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
   EVT VT0 = N0.getValueType();
   SDLoc DL(N);
 
-  // select undef, N1, N2 --> N1 (if it's a constant), otherwise N2
-  if (N0.isUndef())
-    return isa<ConstantSDNode>(N1) ? N1 : N2;
-  // select, ?, undef, N2 --> N2
-  if (N1.isUndef())
-    return N2;
-  // select, ?, N1, undef --> N1
-  if (N2.isUndef())
-    return N1;
-
-  // fold (select true, X, Y) -> X
-  // fold (select false, X, Y) -> Y
-  if (auto *N0C = dyn_cast<const ConstantSDNode>(N0))
-    return N0C->isNullValue() ? N2 : N1;
-
-  // select ?, N1, N1 --> N1
-  if (N1 == N2)
-    return N1;
+  if (SDValue V = DAG.simplifySelect(N0, N1, N2))
+    return V;
 
   // fold (select X, X, Y) -> (or X, Y)
   // fold (select X, 1, Y) -> (or C, Y)
index 45c435a..7be9459 100644 (file)
@@ -5078,24 +5078,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
     break;
   }
   case ISD::SELECT:
-    // select undef, N2, N3 --> N2 (if it's a constant), otherwise N3
-    if (N1.isUndef())
-      return isa<ConstantSDNode>(N2) ? N2 : N3;
-    // select, ?, undef, N3 --> N3
-    if (N2.isUndef())
-      return N3;
-    // select, ?, N2, undef --> N2
-    if (N3.isUndef())
-      return N2;
-
-    // select true, N2, N3 --> N2
-    // select false, N2, N3 --> N3
-    if (auto *N1C = dyn_cast<ConstantSDNode>(N1))
-      return N1C->isNullValue() ? N3 : N2;
-
-    // select ?, N2, N2 --> N2
-    if (N2 == N3)
-      return N2;
+    if (SDValue V = simplifySelect(N1, N2, N3))
+      return V;
     break;
   case ISD::VECTOR_SHUFFLE:
     llvm_unreachable("should use getVectorShuffle constructor!");
@@ -6795,6 +6779,29 @@ SDValue SelectionDAG::getMaskedScatter(SDVTList VTs, EVT VT, const SDLoc &dl,
   return V;
 }
 
+SDValue SelectionDAG::simplifySelect(SDValue Cond, SDValue T, SDValue F) {
+  // select undef, T, F --> T (if T is a constant), otherwise F
+  // select, ?, undef, F --> F
+  // select, ?, T, undef --> T
+  if (Cond.isUndef())
+    return isa<ConstantSDNode>(T) ? T : F;
+  if (T.isUndef())
+    return F;
+  if (F.isUndef())
+    return T;
+
+  // fold (select true, T, F) -> T
+  // fold (select false, T, F) -> F
+  if (auto *CondC = dyn_cast<ConstantSDNode>(Cond))
+    return CondC->isNullValue() ? F : T;
+
+  // select ?, T, T --> T
+  if (T == F)
+    return T;
+
+  return SDValue();
+}
+
 SDValue SelectionDAG::getVAArg(EVT VT, const SDLoc &dl, SDValue Chain,
                                SDValue Ptr, SDValue SV, unsigned Align) {
   SDValue Ops[] = { Chain, Ptr, SV, getTargetConstant(Align, dl, MVT::i32) };