This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR optimization/8300 and target/9763 (Sparc)
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 23 Mar 2003 10:17:01 +0100
- Subject: [PATCH] Fix PR optimization/8300 and target/9763 (Sparc)
Hi,
These are regressions from gcc 2.95.3 present on all active branches.
The compiler ICEs in emit-rtl.c:gen_reg_rtx() on both testcases for exactly
the same reason: it tries to create a new pseudo-reg when it is not allowed
to do so any longer.
We have these lines in toplev.c:
no_new_pseudos = 1;
if (warn_uninitialized || extra_warnings)
{
uninitialized_vars_warning (DECL_INITIAL (decl));
if (extra_warnings)
setjmp_args_warning ();
}
if (optimize)
{
if (initialize_uninitialized_subregs ())
{
/* Insns were inserted, so things might look a bit different. */
insns = get_insns ();
life_analysis (insns, rtl_dump_file,
(PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES));
}
}
The problem is the call to initialize_uninitialized_subregs(): this function
is intended to initialize some pseudo-regs with 0. Now, on generic Sparc
CPUs, FP regs can't be zeroed directly so we end up forcing 0.0 into memory
in order to load it into the FP regs. But, given that we use indexed
addressing, we need a new pseudo to do so, hence we abort in gen_reg_rtx().
The proposed fix is to zero the FP regs with a 'fsub' in this case.
Bootstrapped/regtested on sparc-sun-solaris2.8 (c,c++,objc,f77 3.2 branch)
and sparc-sun-solaris2.9 (c,c++,objc,f77 3.3 branch).
--
Eric Botcazou
2003-03-23 Eric Botcazou <ebotcazou at libertysurf dot fr>
PR optimization/8300 and target/9763
* config/sparc/sparc.md (movsf expander): Use 'fsub'
to zero the FP regs when no new pseudos are allowed.
(movdf expander): Likewise.
2003-03-23 Eric Botcazou <ebotcazou at libertysurf dot fr>
* gcc.dg/20030323-1.c: New test.
* gcc.dg/20030323-2.c: New test.
Index: config/sparc/sparc.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.md,v
retrieving revision 1.148.2.15.4.1
diff -u -r1.148.2.15.4.1 sparc.md
--- config/sparc/sparc.md 2 Oct 2002 03:47:05 -0000 1.148.2.15.4.1
+++ config/sparc/sparc.md 20 Mar 2003 09:55:25 -0000
@@ -3177,7 +3177,7 @@
""
"
{
- /* Force SFmode constants into memory. */
+ /* Force SFmode constants into memory if necessary. */
if (GET_CODE (operands[0]) == REG
&& CONSTANT_P (operands[1]))
{
@@ -3187,6 +3187,7 @@
if (operands [1] == const0_rtx)
operands[1] = CONST0_RTX (SFmode);
+ /* The Visual Instruction Set extensions have 'fzero'. */
if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
goto movsf_is_ok;
@@ -3195,6 +3196,26 @@
if (REGNO (operands[0]) < 32)
goto movsf_is_ok;
+ /* We might be requested to clear some SF regs after the ban on
+ new pseudo regs creation. In that case, we can't force into
+ memory because we would need a new pseudo to load back from
+ memory. */
+ if (no_new_pseudos && fp_zero_operand (operands[1], SFmode))
+ {
+ /* Careful, subsf3 is a FP-only insn. */
+ if (TARGET_FPU)
+ {
+ /* Substract the register from itself. */
+ rtx insn = emit_insn (gen_subsf3 (operands[0], operands[0], operands[0]));
+ set_unique_reg_note (insn, REG_EQUAL, operands[1]);
+ DONE;
+ }
+
+ /* Nothing to be done for integer registers. */
+ else
+ goto movsf_is_ok;
+ }
+
operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
operands[1]));
}
@@ -3240,7 +3261,7 @@
""
"
{
- /* Force DFmode constants into memory. */
+ /* Force DFmode constants into memory if necessary. */
if (GET_CODE (operands[0]) == REG
&& CONSTANT_P (operands[1]))
{
@@ -3250,6 +3271,7 @@
if (operands [1] == const0_rtx)
operands[1] = CONST0_RTX (DFmode);
+ /* The Visual Instruction Set extensions have 'fzero'. */
if ((TARGET_VIS || REGNO (operands[0]) < 32)
&& fp_zero_operand (operands[1], DFmode))
goto movdf_is_ok;
@@ -3258,6 +3280,26 @@
if (REGNO (operands[0]) < 32
&& (reload_completed || reload_in_progress))
goto movdf_is_ok;
+
+ /* We might be requested to clear some DF regs after the ban on
+ new pseudo regs creation. In that case, we can't force into
+ memory because we would need a new pseudo to load back from
+ memory. */
+ if (no_new_pseudos && fp_zero_operand (operands[1], DFmode))
+ {
+ /* Careful, subdf3 is a FP-only insn. */
+ if (TARGET_FPU)
+ {
+ /* Substract the register from itself. */
+ rtx insn = emit_insn (gen_subdf3 (operands[0], operands[0], operands[0]));
+ set_unique_reg_note (insn, REG_EQUAL, operands[1]);
+ DONE;
+ }
+
+ /* Nothing to be done for integer registers. */
+ else
+ goto movdf_is_ok;
+ }
operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
operands[1]));
/* PR optimization/8300 */
/* Originator: Robert Schiele <rschiele at uni-mannheim dot de> */
/* { dg-do compile } */
/* { dg-options "-O" } */
/* This testcase violates the ISO C aliasing rules
but it used to expose a real problem on Sparc. */
void a()
{
double b;
int c[2];
*((int*)&b) && (c[1] = 0);
}
/* PR target/9763 */
/* Contributed by Christian Ehrhardt <ehrhardt at mathematik dot uni-ulm dot de> */
/* { dg-do compile } */
/* { dg-options "-O" } */
/* This testcase violates the ISO C aliasing rules
but it used to expose a real problem on Sparc. */
static int phys_get_long(int addr)
{
if (addr)
return 0;
addr = 0xff000000;
}
struct ieee {
int negative:1 ;
};
double make_single(int value)
{
float result;
struct ieee * srp = (struct ieee *) ( &result );
srp->negative = (value >> 31) & 1;
return result;
}