Bug 18420 - [4.0 Regression] ICE compiling mesa at -O2
Summary: [4.0 Regression] ICE compiling mesa at -O2
Status: CLOSED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 4.0.0
: P2 normal
Target Milestone: 4.0.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2004-11-10 16:44 UTC by Jon Grimm
Modified: 2021-02-16 17:26 UTC (History)
6 users (show)

See Also:
Host:
Target: powerpc64-linux, powerpc-darwin
Build:
Known to work:
Known to fail:
Last reconfirmed: 2004-11-10 22:57:11


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jon Grimm 2004-11-10 16:44:14 UTC
I'll add more details as they unfold, but wanted to get this posted into
bugzilla.  The autotester has been pretty flaky lately that I don't have a good
idea when this broke, but looks to have broken somewhere between Oct 29 and Nov
4.  I don't have data between those dates, but Nov 4. build did not compile
mesa.  SegFault doesn't happen at -O1.  

SegFault Building mesa. 

/opt/gcc-nightly/gcc/libexec/gcc/powerpc64-linux/4.0.0/cc1 -O2 context.c

context.c: In function gl_create_visual:
context.c:1082: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.

Watching in GDB shows. 

Analyzing compilation unit
Performing intraprocedural optimizations
Assembling functions:
 free_shared_state
 init_material
 gl_create_visual

Program received signal SIGSEGV, Segmentation fault.
note_stores (x=0x403d62f0, fun=0x10325090 <forget_old_reloads_1>, data=0x0)
    at /home/gccbuild/gcc_mline_anoncvs/gcc/gcc/rtlanal.c:1405
1405    /home/gccbuild/gcc_mline_anoncvs/gcc/gcc/rtlanal.c: No such file or
directory.
        in /home/gccbuild/gcc_mline_anoncvs/gcc/gcc/rtlanal.c
Comment 1 Jon Grimm 2004-11-10 22:50:19 UTC
Testcase reduced from the mesa context.c file.

Compiling this with -O2 segfaults on linux-powerpc64 segfaults.


typedef unsigned int size_t;
extern void *malloc (size_t __size) __attribute__ ((__malloc__));
extern void abort(void);

struct _abc {
  int ebc;
};

void xxx ( float rscale,
           float gscale,
           float bscale,
           float ascale)
{
   struct _abc *vis;

   if (rscale > 255.0) abort();
   if (gscale > 255.0) abort();
   if (bscale > 255.0) abort();
   if (ascale > 255.0) abort();

   vis = (struct _abc *) malloc(sizeof(struct _abc) );

   if (rscale==255.0F && gscale==255.0F
     && bscale==255.0F && ascale==255.0F) {
     vis->ebc = 1;
   }

}


 

Comment 2 Andrew Pinski 2004-11-10 22:57:10 UTC
Confirmed, also happens on powerpc-darwin with -O2 -fPIC.
Comment 3 Andrew Pinski 2004-11-10 23:04:51 UTC
Hmm, someone did an emit_rtx and did not end_sequence as the insn looks like:
(insn 143 0 0 (set (nil)
        (reg:CC 75 cr7)) -1 (nil)
    (nil))

Comment 4 Andrew Pinski 2004-11-10 23:45:11 UTC
I was wrong in the sense that is the right RTL except that nill is wrong and is being overwritten.
Comment 5 Andrew Pinski 2004-11-10 23:49:52 UTC
in gen_reload, we do:
    emit_insn (gen_rtx_SET (VOIDmode, out, in));

but somehow the set gets changed for the out to be nil.  Note out and in are correct here.
After this we don't get the correct insn in the sequence at all.
Comment 6 Andrew Pinski 2004-11-10 23:58:02 UTC
Never mind my comment about "emit_insn (gen_rtx_SET " because we are not calling that but
7530        emit_insn (gen_move_insn (out, in));
Comment 7 Andrew Pinski 2004-11-11 00:04:17 UTC
The bug is in emit_move_insn_1, we set the out side to null for some reason.
Comment 8 Andrew Pinski 2004-11-11 00:30:51 UTC
We used to change the mode to CC from CCFP but now we don't.
Comment 9 Andrew Pinski 2004-11-11 00:31:42 UTC
This is the rtl we used to produce:
(insn 144 69 75 8 (set (reg:CC 75 cr7)
        (reg:CC 30 r30 [125])) 336 {*movcc_internal1} (nil)
    (nil))  <-- this the insn which we are messing up now.

