Bug 59743 - [4.9 Regression] ICE: Segmentation fault
Summary: [4.9 Regression] ICE: Segmentation fault
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: 4.9.0
Assignee: Jeffrey A. Law
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-01-09 20:23 UTC by Markus Trippelsdorf
Modified: 2014-01-10 22:14 UTC (History)
3 users (show)

See Also:
Host:
Target: i?86-*-*
Build:
Known to work:
Known to fail:
Last reconfirmed: 2014-01-10 00:00:00


Attachments
original testcase (1.47 KB, text/plain)
2014-01-09 22:00 UTC, Markus Trippelsdorf
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Trippelsdorf 2014-01-09 20:23:39 UTC
reduced test case:

typedef union {
  long all;
  struct {
    int low;
    int high;
  } s;
} udwords;
int a, b, c, d;
void __udivmoddi4() {
  udwords r;
  d = __builtin_clz(0);
  r.s.low = 0;
  for (; d; --d) {
    r.s.high = r.s.high << 1 | r.s.low >> a;
    r.s.low = r.s.low << b >> 1;
    int s = -r.all;
    c = s;
    r.all--;
  }
}

 % g++ -O2 -c test.ii
test.ii: In function ‘void __udivmoddi4()’:
test.ii:20:1: internal compiler error: Segmentation fault
 }
 ^
0xb4f8df crash_signal
        ../../gcc/gcc/toplev.c:337
0xb056c9 reg_used_between_p(rtx_def const*, rtx_def const*, rtx_def const*)
        ../../gcc/gcc/rtlanal.c:753
0x103e6eb combine_reaching_defs
        ../../gcc/gcc/ree.c:734
0x103e6eb find_and_remove_re
        ../../gcc/gcc/ree.c:973
0x103e6eb rest_of_handle_ree
        ../../gcc/gcc/ree.c:1035
0x103e6eb execute
        ../../gcc/gcc/ree.c:1074
Please submit a full bug report,
Comment 1 Markus Trippelsdorf 2014-01-09 21:04:53 UTC
Started with r206418.
Comment 2 Jakub Jelinek 2014-01-09 21:15:53 UTC
The ICE is because cand->insn is earlier in the bb than def_insn.  But too tired to look why.
Comment 3 Jeffrey A. Law 2014-01-09 21:20:44 UTC
No worries Jakub.  I'll take it as it's clearly mine.
Comment 4 Jeffrey A. Law 2014-01-09 21:50:25 UTC
I see what's going on.

Basically the code exhibits undefined behaviour (r.s.high is not defined before its first use in the loop).  Thus the first and only reaching def is appearing after the first use.

Obviously we shouldn't be faulting here.

Markus -- You might want to go back to your original test and ensure it's not exhibiting undefined behaviour.  The original code may be exhibiting undefined behaviour.
Comment 5 Jeffrey A. Law 2014-01-09 21:57:08 UTC
I think we can just check DF_INSN_LUIDs here to catch this case.  My systems are busy right now, but I should be able to nail this down as soon as one frees up.
Comment 6 Markus Trippelsdorf 2014-01-09 22:00:31 UTC
Created attachment 31791 [details]
original testcase

Here's the unreduced original.
Comment 7 Jakub Jelinek 2014-01-09 23:45:04 UTC
(In reply to Jeffrey A. Law from comment #5)
> I think we can just check DF_INSN_LUIDs here to catch this case.  My systems
> are busy right now, but I should be able to nail this down as soon as one
> frees up.

But is DF_INSN_LUID always computed?  I mean, for -O2 it probably is, but what about -O -free ?  For -O I think the live problem isn't on and thus I think DF_INSN_LUID isn't computed.  The DF documentation is unfortunately non-existent :(.
Comment 8 Jeffrey A. Law 2014-01-10 05:20:59 UTC
  /* The logical uid of the insn in the basic block.  This is valid
     after any call to df_analyze but may rot after insns are added,
     deleted or moved. */
  int luid;
Comment 9 Jeffrey A. Law 2014-01-10 05:34:49 UTC
And note that ree does not make the LUID data stale until after analyzing *all* the potential transformations.  So the limitations of LUIDs shouldn't be a problem.

Anyway, patch is in testing.
Comment 10 Jakub Jelinek 2014-01-10 11:57:53 UTC
Ah, there is:
  /* If the df_live problem is not defined, such as at -O0 and -O1, we
     still need to keep the luids up to date.  This is normally done
     in the df_live problem since this problem has a forwards
     scan.  */
  if (!df_live)
    df_recompute_luids (bb);
in df_lr_bb_local_compute, so I think luids are fine even at -O0/-O1.
Comment 11 Jeffrey A. Law 2014-01-10 21:48:52 UTC
Thanks.  I'm still working through the RTL/source on the full testcase to see if there are any uninitialized uses.  Regardless the patch I have here works for both the reduced and original testcase.  I'll be posting it for review momentarily.
Comment 12 Jeffrey A. Law 2014-01-10 22:13:51 UTC
Author: law
Date: Fri Jan 10 22:13:18 2014
New Revision: 206545

URL: http://gcc.gnu.org/viewcvs?rev=206545&root=gcc&view=rev
Log:
	PR middle-end/59743
	* ree.c (combine_reaching_defs): Ensure the defining statement
	occurs before the extension when optimizing extensions with
	different source and destination hard registers.

	PR middle-end/59743
	* gcc.c-torture/compile/pr59743.c: New test.

Added:
    trunk/gcc/testsuite/gcc.c-torture/compile/pr59743.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/ree.c
    trunk/gcc/testsuite/ChangeLog
Comment 13 Jeffrey A. Law 2014-01-10 22:14:08 UTC
Should be fixed on the trunk now.