fix rtl-opt/15289, part 4
Eric Botcazou
ebotcazou@adacore.com
Sat Dec 4 19:27:00 GMT 2004
> The hardest part here, actually, was making sense of emit_move_insn_1.
> I wound up splitting out seven subroutines in order to help.
I'm still seeing problems on the 3.4 branch, that I don't think we should be
fighting at this stage.
gcc.c-torture/execute/20020411-1.c on SPARC 64-bit: emit_move_complex is
invoked with:
mode = SCmode
x = (reg/i:SC 32 %f0)
y = (concat:SC (reg:SF 107 [ <result> ])
(reg:SF 108 [ <result>+4 ]))
and generates:
(insn 49 48 50 (clobber (reg/i:SC 32 %f0)) -1 (nil)
(nil))
(insn 50 49 51 (set (reg:DI 132)
(zero_extend:DI (subreg:SI (reg:SF 107 [ <result> ]) 0))) -1 (nil)
(nil))
(insn 51 50 52 (set (reg:DI 133)
(ashift:DI (reg:DI 132)
(const_int 32 [0x20]))) -1 (nil)
(nil))
(insn 52 51 53 (set (reg:DI 135)
(const_int -1 [0xffffffffffffffff])) -1 (nil)
(nil))
(insn 53 52 54 (set (reg:DI 134)
(lshiftrt:DI (reg:DI 135)
(const_int 32 [0x20]))) -1 (nil)
(expr_list:REG_EQUAL (const_int 4294967295 [0xffffffff])
(nil)))
(insn 54 53 55 (set (subreg:DI (reg/i:SC 32 %f0) 0)
(and:DI (subreg:DI (reg/i:SC 32 %f0) 0)
(reg:DI 134))) -1 (nil)
(nil))
(insn 55 54 56 (set (subreg:DI (reg/i:SC 32 %f0) 0)
(ior:DI (subreg:DI (reg/i:SC 32 %f0) 0)
(reg:DI 133))) -1 (nil)
(nil))
(insn 56 55 57 (set (reg:DI 136)
(zero_extend:DI (subreg:SI (reg:SF 108 [ <result>+4 ]) 0))) -1 (nil)
(nil))
(insn 57 56 58 (set (reg:DI 138)
(const_int -1 [0xffffffffffffffff])) -1 (nil)
(nil))
(insn 58 57 59 (set (reg:DI 137)
(ashift:DI (reg:DI 138)
(const_int 32 [0x20]))) -1 (nil)
(expr_list:REG_EQUAL (const_int -4294967296 [0xffffffff00000000])
(nil)))
(insn 59 58 60 (set (subreg:DI (reg/i:SC 32 %f0) 0)
(and:DI (subreg:DI (reg/i:SC 32 %f0) 0)
(reg:DI 137))) -1 (nil)
(nil))
(insn 60 59 62 (set (subreg:DI (reg/i:SC 32 %f0) 0)
(ior:DI (subreg:DI (reg/i:SC 32 %f0) 0)
(reg:DI 136))) -1 (nil)
(nil))
This leads to problems later with register liveness info and eventually an ICE
at -O3 in regrename. Before your patch the compiler was emitting instead:
(insn 40 39 41 (set (mem/f:SF (plus:DI (reg/f:DI 103 virtual-stack-vars)
(const_int -8 [0xfffffffffffffff8])) [5 S4 A64])
(reg:SF 107 [ <result> ])) -1 (nil)
(nil))
(insn 41 40 42 (set (mem/f:SF (plus:DI (reg/f:DI 103 virtual-stack-vars)
(const_int -4 [0xfffffffffffffffc])) [5 S4 A32])
(reg:SF 108 [ <result>+4 ])) -1 (nil)
(nil))
(insn 42 41 44 (set (subreg:DF (reg/i:SC 32 %f0) 0)
(mem/f:DF (plus:DI (reg/f:DI 103 virtual-stack-vars)
(const_int -8 [0xfffffffffffffff8])) [5 S8 A64])) -1 (nil)
(nil))
gcc.dg/compat/scalar-return-3_y.c: the compiler emits unaligned word moves:
(mem/f:CSI (plus:DI (reg/f:DI 103 virtual-stack-vars)
(const_int -12 [0xfffffffffffffff4])) [0 rslt+0 S8 A64])
What happens is that assign_stack_temp_for_type uses the alignment of the mode
while set_mem_attributes_minus_bitpos uses the alignment of the variable and
overrides the previous alignment.
Fixing the former problem with something like:
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.615.4.17
diff -u -p -r1.615.4.17 expr.c
--- expr.c 3 Dec 2004 19:50:35 -0000 1.615.4.17
+++ expr.c 4 Dec 2004 17:13:59 -0000
@@ -2812,7 +2812,15 @@ write_complex_part (rtx cplx, rtx val, b
will work. This special case is important, since store_bit_field
wants to operate on integer modes, and there's rarely an OImode to
correspond to TCmode. */
- if (ibitsize >= BITS_PER_WORD)
+ if (ibitsize >= BITS_PER_WORD
+ /* For hard regs we have the right predicate. This case
+ is important for SCmode regs on 64-bit targets. */
+ || (GET_CODE (cplx) == REG
+ && REGNO (cplx) < FIRST_PSEUDO_REGISTER
+ && subreg_offset_representable_p (REGNO (cplx),
+ cmode,
+ imag_p ? GET_MODE_SIZE (imode) : 0,
+ imode)))
{
rtx part = simplify_gen_subreg (imode, cplx, cmode,
imag_p ? GET_MODE_SIZE (imode) : 0);
@@ -2856,7 +2864,15 @@ read_complex_part (rtx cplx, bool imag_p
will work. This special case is important, since extract_bit_field
wants to operate on integer modes, and there's rarely an OImode to
correspond to TCmode. */
- if (ibitsize >= BITS_PER_WORD)
+ if (ibitsize >= BITS_PER_WORD
+ /* For hard regs we have the right predicate. This case
+ is important for SCmode regs on 64-bit targets. */
+ || (GET_CODE (cplx) == REG
+ && REGNO (cplx) < FIRST_PSEUDO_REGISTER
+ && subreg_offset_representable_p (REGNO (cplx),
+ cmode,
+ imag_p ? GET_MODE_SIZE (imode) : 0,
+ imode)))
{
rtx ret = simplify_gen_subreg (imode, cplx, cmode,
imag_p ? GET_MODE_SIZE (imode) : 0);
leads to more failures in the compat testsuite on complex integers.
So I'm again asking you to reconsider your position on the appropriateness of
these patches for the 3.4 branch.
--
Eric Botcazou
More information about the Gcc-patches
mailing list