]> granicus.if.org Git - llvm/commitdiff
[SelectionDAG] Optional handling of UNDEF elements in matchUnaryPredicate
authorSimon Pilgrim <llvm-dev@redking.me.uk>
Wed, 19 Dec 2018 10:41:06 +0000 (10:41 +0000)
committerSimon Pilgrim <llvm-dev@redking.me.uk>
Wed, 19 Dec 2018 10:41:06 +0000 (10:41 +0000)
Now that SimplifyDemandedBits/SimplifyDemandedVectorElts are simplifying vector elements, we're seeing more constant BUILD_VECTOR containing UNDEFs.

This patch provides opt-in handling of UNDEF elements in matchUnaryPredicate, passing NULL instead of the ConstantSDNode* argument.

I've updated SelectionDAG::simplifyShift to demonstrate its use.

Differential Revision: https://reviews.llvm.org/D55819

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

include/llvm/CodeGen/SelectionDAGNodes.h
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
test/CodeGen/X86/combine-shl.ll
test/CodeGen/X86/combine-sra.ll
test/CodeGen/X86/combine-srl.ll

index 2931717b72deb1dafe45c442a5e904a57ea84fc8..9d98df04421198ebb907a1b4c0dd3cc72e58c777 100644 (file)
@@ -2487,8 +2487,10 @@ namespace ISD {
 
   /// Attempt to match a unary predicate against a scalar/splat constant or
   /// every element of a constant BUILD_VECTOR.
+  /// If AllowUndef is true, then UNDEF element will pass nullptr to Match.
   bool matchUnaryPredicate(SDValue Op,
-                           std::function<bool(ConstantSDNode *)> Match);
+                           std::function<bool(ConstantSDNode *)> Match,
+                           bool AllowUndefs = false);
 
   /// Attempt to match a binary predicate against a pair of scalar/splat
   /// constants or every element of a pair of constant BUILD_VECTORs.
index d69e50d9007be7ae2d2a00aa773b764684a2b39b..a1ce77455e96420ff815c83af7d77276840857fa 100644 (file)
@@ -269,15 +269,24 @@ bool ISD::allOperandsUndef(const SDNode *N) {
 }
 
 bool ISD::matchUnaryPredicate(SDValue Op,
-                              std::function<bool(ConstantSDNode *)> Match) {
+                              std::function<bool(ConstantSDNode *)> Match,
+                              bool AllowUndefs) {
+  // FIXME: Add support for scalar UNDEF cases?
   if (auto *Cst = dyn_cast<ConstantSDNode>(Op))
     return Match(Cst);
 
+  // FIXME: Add support for vector UNDEF cases?
   if (ISD::BUILD_VECTOR != Op.getOpcode())
     return false;
 
   EVT SVT = Op.getValueType().getScalarType();
   for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) {
+    if (AllowUndefs && Op.getOperand(i).isUndef()) {
+      if (!Match(nullptr))
+        return false;
+      continue;
+    }
+
     auto *Cst = dyn_cast<ConstantSDNode>(Op.getOperand(i));
     if (!Cst || Cst->getValueType(0) != SVT || !Match(Cst))
       return false;
@@ -6967,11 +6976,11 @@ SDValue SelectionDAG::simplifyShift(SDValue X, SDValue Y) {
     return X;
 
   // shift X, C >= bitwidth(X) --> undef
-  // All vector elements must be too big to avoid partial undefs.
+  // All vector elements must be too big (or undef) to avoid partial undefs.
   auto isShiftTooBig = [X](ConstantSDNode *Val) {
-    return Val->getAPIntValue().uge(X.getScalarValueSizeInBits());
+    return !Val || Val->getAPIntValue().uge(X.getScalarValueSizeInBits());
   };
-  if (ISD::matchUnaryPredicate(Y, isShiftTooBig))
+  if (ISD::matchUnaryPredicate(Y, isShiftTooBig, true))
     return getUNDEF(X.getValueType());
 
   return SDValue();
index 3cb1dd65e9ce925dced13c6789851dd027d10e53..d7cd5451bef6dda9079f341b5f02a60faf382ebe 100644 (file)
@@ -46,15 +46,9 @@ define <4 x i32> @combine_vec_shl_outofrange2(<4 x i32> %a0) {
 }
 
 define <4 x i32> @combine_vec_shl_outofrange3(<4 x i32> %a0) {
-; SSE-LABEL: combine_vec_shl_outofrange3:
-; SSE:       # %bb.0:
-; SSE-NEXT:    xorps %xmm0, %xmm0
-; SSE-NEXT:    retq
-;
-; AVX-LABEL: combine_vec_shl_outofrange3:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vpsllvd {{.*}}(%rip), %xmm0, %xmm0
-; AVX-NEXT:    retq
+; CHECK-LABEL: combine_vec_shl_outofrange3:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    retq
   %1 = shl <4 x i32> %a0, <i32 33, i32 34, i32 35, i32 undef>
   ret <4 x i32> %1
 }
index f8b536ac553ae8569167be8f942d100c3c96fd75..4a14991c5eb5e89b9045b02b47cf9f71eb861157 100644 (file)
@@ -51,14 +51,9 @@ define <4 x i32> @combine_vec_ashr_outofrange1(<4 x i32> %x) {
 }
 
 define <4 x i32> @combine_vec_ashr_outofrange2(<4 x i32> %x) {
-; SSE-LABEL: combine_vec_ashr_outofrange2:
-; SSE:       # %bb.0:
-; SSE-NEXT:    retq
-;
-; AVX-LABEL: combine_vec_ashr_outofrange2:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vpsravd {{.*}}(%rip), %xmm0, %xmm0
-; AVX-NEXT:    retq
+; CHECK-LABEL: combine_vec_ashr_outofrange2:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    retq
   %1 = ashr <4 x i32> %x, <i32 33, i32 34, i32 35, i32 undef>
   ret <4 x i32> %1
 }
index 2dd1fa74871af05e2952b0e098cccb1550149795..960aa079e4c0b3b3813a1d51b33faaac4de55f85 100644 (file)
@@ -36,14 +36,9 @@ define <4 x i32> @combine_vec_lshr_outofrange1(<4 x i32> %x) {
 }
 
 define <4 x i32> @combine_vec_lshr_outofrange2(<4 x i32> %x) {
-; SSE-LABEL: combine_vec_lshr_outofrange2:
-; SSE:       # %bb.0:
-; SSE-NEXT:    retq
-;
-; AVX-LABEL: combine_vec_lshr_outofrange2:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vpsrlvd {{.*}}(%rip), %xmm0, %xmm0
-; AVX-NEXT:    retq
+; CHECK-LABEL: combine_vec_lshr_outofrange2:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    retq
   %1 = lshr <4 x i32> %x, <i32 33, i32 34, i32 35, i32 undef>
   ret <4 x i32> %1
 }