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

Reply via email to