This is the mail archive of the gcc@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]

Re: reload getting the mode of (subreg:HI (reg:QI pseudo)) wrong


On Thu, Aug 03, 2006 at 11:55:49PM -0700, Ian Lance Taylor wrote:
> 
> In general, operand_mode[] will be unreliable in cases where it is not
> specified.  This is frowned upon but more or less permitted, and a few
> backends take advantage of it for relatively nefarious purposes.

I only have modeless operands in "call_value" and "setmemhi" and I don't
know how that can be avoided. But presumably, GET_MODE_BITSIZE (VOIDmode)
returns something sensible like 0, so it shouldn't be a problem.
 
> Still, I can't think of a better approach for this problem.  It's
> worth a try to set rld[i].mode to operand_mode[] when operand_mode[]
> is larger.  I don't see that you will have to worry about matching
> constraints.  A big-endian system might be an issue; hopefully
> reload_adjust_reg_for_mode is called whereever necessary.

I tried this patch to find_reloads(), and it did solve the problem.

Index: gcc/reload.c
===================================================================
--- gcc/reload.c	(revision 115810)
+++ gcc/reload.c	(working copy)
@@ -4416,6 +4428,12 @@
 	       > GET_MODE_SIZE (rld[i].inmode)))
 	  ? rld[i].outmode : rld[i].inmode;
 
+      /* Don't be fooled by e.g. paradoxical subreg operands.
+	 We need a register which is at least as wide as the operand.  */
+      if (GET_MODE_BITSIZE (rld[i].mode)
+	  < GET_MODE_BITSIZE (operand_mode[rld[i].opnum]))
+	rld[i].mode = operand_mode[i];
+
       rld[i].nregs = CLASS_MAX_NREGS (rld[i].class, rld[i].mode);
     }

Before reload:

(insn:HI 2485 2483 2486 39 ../../../cvssrc/gcc/gcc/libgcc2.c:1825 (set (subreg:HI (reg:QI 178) 0)
        (ashiftrt:HI (reg:HI 641)
            (const_int 15 [0xf]))) 31 {*ashrhi3_const15} (insn_list:REG_DEP_TRUE 2480 (nil))
    (expr_list:REG_DEAD (reg:HI 641)
        (nil)))

After reload:

Reloads for insn # 2485
Reload 0: reload_out (QI) = (reg:QI 178)
	DX_REGS, RELOAD_FOR_OUTPUT (opnum = 0)
	reload_out_reg: (reg:QI 178)
	reload_reg_rtx: (reg:HI 4 d)

(insn:HI 2485 2483 2604 39 ../../../cvssrc/gcc/gcc/libgcc2.c:1825 (set (reg:HI 4 d)
        (ashiftrt:HI (reg:HI 2 a [641])
            (const_int 15 [0xf]))) 31 {*ashrhi3_const15} (insn_list:REG_DEP_TRUE 2480 (nil))
    (nil))

(insn 2604 2485 2486 39 ../../../cvssrc/gcc/gcc/libgcc2.c:1825 (set (mem/c:QI (plus:HI (reg/f:HI 10 bp)
                (const_int -42 [0xffffffd6])) [10 S1 A8])
        (reg:QI 4 d)) 34 {movqi} (nil)
    (nil))

This is close to what it looked like before combine (in the life1 dump):

(insn 2483 2480 2485 40 ../../../cvssrc/gcc/gcc/libgcc2.c:1825 (set (reg:HI 643)
        (ashiftrt:HI (reg:HI 641)
            (const_int 15 [0xf]))) 31 {*ashrhi3_const15} (insn_list:REG_DEP_TRUE 2480 (nil))
    (expr_list:REG_DEAD (reg:HI 641)
        (nil)))

(insn 2485 2483 2486 40 ../../../cvssrc/gcc/gcc/libgcc2.c:1825 (set (reg:QI 178)
        (subreg:QI (reg:HI 643) 0)) 34 {movqi} (insn_list:REG_DEP_TRUE 2483 (nil))
    (expr_list:REG_DEAD (reg:HI 643)
        (nil)))

But nice try anyway, combine. :-)

-- 
Rask Ingemann Lambertsen


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