From: Simon Pilgrim Date: Wed, 19 Dec 2018 10:41:06 +0000 (+0000) Subject: [SelectionDAG] Optional handling of UNDEF elements in matchUnaryPredicate X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=de6808bcecbbb4cb4c8bebf8470b1c9cd4026158;p=llvm [SelectionDAG] Optional handling of UNDEF elements in matchUnaryPredicate 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 --- diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 2931717b72d..9d98df04421 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -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 Match); + std::function 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. diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index d69e50d9007..a1ce77455e9 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -269,15 +269,24 @@ bool ISD::allOperandsUndef(const SDNode *N) { } bool ISD::matchUnaryPredicate(SDValue Op, - std::function Match) { + std::function Match, + bool AllowUndefs) { + // FIXME: Add support for scalar UNDEF cases? if (auto *Cst = dyn_cast(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(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(); diff --git a/test/CodeGen/X86/combine-shl.ll b/test/CodeGen/X86/combine-shl.ll index 3cb1dd65e9c..d7cd5451bef 100644 --- a/test/CodeGen/X86/combine-shl.ll +++ b/test/CodeGen/X86/combine-shl.ll @@ -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, ret <4 x i32> %1 } diff --git a/test/CodeGen/X86/combine-sra.ll b/test/CodeGen/X86/combine-sra.ll index f8b536ac553..4a14991c5eb 100644 --- a/test/CodeGen/X86/combine-sra.ll +++ b/test/CodeGen/X86/combine-sra.ll @@ -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, ret <4 x i32> %1 } diff --git a/test/CodeGen/X86/combine-srl.ll b/test/CodeGen/X86/combine-srl.ll index 2dd1fa74871..960aa079e4c 100644 --- a/test/CodeGen/X86/combine-srl.ll +++ b/test/CodeGen/X86/combine-srl.ll @@ -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, ret <4 x i32> %1 }