[ This patch is part of the SVE series posted here: https://gcc.gnu.org/ml/gcc/2016-11/msg00030.html ]
The old assignment to bitwidth was before we handled VOIDmode with: if (mode == VOIDmode) mode = GET_MODE (x); so when VOIDmode was specified we would always use: if (bitwidth < GET_MODE_PRECISION (GET_MODE (x))) { num0 = cached_num_sign_bit_copies (x, GET_MODE (x), known_x, known_mode, known_ret); return MAX (1, num0 - (int) (GET_MODE_PRECISION (GET_MODE (x)) - bitwidth)); } For a zero bitwidth this always returns 1 (which is the most pessimistic result). Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install? Thanks, Richard gcc/ 2016-11-15 Richard Sandiford <richard.sandif...@arm.com> Alan Hayward <alan.hayw...@arm.com> David Sherwood <david.sherw...@arm.com> * rtlanal.c (num_sign_bit_copies1): Calculate bitwidth after handling VOIDmode. diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 4617e8e..35e95f2 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -4795,7 +4795,6 @@ num_sign_bit_copies1 (const_rtx x, machine_mode mode, const_rtx known_x, unsigned int known_ret) { enum rtx_code code = GET_CODE (x); - unsigned int bitwidth = GET_MODE_PRECISION (mode); machine_mode inner_mode; int num0, num1, result; unsigned HOST_WIDE_INT nonzero; @@ -4812,6 +4811,7 @@ num_sign_bit_copies1 (const_rtx x, machine_mode mode, const_rtx known_x, return 1; /* For a smaller object, just ignore the high bits. */ + unsigned int bitwidth = GET_MODE_PRECISION (mode); if (bitwidth < GET_MODE_PRECISION (GET_MODE (x))) { num0 = cached_num_sign_bit_copies (x, GET_MODE (x),