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