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