The validity check in do_check_validity was passing the address mode
(GET_MODE of the address RTX, e.g. DImode) to memory_address_addr_space_p
instead of the memory access mode (GET_MODE of the MEM RTX, e.g. SImode).
The first argument to memory_address_addr_space_p is the mode of the
memory access, not the address mode.
On targets where address validity depends on the access width (e.g.
alignment-sensitive modes, vector modes), this could accept an illegal
offset or reject a valid one.
Rename the variable to 'addr_mode' for address construction and add a
separate 'mem_mode' for the validity check.
gcc/ChangeLog:
* fold-mem-offsets.cc (do_check_validity): fix wrong mode
and rename arguments to avoid future confusion
---
gcc/fold-mem-offsets.cc | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/gcc/fold-mem-offsets.cc b/gcc/fold-mem-offsets.cc
index 9ac4a59ace6b..1cd2dc036c2f 100644
--- a/gcc/fold-mem-offsets.cc
+++ b/gcc/fold-mem-offsets.cc
@@ -688,14 +688,16 @@ do_check_validity (rtx_insn *insn, fold_mem_info *info)
int icode = INSN_CODE (insn);
INSN_CODE (insn) = -1;
rtx mem_addr = XEXP (mem, 0);
- machine_mode mode = GET_MODE (mem_addr);
+ machine_mode addr_mode = GET_MODE (mem_addr);
+ machine_mode mem_mode = GET_MODE (mem);
if (new_offset != 0)
- XEXP (mem, 0) = gen_rtx_PLUS (mode, reg, gen_int_mode (new_offset, mode));
+ XEXP (mem, 0) = gen_rtx_PLUS (addr_mode, reg,
+ gen_int_mode (new_offset, addr_mode));
else
XEXP (mem, 0) = reg;
bool illegal = insn_invalid_p (insn, false)
- || !memory_address_addr_space_p (mode, XEXP (mem, 0),
+ || !memory_address_addr_space_p (mem_mode, XEXP (mem, 0),
MEM_ADDR_SPACE (mem));
/* Restore the instruction. */
--
2.34.1