Bug 26300 - [4.1 Regression] ICE in trunc_int_for_mode
Summary: [4.1 Regression] ICE in trunc_int_for_mode
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.1.0
: P3 normal
Target Milestone: 4.1.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2006-02-15 11:03 UTC by Jakub Jelinek
Modified: 2006-02-17 12:31 UTC (History)
3 users (show)

See Also:
Host:
Target: x86_64-linux
Build:
Known to work:
Known to fail:
Last reconfirmed: 2006-02-15 14:47:21


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jakub Jelinek 2006-02-15 11:03:39 UTC
extern void fn1 (long int) __attribute__ ((noreturn));
void fn2 (long int);
extern long int u, v;
struct S
{
  char c;
  long int d;
  long int e;
};

static inline struct S *
fn3 (long int x)
{
  if (*(char *) x != 6)
    fn1 (0);
  return (struct S *) x;
}

static inline int
fn4 (long int x)
{
  if (x == u)
    return 3;
  fn2 (x);
  return 0;
}

int
test (long int x)
{
  long int r;
  int m = 0;

  for (r = x; r != v; r = (fn3 (r)->d))
    if (*(char *) r != 6)
      fn1 (x);
    else
      m |= 1 << (fn4 (fn3 (r)->e) - 1);
  return m;
}

ICEs at -O and above on x86_64.
Comment 1 Jakub Jelinek 2006-02-15 11:25:49 UTC
What happens is that first dom1 splits the 1 << (f4 (...) - 1) shift into
1 << (3 - 1) and 1 << (0 - 1) branches depending on if fn3 (r)->e == u or not.
The latter triggers undefined behavior, but if the 1 << (3 - 1) branch is
always taken, then it will never be triggered at runtime.
D.1642 = 1 << -1;
is then expanded into RTL (not folded, since folders refuse to fold shifts by
negative value), at life1 we still have:
(insn 69 67 70 10 (set (reg:SI 66)
        (const_int 1 [0x1])) 40 {*movsi_1} (nil)
    (nil))

(insn 70 69 71 10 (parallel [
            (set (reg:SI 61 [ D.1642 ])
                (ashift:SI (reg:SI 66)
                    (const_int -1 [0xffffffffffffffff])))
            (clobber (reg:CC 17 flags))
        ]) 413 {*ashlsi3_1} (insn_list:REG_DEP_TRUE 69 (nil))
    (expr_list:REG_DEAD (reg:SI 66)
        (expr_list:REG_UNUSED (reg:CC 17 flags)
            (nil))))
but then combine changes that into:
(insn 71 70 72 10 (parallel [
            (set (zero_extract:DI (const_int 0 [0x0])
                    (const_int 1 [0x1])
                    (const_int -1 [0xffffffffffffffff]))
                (const_int 1 [0x1]))
        ]) 318 {*iorsi_1} (insn_list:REG_DEP_TRUE 70 (nil))
    (expr_list:REG_DEAD (reg:SI 61 [ D.1642 ])
        (expr_list:REG_UNUSED (reg:CC 17 flags)
            (nil))))
which is not valid RTL (zero_extract requires first arg to be REG or MEM).
I think this is not the first time we have issues with shifts by negative value,
perhaps tree->rtl expansion could mask the shift count or something, otherwise
we'll keep finding such bugs all the time.
Comment 2 Andrew Pinski 2006-02-15 14:47:21 UTC
Confirmed, this is undefined behavior anyways so I don't think we should block 4.1 for this code.
Comment 3 Andrew Pinski 2006-02-15 14:47:47 UTC
Anyways patch posted:
http://gcc.gnu.org/ml/gcc-patches/2006-02/msg01222.html
Comment 4 Jakub Jelinek 2006-02-15 14:55:56 UTC
Well, undefined behavior only if you reach it.
The original code looked like:
 if (((type) == (Qnothing)))
  return IMAGE_NOTHING;
 if (((type) == (Qtext)))
  return IMAGE_TEXT;
 if (((type) == (Qmono_pixmap)))
  return IMAGE_MONO_PIXMAP;
 if (((type) == (Qcolor_pixmap)))
  return IMAGE_COLOR_PIXMAP;
 if (((type) == (Qpointer)))
  return IMAGE_POINTER;
 if (((type) == (Qsubwindow)))
  return IMAGE_SUBWINDOW;
 if (((type) == (Qwidget)))
  return IMAGE_WIDGET;

 maybe_signal_simple_error("Invalid image-instance type", type,
      Qimage, errb);

 return IMAGE_UNKNOWN;

where IMAGE_UNKNOWN is 0, guess the authors just assume this will never happen.
Comment 5 Jakub Jelinek 2006-02-15 20:41:08 UTC
Subject: Bug 26300

Author: jakub
Date: Wed Feb 15 20:41:03 2006
New Revision: 111116

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=111116
Log:
	PR middle-end/26300
	* combine.c (make_extraction): Bail out if ORIG_POS is negative.

	* gcc.c-torture/compile/20060215-1.c: New test.

Added:
    trunk/gcc/testsuite/gcc.c-torture/compile/20060215-1.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/combine.c
    trunk/gcc/testsuite/ChangeLog

Comment 6 Jakub Jelinek 2006-02-17 08:58:49 UTC
Subject: Bug 26300

Author: jakub
Date: Fri Feb 17 08:58:46 2006
New Revision: 111176

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=111176
Log:
	PR middle-end/26300
	* combine.c (make_extraction): Bail out if ORIG_POS is negative.

	* gcc.c-torture/compile/20060215-1.c: New test.

Added:
    branches/gcc-4_1-branch/gcc/testsuite/gcc.c-torture/compile/20060215-1.c
Modified:
    branches/gcc-4_1-branch/gcc/ChangeLog
    branches/gcc-4_1-branch/gcc/combine.c
    branches/gcc-4_1-branch/gcc/testsuite/ChangeLog

Comment 7 Andrew Pinski 2006-02-17 12:31:07 UTC
Fixed.