This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] rtlanal: Fix nonzero_bits for non-load paradoxical subregs (PR85925)
- From: Segher Boessenkool <segher at kernel dot crashing dot org>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Segher Boessenkool <segher at kernel dot crashing dot org>, Richard Sandiford <richard dot sandiford at linaro dot org>
- Date: Mon, 4 Jun 2018 12:58:06 +0000
- Subject: [PATCH] rtlanal: Fix nonzero_bits for non-load paradoxical subregs (PR85925)
Hi!
In the PR we have insns:
Trying 23 -> 24:
23: r123:SI=zero_extend(r122:HI)
REG_DEAD r122:HI
24: [r115:SI]=r123:SI
REG_DEAD r123:SI
which should be combined to
(set (mem:SI (reg/f:SI 115 [ pretmp_19 ]) [1 *pretmp_19+0 S4 A32])
(and:SI (subreg:SI (reg:HI 122) 0)
(const_int 32767 [0x7fff])))
But nonzero_bits of reg:HI 122 is 0x7fff, and nonzero_bits1 thinks it
then also has that same nonzero_bits for the subreg. This is not
correct: the bit outside of HImode are undefined. load_extend_op
applies to loads from memory only, not anything else. Which means the
whole AND is optimised away.
Richard, what do you think?
Tested on the testcase for an arm compiler, and bootstrapped and
regression checked on powerpc64-linux {-m32,-m64} (not that that means
much, WORD_REGISTER_OPERATIONS isn't set there).
Segher
2018-06-04 Segher Boessenkool <segher@kernel.crashing.org>
PR rtl-optimization/85925
* rtlanal.c (nonzero_bits1): For any paradoxical subreg of
something other than memory the high bits are undefined.
---
gcc/rtlanal.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index ac3662d..6f171de 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -4742,17 +4742,17 @@ nonzero_bits1 (const_rtx x, scalar_int_mode mode, const_rtx known_x,
nonzero &= cached_nonzero_bits (SUBREG_REG (x), mode,
known_x, known_mode, known_ret);
- /* On many CISC machines, accessing an object in a wider mode
+ /* On many CISC machines, accessing an object in a wider mode
causes the high-order bits to become undefined. So they are
not known to be zero. */
rtx_code extend_op;
if ((!WORD_REGISTER_OPERATIONS
/* If this is a typical RISC machine, we only have to worry
about the way loads are extended. */
+ || !MEM_P (SUBREG_REG (x))
|| ((extend_op = load_extend_op (inner_mode)) == SIGN_EXTEND
? val_signbit_known_set_p (inner_mode, nonzero)
- : extend_op != ZERO_EXTEND)
- || (!MEM_P (SUBREG_REG (x)) && !REG_P (SUBREG_REG (x))))
+ : extend_op != ZERO_EXTEND))
&& xmode_width > inner_width)
nonzero
|= (GET_MODE_MASK (GET_MODE (x)) & ~GET_MODE_MASK (inner_mode));
--
1.8.3.1