Hi!

build_low_bits_mask doesn't work for vector types (even TYPE_PRECISION
alone on it is meaningless), but what we actually want is a constant with
all bits set.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2014-03-11  Jakub Jelinek  <ja...@redhat.com>
            Marc Glisse  <marc.gli...@inria.fr>

        PR tree-optimization/60502
        * tree-ssa-reassoc.c (eliminate_not_pairs): Use build_all_ones_cst
        instead of build_low_bits_mask.

        * gcc.c-torture/compile/pr60502.c: New test.

--- gcc/tree-ssa-reassoc.c.jj   2014-03-11 15:47:44.000000000 +0100
+++ gcc/tree-ssa-reassoc.c      2014-03-11 18:47:53.254946786 +0100
@@ -828,8 +828,7 @@ eliminate_not_pairs (enum tree_code opco
          if (opcode == BIT_AND_EXPR)
            oe->op = build_zero_cst (TREE_TYPE (oe->op));
          else if (opcode == BIT_IOR_EXPR)
-           oe->op = build_low_bits_mask (TREE_TYPE (oe->op),
-                                         TYPE_PRECISION (TREE_TYPE (oe->op)));
+           oe->op = build_all_ones_cst (TREE_TYPE (oe->op));
 
          reassociate_stats.ops_eliminated += ops->length () - 1;
          ops->truncate (0);
--- gcc/testsuite/gcc.c-torture/compile/pr60502.c.jj    2014-03-11 
18:36:45.341757473 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr60502.c       2014-03-11 
18:35:58.000000000 +0100
@@ -0,0 +1,18 @@
+/* PR tree-optimization/60502 */
+
+typedef signed char v16i8 __attribute__ ((vector_size (16)));
+typedef unsigned char v16u8 __attribute__ ((vector_size (16)));
+
+void
+foo (v16i8 *x)
+{
+  v16i8 m1 = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 
};
+  *x |= *x ^ m1;
+}
+
+void
+bar (v16u8 *x)
+{
+  v16u8 m1 = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 
};
+  *x |= *x ^ m1;
+}

        Jakub

Reply via email to