(jump_insn:HI 75 144 80 8 (set (pc)
        (if_then_else (ne (reg:CCFP 75 cr7)
                (const_int 0 [0x0]))
            (label_ref 115)
            (pc))) 527 {*rs6000.md:13676} (insn_list:REG_DEP_ANTI 67 (insn_list:REG_DEP_ANTI 69 
(insn_list:REG_DEP_ANTI 68 (nil))))
    (expr_list:REG_BR_PROB (
Comment 10 Andrew Pinski 2004-11-11 00:34:01 UTC
Found the patch which caused the problem:
        * simplify-rtx.c (simplify_gen_subreg): Fail if simplify_subreg
        has failed when passed a hard register.
Comment 11 Andrew Pinski 2004-11-11 00:47:57 UTC
This patch fixes it:
Index: simplify-rtx.c
===============================================================
====
RCS file: /cvs/gcc/gcc/gcc/simplify-rtx.c,v
retrieving revision 1.207
diff -u -p -r1.207 simplify-rtx.c
--- simplify-rtx.c	28 Oct 2004 12:47:21 -0000	1.207
+++ simplify-rtx.c	11 Nov 2004 00:47:26 -0000
@@ -3790,7 +3790,8 @@ simplify_gen_subreg (enum machine_mode o
     return newx;
 
   if (GET_CODE (op) == SUBREG || GET_MODE (op) == VOIDmode
-      || (REG_P (op) && REGNO (op) < FIRST_PSEUDO_REGISTER))
+      || (REG_P (op) && REGNO (op) < FIRST_PSEUDO_REGISTER
+          && GET_MODE_SIZE (innermode) != GET_MODE_SIZE (innermode)))
     return NULL_RTX;
 
   return gen_rtx_SUBREG (outermode, op, byte);
Comment 12 Andrew Pinski 2004-11-11 01:04:07 UTC
Even though this patch fixes it, it is not the right fix as simplify_subreg should just return a change in 
the mode rather than return null.
Comment 13 Andrew Pinski 2004-11-11 01:49:51 UTC
The problem is that the register is r30 (which is the FRAME_POINTER_REGNUM) and reload is not 
complete at this point, maybe this is not the correct check.

((reload_completed && !frame_pointer_needed)
	  || (REGNO (op) != FRAME_POINTER_REGNUM
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
	      && REGNO (op) != HARD_FRAME_POINTER_REGNUM
#endif
	     ))
Comment 14 Andrew Pinski 2004-11-11 02:04:29 UTC
Jan you added that code to simplify_subreg but I could not figure out why it was really added except 
that it effected x86_64 (when bootstrapped with -fomit-frame-pointer).  Note in this case the mode the 
modes are the same size which is unlike the case you found.

Reference: 
http://gcc.gnu.org/ml/gcc-patches/2001-05/msg01737.html
http://gcc.gnu.org/ml/gcc-patches/2001-05/msg01729.html
Comment 15 Andrew Pinski 2004-11-11 02:10:23 UTC
The reason why we are not using r31 at least on darwin is because that is the PIC register.
Comment 16 Jim Wilson 2004-11-11 05:19:17 UTC
This looks like the same problem as 18294 which is an ia64-hpux bootstrap
failure.  In that PR, I suggested that simplify_gen_subreg should just create
the subreg for a hard register when simplify_subreg does not, but I haven't
looked at this very closely.  This problem occurs early, during virtual register
instantiation.

The patch in comment #11 is flawed.  It has
+          && GET_MODE_SIZE (innermode) != GET_MODE_SIZE (innermode)))
which will always be false.  Probably one of these was meant to be outermode.

If we are trying to prevent reload from creating subregs, then maybe the
reload_completed check could instead be !reload_in_progress.  This is just a
random guess though.  I haven't tried looking at Ulrich Weigand's patch yet.
Comment 17 Ulrich Weigand 2004-11-25 18:33:02 UTC
Now that RTH's validate_subreg patch is in, I guess the right fix for
this problem might be to always return a SUBREG in simplify_gen_subreg
unless that SUBREG is actually invalid.

What do you think of this patch:

Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/simplify-rtx.c,v
retrieving revision 1.211
diff -c -p -r1.211 simplify-rtx.c
*** simplify-rtx.c      24 Nov 2004 00:09:03 -0000      1.211
--- simplify-rtx.c      25 Nov 2004 18:29:38 -0000
*************** simplify_gen_subreg (enum machine_mode o
*** 3782,3792 ****
    if (newx)
      return newx;

!   if (GET_CODE (op) == SUBREG || GET_MODE (op) == VOIDmode
!       || (REG_P (op) && REGNO (op) < FIRST_PSEUDO_REGISTER))
!     return NULL_RTX;
!
!   if (validate_subreg (outermode, innermode, op, byte))
      return gen_rtx_SUBREG (outermode, op, byte);

    return NULL_RTX;
--- 3782,3788 ----
    if (newx)
      return newx;

!   if (REG_P (op) && validate_subreg (outermode, innermode, op, byte))
      return gen_rtx_SUBREG (outermode, op, byte);

    return NULL_RTX;


(B.t.w. shouldn't validate_subreg reject non-REG inputs itself?)
Comment 18 GCC Commits 2004-11-28 13:03:08 UTC
Subject: Bug 18420

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	uweigand@gcc.gnu.org	2004-11-28 13:02:53

Modified files:
	gcc            : ChangeLog simplify-rtx.c 

Log message:
	PR rtl-optimization/18420
	* simplify-rtx.c (simplify_gen_subreg): Revert 2004-10-28 change.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.6599&r2=2.6600
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/simplify-rtx.c.diff?cvsroot=gcc&r1=1.211&r2=1.212

Comment 19 Andrew Pinski 2004-11-28 15:40:12 UTC
Fixed.
Comment 20 Jon Grimm 2004-11-30 14:49:05 UTC
Verified this fixed mesa too. 
Comment 21 seurer 2021-02-16 17:26:58 UTC
This was fixed long ago.  Closing.