aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2019-10-21 11:38:37 +0000
committerJakub Jelinek <jakub@redhat.com>2019-10-21 11:38:37 +0000
commitbe5218ee24c382d0ac0ae83a265ab4703d9900c6 (patch)
tree5139e4d0dae7aef738a42481e2377a2688e5997a
parentc079ad98d032f198142faa1763102f39ad3e8389 (diff)
Backported from mainline
2019-09-01 Jakub Jelinek <jakub@redhat.com> PR middle-end/91623 * optabs.c (expand_vec_cond_expr): If op0 is a VECTOR_CST and only EQ_EXPR/NE_EXPR is supported, verify that op0 only contains zeros or negative elements and use NE_EXPR instead of LT_EXPR against zero vector. * gcc.target/i386/pr91623.c: New test. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-9-branch@277246 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/optabs.c19
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.target/i386/pr91623.c32
4 files changed, 60 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3316996183b..64d4e31be0e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -14,6 +14,12 @@
2019-09-01 Jakub Jelinek <jakub@redhat.com>
+ PR middle-end/91623
+ * optabs.c (expand_vec_cond_expr): If op0 is a VECTOR_CST and only
+ EQ_EXPR/NE_EXPR is supported, verify that op0 only contains
+ zeros or negative elements and use NE_EXPR instead of LT_EXPR against
+ zero vector.
+
PR lto/91572
* tree.c (find_decls_types_in_node): Also walk TREE_PURPOSE of
GIMPLE_ASM TREE_LIST operands.
diff --git a/gcc/optabs.c b/gcc/optabs.c
index a0e361b8bfe..7d7efe0a4a2 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -5819,6 +5819,25 @@ expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
icode = get_vcond_icode (mode, cmp_op_mode, unsignedp);
if (icode == CODE_FOR_nothing)
{
+ if (tcode == LT_EXPR
+ && op0a == op0
+ && TREE_CODE (op0) == VECTOR_CST)
+ {
+ /* A VEC_COND_EXPR condition could be folded from EQ_EXPR/NE_EXPR
+ into a constant when only get_vcond_eq_icode is supported.
+ Verify < 0 and != 0 behave the same and change it to NE_EXPR. */
+ unsigned HOST_WIDE_INT nelts;
+ if (!VECTOR_CST_NELTS (op0).is_constant (&nelts))
+ {
+ if (VECTOR_CST_STEPPED_P (op0))
+ return 0;
+ nelts = vector_cst_encoded_nelts (op0);
+ }
+ for (unsigned int i = 0; i < nelts; ++i)
+ if (tree_int_cst_sgn (vector_cst_elt (op0, i)) == 1)
+ return 0;
+ tcode = NE_EXPR;
+ }
if (tcode == EQ_EXPR || tcode == NE_EXPR)
icode = get_vcond_eq_icode (mode, cmp_op_mode);
if (icode == CODE_FOR_nothing)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 57e95b2b1aa..28a8cb5b136 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -3,6 +3,9 @@
Backported from mainline
2019-09-01 Jakub Jelinek <jakub@redhat.com>
+ PR middle-end/91623
+ * gcc.target/i386/pr91623.c: New test.
+
PR lto/91572
* g++.dg/lto/pr91572_0.C: New test.
diff --git a/gcc/testsuite/gcc.target/i386/pr91623.c b/gcc/testsuite/gcc.target/i386/pr91623.c
new file mode 100644
index 00000000000..94de4f91c6d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr91623.c
@@ -0,0 +1,32 @@
+/* PR middle-end/91623 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -msse4.1 -mno-sse4.2" } */
+
+typedef long long V __attribute__((__vector_size__(16)));
+V e, h;
+int d;
+const int i;
+
+void foo (void);
+
+void
+bar (int k, int l)
+{
+ if (d && 0 <= k - 1 && l)
+ foo ();
+}
+
+void
+baz (void)
+{
+ V n = (V) { 1 };
+ V g = (V) {};
+ V o = g;
+ for (int f = 0; f < i; ++f)
+ {
+ V a = o == n;
+ h = a;
+ bar (f, i);
+ o = e;
+ }
+}