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]

RFA: fix SH build failure on mainline



sh-elf and sh64-elf builds from mainline (last tested: 20050802 19:00 UTC)
are currently failing during newlib build with an internal compiler error
in simplify_subreg.
The sh-elf failure is while compiling newlib/libm/math/kf_rem_pio2.c for the
-ml multilib.  We got an insn with a REG_EQUAL note that has a mode mismatch
with the actual value being assigned.  During combine, this note is used
to generate a new pattern, and eventually we end up with a call of
simplify_subreg with innermode SImode, but op in SFmode.
The instruction that triggers this is:

(insn 1552 1551 0 (set (reg:SI 774)
        (xor:SI (subreg:SI (reg/v:SF 209 [ fw.202 ]) 0)
            (reg:SI 773))) -1 (nil)
    (expr_list:REG_EQUAL (neg:SF (reg/v:SF 209 [ fw.202 ]))
        (nil)))

Before Jan Hubicka's expr.c expand_expr_real_1 patch on the 29th July,
the instruction looked slightly different:

(insn 1552 1551 0 (set (subreg:SI (reg:SF 773) 0)
        (xor:SI (subreg:SI (reg/v:SF 209 [ fw.202 ]) 0)
            (reg:SI 774))) -1 (nil)
    (expr_list:REG_EQUAL (neg:SF (reg/v:SF 209 [ fw.202 ]))
        (nil)))

and combine somehow muddled through with this.  Still, the basic problem is
that we have a mode mismatch between note and actual assignment.
This problem was introduced when rth splitted expand_absneg_bit out from
expand_unop on the 31st January; before, we always generated a final move
insn to the original target, which we tagged the note on.  Now, we
are also content with returning a subreg of an intermediate register,
and the last insn that the note is tagged onto might be in a different
mode than the equivalence.

I think there are two main approaches to solve the ICE problem: either
restore the copy, or adjust the REG_EQUAL note to the mode that the
last assignment used.
I think we should do the latter.

I'm boostrapping / regtesting this patch on i686-pc-linux-gnu native and
X sh-elf / sh64-elf.

2005-08-03  J"orn Rennecke <joern.rennecke@st.com>

	* optabs.c (expand_absneg_bit): When doing a single-word operation,
	adjust the mode of the datum for the REG_EQUAL note.

Index: optabs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/optabs.c,v
retrieving revision 1.288
diff -p -r1.288 optabs.c
*** optabs.c	29 Jul 2005 22:22:39 -0000	1.288
--- optabs.c	3 Aug 2005 17:12:03 -0000
*************** expand_absneg_bit (enum rtx_code code, e
*** 2298,2311 ****
      }
    else
      {
        temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
  			   gen_lowpart (imode, op0),
  			   immed_double_const (lo, hi, imode),
  		           gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
        target = lowpart_subreg_maybe_copy (mode, temp, imode);
! 
!       set_unique_reg_note (get_last_insn (), REG_EQUAL,
! 			   gen_rtx_fmt_e (code, mode, copy_rtx (op0)));
      }
  
    return target;
--- 2298,2318 ----
      }
    else
      {
+       rtx set, equiv;
+ 
        temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
  			   gen_lowpart (imode, op0),
  			   immed_double_const (lo, hi, imode),
  		           gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
        target = lowpart_subreg_maybe_copy (mode, temp, imode);
!       set = single_set (get_last_insn ());
!       if (set)
! 	{
! 	  equiv = gen_rtx_fmt_e (code, mode, copy_rtx (op0));
! 	  equiv = lowpart_subreg (GET_MODE (SET_DEST (set)), equiv, mode);
! 	  if (equiv)
! 	    set_unique_reg_note (get_last_insn (), REG_EQUAL, equiv);
! 	}
      }
  
    return target;

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