We may not strip sign-conversions around MIN/MAX operations.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.
PR tree-optimization/122844
* tree-vect-slp.cc (vect_analyze_slp_reduc_chain): Only
try stripping sign conversions around ops where this is valid.
* gcc.dg/vect/vect-pr122844.c: New testcase.
---
gcc/testsuite/gcc.dg/vect/vect-pr122844.c | 34 +++++++++++++++++++++++
gcc/tree-vect-slp.cc | 4 ++-
2 files changed, 37 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.dg/vect/vect-pr122844.c
diff --git a/gcc/testsuite/gcc.dg/vect/vect-pr122844.c
b/gcc/testsuite/gcc.dg/vect/vect-pr122844.c
new file mode 100644
index 00000000000..52da3ec4cb3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-pr122844.c
@@ -0,0 +1,34 @@
+#include "tree-vect.h"
+
+short c = 2;
+short l = 6;
+unsigned char m;
+int k;
+int a = -1;
+unsigned long long t[2][2];
+
+static void b( short c, int k, short l, unsigned m)
+{
+ for( signed x=0; x<2; x++)
+ for( int ab=0; ab<k+2; ab++)
+ a = ({
+ int ac = a;
+ int ad = ({ int ac = l ? m : t[x][0];
+ unsigned long long ad = c ? m : t[x][x];
+ ac < ad ? ac : ad; });
+
+ ac < ad ? ac : ad;
+ });
+}
+
+int main()
+{
+ check_vect ();
+
+ long long ag;
+ b(c,k,l,m);
+ ag = a;
+ if (ag != -1)
+ abort ();
+}
+
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index 23098238b12..5b0de9291cb 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -4310,7 +4310,9 @@ vect_analyze_slp_reduc_chain (loop_vec_info vinfo,
/* When this linearization didn't produce a chain see if stripping
a wrapping sign conversion produces one. */
- if (scalar_stmts.length () == 1)
+ if (scalar_stmts.length () == 1
+ && (code == PLUS_EXPR || code == MULT_EXPR || code == BIT_IOR_EXPR
+ || code == BIT_AND_EXPR || code == BIT_XOR_EXPR))
{
gimple *stmt = scalar_stmts[0]->stmt;
if (!is_gimple_assign (stmt)
--
2.51.0