aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorDavid Edelsohn <edelsohn@gnu.org>2005-07-02 23:06:40 +0000
committerDavid Edelsohn <edelsohn@gnu.org>2005-07-02 23:06:40 +0000
commitb3b41c4cf9ef028578574e95a4f936c77b44084a (patch)
tree88e11d66bf721bd40638fb338c82eba312c9bd40 /gcc/expr.c
parentaa7e88bba356193a601b545a12c2df613f07bf6e (diff)
PR middle-end/21742
* expr.c (write_complex_part): Use adjust_address for MEM. (read_complex_part): Same. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@101539 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index b9bba08f7f4..a3c1b6ad917 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -2660,6 +2660,16 @@ write_complex_part (rtx cplx, rtx val, bool imag_p)
imode = GET_MODE_INNER (cmode);
ibitsize = GET_MODE_BITSIZE (imode);
+ /* For MEMs simplify_gen_subreg may generate an invalid new address
+ because, e.g., the original address is considered mode-dependent
+ by the target, which restricts simplify_subreg from invoking
+ adjust_address_nv. Instead of preparing fallback support for an
+ invalid address, we call adjust_address_nv directly. */
+ if (MEM_P (cplx))
+ emit_move_insn (adjust_address_nv (cplx, imode,
+ imag_p ? GET_MODE_SIZE (imode) : 0),
+ val);
+
/* If the sub-object is at least word sized, then we know that subregging
will work. This special case is important, since store_bit_field
wants to operate on integer modes, and there's rarely an OImode to
@@ -2671,11 +2681,7 @@ write_complex_part (rtx cplx, rtx val, bool imag_p)
where the natural size of floating-point regs is 32-bit. */
|| (REG_P (cplx)
&& REGNO (cplx) < FIRST_PSEUDO_REGISTER
- && hard_regno_nregs[REGNO (cplx)][cmode] % 2 == 0)
- /* For MEMs we always try to make a "subreg", that is to adjust
- the MEM, because store_bit_field may generate overly
- convoluted RTL for sub-word fields. */
- || MEM_P (cplx))
+ && hard_regno_nregs[REGNO (cplx)][cmode] % 2 == 0))
{
rtx part = simplify_gen_subreg (imode, cplx, cmode,
imag_p ? GET_MODE_SIZE (imode) : 0);
@@ -2720,6 +2726,15 @@ read_complex_part (rtx cplx, bool imag_p)
}
}
+ /* For MEMs simplify_gen_subreg may generate an invalid new address
+ because, e.g., the original address is considered mode-dependent
+ by the target, which restricts simplify_subreg from invoking
+ adjust_address_nv. Instead of preparing fallback support for an
+ invalid address, we call adjust_address_nv directly. */
+ if (MEM_P (cplx))
+ return adjust_address_nv (cplx, imode,
+ imag_p ? GET_MODE_SIZE (imode) : 0);
+
/* If the sub-object is at least word sized, then we know that subregging
will work. This special case is important, since extract_bit_field
wants to operate on integer modes, and there's rarely an OImode to
@@ -2731,11 +2746,7 @@ read_complex_part (rtx cplx, bool imag_p)
where the natural size of floating-point regs is 32-bit. */
|| (REG_P (cplx)
&& REGNO (cplx) < FIRST_PSEUDO_REGISTER
- && hard_regno_nregs[REGNO (cplx)][cmode] % 2 == 0)
- /* For MEMs we always try to make a "subreg", that is to adjust
- the MEM, because extract_bit_field may generate overly
- convoluted RTL for sub-word fields. */
- || MEM_P (cplx))
+ && hard_regno_nregs[REGNO (cplx)][cmode] % 2 == 0))
{
rtx ret = simplify_gen_subreg (imode, cplx, cmode,
imag_p ? GET_MODE_SIZE (imode) : 0);