Right now forwprop calls into fold to do some folding of comparisons.
But fold is designed for generic which does not have a limitation on
vector comparisons in many cases. So fold turns `a >> signbit != 0`
into `a < 0` but `a < 0` does not exist for the vector type (with a
resulting bool).
Really forwprop should not call into fold but that is an on going
project and should be fixed for GCC 17 (see PR 120206). For now
the way to fix this is to reject the vector comparison if
expand_vec_cmp_expr_p says the comparison is not valid.
Bootstrapped and tested on x86_64-linux-gnu.
PR tree-optimization/123107
gcc/ChangeLog:
* tree-ssa-forwprop.cc (combine_cond_expr_cond): Reject vector
comparisons in some cases.
gcc/testsuite/ChangeLog:
* gcc.dg/torture/pr123107-1.c: New test.
Signed-off-by: Andrew Pinski <[email protected]>
---
gcc/testsuite/gcc.dg/torture/pr123107-1.c | 14 ++++++++++++++
gcc/tree-ssa-forwprop.cc | 12 ++++++++++++
2 files changed, 26 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/torture/pr123107-1.c
diff --git a/gcc/testsuite/gcc.dg/torture/pr123107-1.c
b/gcc/testsuite/gcc.dg/torture/pr123107-1.c
new file mode 100644
index 00000000000..cf70abe9451
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr123107-1.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mavx2" { target i?86-*-* x86_64-*-* } } */
+
+/* PR tree-optimization/123107 */
+/* Forwardprop should check what fold gets back to be valid. */
+
+typedef int vec8short __attribute__((vector_size(8 * sizeof(int))));
+int f( vec8short t)
+{
+ t = t < 0;
+ return !(t[0] | t[1] | t[2] | t[3]
+ | t[4] | t[5] | t[6] | t[7]);
+}
+
diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
index 2200fc04918..7f5820be9c4 100644
--- a/gcc/tree-ssa-forwprop.cc
+++ b/gcc/tree-ssa-forwprop.cc
@@ -428,6 +428,18 @@ combine_cond_expr_cond (gimple *stmt, enum tree_code code,
tree type,
return NULL_TREE;
}
+ /* For vector comparisons, check to make sure fold
+ returns a valid coparison for this target. */
+ if (COMPARISON_CLASS_P (t)
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == VECTOR_TYPE
+ && !expand_vec_cmp_expr_p (TREE_TYPE (TREE_OPERAND (t, 0)),
+ TREE_TYPE (t),
+ TREE_CODE (t)))
+ {
+ fold_undefer_overflow_warnings (false, NULL, 0);
+ return NULL_TREE;
+ }
+
bool nowarn = warning_suppressed_p (stmt, OPT_Wstrict_overflow);
fold_undefer_overflow_warnings (!nowarn, stmt, 0);
--
2.43.0