diff options
Diffstat (limited to 'recipes/gcc/gcc-4.3.2/debian/pr30961.dpatch')
-rw-r--r-- | recipes/gcc/gcc-4.3.2/debian/pr30961.dpatch | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/recipes/gcc/gcc-4.3.2/debian/pr30961.dpatch b/recipes/gcc/gcc-4.3.2/debian/pr30961.dpatch new file mode 100644 index 0000000000..b20fdf5bf5 --- /dev/null +++ b/recipes/gcc/gcc-4.3.2/debian/pr30961.dpatch @@ -0,0 +1,179 @@ +#! /bin/sh -e + +# DP: <your description> + +dir= +if [ $# -eq 3 -a "$2" = '-d' ]; then + pdir="-d $3" + dir="$3/" +elif [ $# -ne 1 ]; then + echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" + exit 1 +fi +case "$1" in + -patch) + patch $pdir -f --no-backup-if-mismatch -p0 < $0 + ;; + -unpatch) + patch $pdir -f --no-backup-if-mismatch -R -p0 < $0 + ;; + *) + echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" + exit 1 +esac +exit 0 + +From: "H.J. Lu" <hjl@lucon.org> +Sender: gcc-patches-owner@gcc.gnu.org +To: gcc-patches@gcc.gnu.org +Subject: PATCH: PR target/30961: [4.1/4.2/4.3 regression] redundant reg/mem stores/moves +Date: Mon, 27 Aug 2007 11:34:12 -0700 + +We start with + +(note:HI 3 4 22 2 NOTE_INSN_FUNCTION_BEG) + +(insn:HI 6 3 10 2 c.c:3 (set (reg:DF 58 [ <result> ]) + (subreg:DF (reg/v:DI 59 [ in ]) 0)) 102 {*movdf_integer_rex64} (expr_list:REG_DEAD (reg/v:DI 59 [ in ]) + (nil))) + +(insn:HI 10 6 16 2 c.c:7 (set (reg/i:DF 21 xmm0 [ <result> ]) + (reg:DF 58 [ <result> ])) 102 {*movdf_integer_rex64} (expr_list:REG_DEAD (reg:DF 58 [ <result> ]) + (nil))) + +(insn:HI 16 10 0 2 c.c:7 (use (reg/i:DF 21 xmm0 [ <result> ])) -1 (nil)) + +we are trying to allocate registers for insn 6 and we allocate +xmm0 for the return value. Reload doesn't check if xmm0 can be used for +DF 59, it allocates xmm1 for DF 59 and generates: + +Reloads for insn # 6 +Reload 0: reload_in (DF) = (reg:DF 5 di) + SSE_REGS, RELOAD_FOR_INPUT (opnum = 1), can't combine + reload_in_reg: (subreg:DF (reg/v:DI 5 di [orig:59 in ] [59]) 0) + reload_reg_rtx: (reg:DF 22 xmm1) +... + +(note:HI 4 1 3 2 [bb 2] NOTE_INSN_BASIC_BLOCK) + +(note:HI 3 4 22 2 NOTE_INSN_FUNCTION_BEG) + +(insn 22 3 23 2 c.c:3 (set (mem/c:DF (plus:DI (reg/f:DI 7 sp) + (const_int -8 [0xfffffffffffffff8])) [0 S8 A8]) + (reg:DF 5 di)) 102 {*movdf_integer_rex64} (nil)) + +(insn 23 22 6 2 c.c:3 (set (reg:DF 22 xmm1) + (mem/c:DF (plus:DI (reg/f:DI 7 sp) + (const_int -8 [0xfffffffffffffff8])) [0 S8 A8])) 102 {*movdf_integer_rex64} (nil)) + +(insn:HI 6 23 16 2 c.c:3 (set (reg:DF 21 xmm0 [orig:58 <result> ] [58]) + (reg:DF 22 xmm1)) 102 {*movdf_integer_rex64} (nil)) + +(insn 16 6 21 2 c.c:7 (use (reg/i:DF 21 xmm0 [ <result> ])) -1 (nil)) + +This patch tries to use the destination register when reloading for input. It +generates + +Reloads for insn # 6 +Reload 0: reload_in (DF) = (reg:DF 5 di) + SSE_REGS, RELOAD_FOR_INPUT (opnum = 1), can't combine + reload_in_reg: (subreg:DF (reg/v:DI 5 di [orig:59 in ] [59]) 0) + reload_reg_rtx: (reg:DF 21 xmm0) +... +(note:HI 4 1 3 2 [bb 2] NOTE_INSN_BASIC_BLOCK) + +(note:HI 3 4 22 2 NOTE_INSN_FUNCTION_BEG) + +(insn 22 3 23 2 c.c:3 (set (mem/c:DF (plus:DI (reg/f:DI 7 sp) + (const_int -8 [0xfffffffffffffff8])) [0 S8 A8]) + (reg:DF 5 di)) 102 {*movdf_integer_rex64} (nil)) + +(insn 23 22 6 2 c.c:3 (set (reg:DF 21 xmm0) + (mem/c:DF (plus:DI (reg/f:DI 7 sp) + (const_int -8 [0xfffffffffffffff8])) [0 S8 A8])) 102 {*movdf_integer_rex64} (nil)) + +(insn:HI 6 23 10 2 c.c:3 (set (reg:DF 22 xmm1 [orig:58 <result> ] [58]) + (reg:DF 21 xmm0)) 102 {*movdf_integer_rex64} (nil)) + +(insn:HI 10 6 16 2 c.c:7 (set (reg/i:DF 21 xmm0 [ <result> ]) + (reg:DF 22 xmm1 [orig:58 <result> ] [58])) 102 {*movdf_integer_rex64} (nil)) + +(insn 16 10 21 2 c.c:7 (use (reg/i:DF 21 xmm0 [ <result> ])) -1 (nil)) + + +H.J. +---- +gcc/ + +2007-08-27 H.J. Lu <hongjiu.lu@intel.com> + + PR target/30961 + * reload1.c (find_reg): Favor the hard register in destination + if it is usable and a memory location is needed for reload + input. + +gcc/testsuite/ + +2007-08-27 H.J. Lu <hongjiu.lu@intel.com> + + PR target/30961 + * gcc.target/i386/pr30961-1.c: New. + +--- gcc/reload1.c.second 2007-08-27 09:35:08.000000000 -0700 ++++ gcc/reload1.c 2007-08-27 09:36:33.000000000 -0700 +@@ -1781,6 +1781,20 @@ find_reg (struct insn_chain *chain, int + HARD_REG_SET not_usable; + HARD_REG_SET used_by_other_reload; + reg_set_iterator rsi; ++#ifdef SECONDARY_MEMORY_NEEDED ++ rtx body = PATTERN (chain->insn); ++ unsigned int dest_reg = FIRST_PSEUDO_REGISTER; ++ ++ if (GET_CODE (body) == SET) ++ { ++ rtx dest = SET_DEST (body); ++ ++ if ((REG_P (dest) ++ || (GET_CODE (dest) == SUBREG ++ && REG_P (SUBREG_REG (dest))))) ++ dest_reg = reg_or_subregno (dest); ++ } ++#endif + + COPY_HARD_REG_SET (not_usable, bad_spill_regs); + IOR_HARD_REG_SET (not_usable, bad_spill_regs_global); +@@ -1821,6 +1835,18 @@ find_reg (struct insn_chain *chain, int + this_cost--; + if (rl->out && REG_P (rl->out) && REGNO (rl->out) == regno) + this_cost--; ++#ifdef SECONDARY_MEMORY_NEEDED ++ /* If a memory location is needed for rl->in and dest_reg ++ is usable, we will favor it. */ ++ else if (dest_reg == regno ++ && rl->in ++ && REG_P (rl->in) ++ && REGNO (rl->in) < FIRST_PSEUDO_REGISTER ++ && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (rl->in)), ++ rl->class, ++ rl->mode)) ++ this_cost = 0; ++#endif + if (this_cost < best_cost + /* Among registers with equal cost, prefer caller-saved ones, or + use REG_ALLOC_ORDER if it is defined. */ +--- gcc/testsuite/gcc.target/i386/pr30961-1.c.second 2007-08-27 11:01:59.000000000 -0700 ++++ gcc/testsuite/gcc.target/i386/pr30961-1.c 2007-08-27 11:02:51.000000000 -0700 +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target lp64 } */ ++/* { dg-options "-O2" } */ ++ ++double ++convert (long long in) ++{ ++ double f; ++ __builtin_memcpy( &f, &in, sizeof( in ) ); ++ return f; ++} ++ ++/* { dg-final { scan-assembler-not "movapd" } } */ |