summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/CodeGen/SelectionDAGNodes.h4
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp17
-rw-r--r--llvm/test/CodeGen/X86/combine-shl.ll12
-rw-r--r--llvm/test/CodeGen/X86/combine-sra.ll11
-rw-r--r--llvm/test/CodeGen/X86/combine-srl.ll11
5 files changed, 25 insertions, 30 deletions
diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
index 2931717b72d..9d98df04421 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/llvm/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<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.
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index d69e50d9007..a1ce77455e9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -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();
diff --git a/llvm/test/CodeGen/X86/combine-shl.ll b/llvm/test/CodeGen/X86/combine-shl.ll
index 3cb1dd65e9c..d7cd5451bef 100644
--- a/llvm/test/CodeGen/X86/combine-shl.ll
+++ b/llvm/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, <i32 33, i32 34, i32 35, i32 undef>
ret <4 x i32> %1
}
diff --git a/llvm/test/CodeGen/X86/combine-sra.ll b/llvm/test/CodeGen/X86/combine-sra.ll
index f8b536ac553..4a14991c5eb 100644
--- a/llvm/test/CodeGen/X86/combine-sra.ll
+++ b/llvm/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, <i32 33, i32 34, i32 35, i32 undef>
ret <4 x i32> %1
}
diff --git a/llvm/test/CodeGen/X86/combine-srl.ll b/llvm/test/CodeGen/X86/combine-srl.ll
index 2dd1fa74871..960aa079e4c 100644
--- a/llvm/test/CodeGen/X86/combine-srl.ll
+++ b/llvm/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, <i32 33, i32 34, i32 35, i32 undef>
ret <4 x i32> %1
}
OpenPOWER on IntegriCloud