Bug 38281

Summary: [4.4 Regression] segmentation fault with optimization enabled
Product: gcc Reporter: John Regehr <regehr>
Component: rtl-optimizationAssignee: Andrew Pinski <pinskia>
Status: RESOLVED FIXED    
Severity: normal CC: fang, gcc-bugs, pinskia
Priority: P2 Keywords: ice-on-valid-code, patch
Version: 4.4.0   
Target Milestone: 4.4.0   
URL: http://gcc.gnu.org/ml/gcc-patches/2008-11/msg01472.html
Host: i686-pc-linux-gnu Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu Known to work:
Known to fail: Last reconfirmed: 2008-11-27 01:00:40

Description John Regehr 2008-11-27 00:25:16 UTC
Seen using r142231 on Ubuntu Hardy on x86.

regehr@john-home:~/volatile/tmp69$ current-gcc -O small.c
small.c: In function ‘func_41’:
small.c:22: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
regehr@john-home:~/volatile/tmp69$ current-gcc -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../configure --program-prefix=current- --enable-languages=c,c++ --prefix=/home/regehr : (reconfigured) ../configure --program-prefix=current- --enable-languages=c,c++ --prefix=/home/regehr : (reconfigured) ../configure --program-prefix=current- --enable-languages=c,c++ --prefix=/home/regehr
Thread model: posix
gcc version 4.4.0 20081126 (experimental) (GCC) 
regehr@john-home:~/volatile/tmp69$ cat small.c
typedef unsigned short int uint16_t;

inline uint16_t safe_div_uint16_t_u_u (uint16_t ui1, uint16_t ui2)
{
  if (ui2 == 0)
    return ui1;
  return ui1 / ui2;
}

uint16_t g_223;
uint16_t g_243;
int g_252;

int func_41 (uint16_t p_42)
{
  int l_258 = 0;
  int l_261 = 0x3D75D162L;
  g_223 = safe_div_uint16_t_u_u (g_243 > l_261, func_110 (l_258, 1));
  for (g_252 = 0; g_252; g_252 = 1)
    {
    }
}
Comment 1 Andrew Pinski 2008-11-27 00:37:55 UTC
#0  0x00487a55 in reg_referenced_p (x=0x42f137d0, body=0x0) at /Users/apinski/src/local/gcc/gcc/rtlanal.c:737
#1  0x00af72a5 in distribute_notes (notes=0x42f134b0, from_insn=0x42f12a50, i3=0x42f12a80, i2=0x42f12a50, elim_i2=0x42f13c80, elim_i1=0x0) at /Users/apinski/src/local/gcc/gcc/combine.c:12578
#2  0x00add8c0 in try_combine (i3=0x42f12a80, i2=0x42f12a50, i1=0x42f12a20, new_direct_jump_p=0xbffff6cc) at /Users/apinski/src/local/gcc/gcc/combine.c:3590
#3  0x00ad70ba in combine_instructions (f=0x42f0ef00, nregs=69) at /Users/apinski/src/local/gcc/gcc/combine.c:1156
#4  0x00af8020 in rest_of_handle_combine () at /Users/apinski/src/local/gcc/gcc/combine.c:12989

Comment 2 Andrew Pinski 2008-11-27 00:38:36 UTC
12578                 else if (i2 != 0 && next_nonnote_insn (i2) == i3
12579                          && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))

(gdb) p debug_rtx(i2)
(note 20 19 21 3 NOTE_INSN_DELETED)

Comment 3 Andrew Pinski 2008-11-27 01:00:40 UTC
This patch fixes the ICE:
Index: combine.c
===================================================================
--- combine.c   (revision 142231)
+++ combine.c   (working copy)
@@ -12575,7 +12575,7 @@ distribute_notes (rtx notes, rtx from_in
                place = from_insn;
              else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3)))
                place = i3;
-             else if (i2 != 0 && next_nonnote_insn (i2) == i3
+             else if (i2 != 0 && INSN_P (i2) && next_nonnote_insn (i2) == i3
                       && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
                place = i2;
              else if ((rtx_equal_p (XEXP (note, 0), elim_i2)

--- CUT ---
At -O1, g_243 > l_261 is not optimized to 0 at the tree level but the RTL level which allows combine the ability to optimize the divide.
Comment 4 Jakub Jelinek 2008-11-27 10:01:40 UTC
Yeah, that looks reasonable (though I wonder if other places that use PATTERN in
distribute_notes don't need similar treatment).
Simplified testcase below.  Are you going to post it to gcc-patches?
inline unsigned short
foo (unsigned short x, unsigned short y)
{
  if (y == 0)
    return x;
  return x / y;
}

unsigned short a, b, c;

extern int baz (int, int);

void
bar (void)
{
  int d = 0x3D75D162;
  a = foo (b > d, baz (0, 1));
  for (c = 0; c; c = 1)
    ;
}
Comment 5 Andrew Pinski 2008-11-29 02:45:06 UTC
Mine, I was able to finally test this patch.
Comment 6 Eric Botcazou 2008-12-03 08:42:19 UTC
Subject: Bug 38281

Author: ebotcazou
Date: Wed Dec  3 08:40:50 2008
New Revision: 142388

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=142388
Log:
	PR rtl-optimization/38281
	* combine.c (distribute_notes): When invoking SET_INSN_DELETED on i2,
	set it to NULL_RTX afterwards.

	* emit-rtl.c (set_insn_deleted): Fix formatting.

Added:
    trunk/gcc/testsuite/gcc.c-torture/compile/20081203-1.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/combine.c
    trunk/gcc/emit-rtl.c
    trunk/gcc/testsuite/ChangeLog

Comment 7 Eric Botcazou 2008-12-03 08:47:17 UTC
Thanks for reporting the problem.