This fixes BIT_FIELD_REF handling in bswap pass where we need to distinguish an "operation" vs. a load properly.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2016-06-07 Richard Biener <rguent...@suse.de> PR tree-optimization/71428 * tree-ssa-math-opts.c (perform_symbolic_merge): Properly distinguish BIT_FIELD_REF op vs. load. * gcc.dg/torture/pr71428.c: New testcase. Index: gcc/tree-ssa-math-opts.c =================================================================== *** gcc/tree-ssa-math-opts.c (revision 237117) --- gcc/tree-ssa-math-opts.c (working copy) *************** perform_symbolic_merge (gimple *source_s *** 2164,2173 **** struct symbolic_number *n_start; tree rhs1 = gimple_assign_rhs1 (source_stmt1); ! if (TREE_CODE (rhs1) == BIT_FIELD_REF) rhs1 = TREE_OPERAND (rhs1, 0); tree rhs2 = gimple_assign_rhs1 (source_stmt2); ! if (TREE_CODE (rhs2) == BIT_FIELD_REF) rhs2 = TREE_OPERAND (rhs2, 0); /* Sources are different, cancel bswap if they are not memory location with --- 2164,2175 ---- struct symbolic_number *n_start; tree rhs1 = gimple_assign_rhs1 (source_stmt1); ! if (TREE_CODE (rhs1) == BIT_FIELD_REF ! && TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME) rhs1 = TREE_OPERAND (rhs1, 0); tree rhs2 = gimple_assign_rhs1 (source_stmt2); ! if (TREE_CODE (rhs2) == BIT_FIELD_REF ! && TREE_CODE (TREE_OPERAND (rhs2, 0)) == SSA_NAME) rhs2 = TREE_OPERAND (rhs2, 0); /* Sources are different, cancel bswap if they are not memory location with Index: gcc/testsuite/gcc.dg/torture/pr71428.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr71428.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr71428.c (working copy) *************** *** 0 **** --- 1,20 ---- + /* { dg-do run } */ + /* { dg-additional-options "-fno-tree-forwprop -Wno-psabi -w" } */ + + typedef unsigned short v64u16 __attribute__ ((vector_size (64))); + + v64u16 + foo (v64u16 p1) + { + p1[31] |= p1[1]; + return p1; + } + + int + main () + { + v64u16 x = foo ((v64u16){ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }); + if (x[31] != 1) + __builtin_abort(); + return 0; + }