This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RS6000] Fix ICE storing long long to mem.


This patch fixes a regression introduced by
http://gcc.gnu.org/ml/gcc-patches/2004-07/msg02711.html and
http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00022.html

On powerpc-linux, we have the following generated by -fprofile-generate
to increment long long counters:

(insn 4143 1260 4144 219 (set (reg:SI 1823)
        (high:SI (const:SI (plus:SI (symbol_ref:SI ("*.LPBX1") [flags 0x2])
                    (const_int 26640 [0x6810]))))) -1 (nil)
    (nil))

(insn 4144 4143 4145 219 (set (reg/f:SI 1822)
        (lo_sum:SI (reg:SI 1823)
            (const:SI (plus:SI (symbol_ref:SI ("*.LPBX1") [flags 0x2])
                    (const_int 26640 [0x6810]))))) -1 (nil)
    (expr_list:REG_EQUAL (const:SI (plus:SI (symbol_ref:SI ("*.LPBX1") [flags 0x2])
                (const_int 26640 [0x6810])))
        (nil)))

(insn 4145 4144 4146 219 (set (reg:DI 1824)
        (mem/c:DI (reg/f:SI 1822) [3633 S8 A8])) -1 (nil)
    (nil))

(insn 4146 4145 4147 219 (set (reg:DI 1825)
        (plus:DI (reg:DI 1824)
            (const_int 1 [0x1]))) -1 (nil)
    (nil))

(insn 4147 4146 1261 219 (set (mem/c:DI (reg/f:SI 1822) [3633 S8 A8])
        (reg:DI 1825)) -1 (nil)
    (nil))


cse2 turns this into:


(insn 4144 4143 4145 173 (set (reg/f:SI 1822)
        (lo_sum:SI (reg/f:SI 1823)
            (const:SI (plus:SI (symbol_ref:SI ("*.LPBX1") [flags 0x2])
                    (const_int 26640 [0x6810]))))) 219 {elf_low} (nil)
    (expr_list:REG_EQUAL (const:SI (plus:SI (symbol_ref:SI ("*.LPBX1") [flags 0x2])
                (const_int 26640 [0x6810])))
        (nil)))

(insn 4145 4144 4146 173 (set (reg:DI 1824)
        (mem/c:DI (lo_sum:SI (reg/f:SI 1823)
                (const:SI (plus:SI (symbol_ref:SI ("*.LPBX1") [flags 0x2])
                        (const_int 26640 [0x6810])))) [3633 S8 A8])) 239 {*movdi_internal32} (nil)
    (nil))

(insn 4146 4145 4147 173 (set (reg:DI 1825)
        (plus:DI (reg:DI 1824)
            (const_int 1 [0x1]))) 180 {*adddi3_noppc64} (nil)
    (nil))

(insn 4147 4146 1261 173 (set (mem/c:DI (lo_sum:SI (reg/f:SI 1823)
                (const:SI (plus:SI (symbol_ref:SI ("*.LPBX1") [flags 0x2])
                        (const_int 26640 [0x6810])))) [3633 S8 A8])
        (reg:DI 1825)) 239 {*movdi_internal32} (nil)
    (nil))


And now we have a problem if (reg:DI 1825) is allocated to a pair of
gprs.  Since LO_SUM addresses can't be offset on powerpc, we can't store
the second reg without a temp to calculate the new offset.

The following patch fixes this by preventing CSE from doing the LO_SUM
address transformation for DImode and other 64-bit quantities when
generating 32-bit code.  Prior to Geoff's first patch, this test looked
like:

      if (GET_MODE_BITSIZE (mode) > 32
	  && !(TARGET_HARD_FLOAT && TARGET_FPRS && mode == DFmode))

but that is bogus since we can have DFmode values in gprs.
Unfortunately, this does mean poorer code when accessing memory with
fprs.  I'm not sure what to do about that, perhaps a peephole..

Bootstrapped etc. powerpc-linux and powerpc64-linux.  OK to apply?

	PR target/18751
	* config/rs6000/rs6000.c (legitimate_lo_sum_address_p): Return
	false for anything larger that 32-bit in 32-bit code.

--- gcc-virgin/gcc/config/rs6000/rs6000.c	2004-12-04 09:27:27.000000000 +1030
+++ gcc-current/gcc/config/rs6000/rs6000.c	2004-12-07 00:22:47.000000000 +1030
@@ -3339,7 +3339,8 @@ legitimate_lo_sum_address_p (enum machin
 	return false;
       if (GET_MODE_NUNITS (mode) != 1)
 	return false;
-      if (GET_MODE_BITSIZE (mode) > 64)
+      if (GET_MODE_BITSIZE (mode) > 64
+	  || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64))
 	return false;
 
       return CONSTANT_P (x);

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]