Bug 53053 - code-gen (missing loop-termination test) bug introduced between April 18 and April 19th
Summary: code-gen (missing loop-termination test) bug introduced between April 18 and ...
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-04-20 09:18 UTC by jim
Modified: 2012-04-20 12:00 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-04-20 00:00:00


Attachments
preprocessed source (347.18 KB, application/x-xz)
2012-04-20 10:43 UTC, jim
Details

Note You need to log in before you can comment on or make changes to this bug.
Description jim 2012-04-20 09:18:13 UTC
Background, gcc-compiled emacs (bzr trunk) began to segfault
differently when compiled with yesterday's gcc-trunk.

Given this function from emacs' dispnew.c,
(LAST_AREA is an enum with value 3)

static __attribute__((noinline)) void
swap_glyph_pointers (struct glyph_row *a, struct glyph_row *b)
{
  unsigned int i;
  unsigned hash_tem = a->hash;

  for (i = 0; i < LAST_AREA + 1; ++i)
    {
      struct glyph *temp = a->glyphs[i];
      short used_tem = a->used[i];

      a->glyphs[i] = b->glyphs[i];
      b->glyphs[i] = temp;
      a->used[i] = b->used[i];
      b->used[i] = used_tem;
    }
  a->hash = b->hash;
  b->hash = hash_tem;
}

*** FAILURE: using yesterday's gcc
Compiling dispnew with -O1 or less there is no problem.
Compiling just dispnew.c with -O2 (all the rest is compiled with -ggdb3)
via make CFLAGS='-O2 -ggdb3' CC=/p/p/gcc-2012-04-19.16h18/bin/gcc
* currently-generated code, "i" increases until segfault:

0000000000000120 <swap_glyph_pointers>:
     120:	31 c0                	xor    %eax,%eax
     122:	66 0f 1f 44 00 00    	nopw   0x0(%rax,%rax,1)
     128:	48 8b 0c 87          	mov    (%rdi,%rax,4),%rcx
     12c:	4c 8b 04 86          	mov    (%rsi,%rax,4),%r8
     130:	0f b7 54 07 20       	movzwl 0x20(%rdi,%rax,1),%edx
     135:	4c 89 04 87          	mov    %r8,(%rdi,%rax,4)
     139:	48 89 0c 86          	mov    %rcx,(%rsi,%rax,4)
     13d:	0f b7 4c 06 20       	movzwl 0x20(%rsi,%rax,1),%ecx
     142:	66 89 4c 07 20       	mov    %cx,0x20(%rdi,%rax,1)
     147:	66 89 54 06 20       	mov    %dx,0x20(%rsi,%rax,1)
     14c:	48 83 c0 02          	add    $0x2,%rax
     150:	eb d6                	jmp    128 <swap_glyph_pointers+0x8>
     152:	66 66 66 66 66 2e 0f 	data32 data32 data32 data32 nopw %cs:0x0(%rax,%rax,1)
     159:	1f 84 00 00 00 00 00 

*** SUCCESS: using gcc from Wed April 18
Compiling the same file with gcc built from a snapshot a day earlier,
make CFLAGS='-O2 -ggdb3' CC=/p/p/gcc-2012-04-18.15h00/bin/gcc
* code generated by svn/trunk of gcc-2012-04-18.15h00 (UTC),
This loop terminates normally.

0000000000000120 <swap_glyph_pointers>:
     120:	44 8b 4f 4c          	mov    0x4c(%rdi),%r9d
     124:	31 c0                	xor    %eax,%eax
     126:	48 8b 0c 87          	mov    (%rdi,%rax,4),%rcx
     12a:	4c 8b 04 86          	mov    (%rsi,%rax,4),%r8
     12e:	0f b7 54 07 20       	movzwl 0x20(%rdi,%rax,1),%edx
     133:	4c 89 04 87          	mov    %r8,(%rdi,%rax,4)
     137:	48 89 0c 86          	mov    %rcx,(%rsi,%rax,4)
     13b:	0f b7 4c 06 20       	movzwl 0x20(%rsi,%rax,1),%ecx
     140:	66 89 4c 07 20       	mov    %cx,0x20(%rdi,%rax,1)
     145:	66 89 54 06 20       	mov    %dx,0x20(%rsi,%rax,1)
     14a:	48 83 c0 02          	add    $0x2,%rax
     14e:	48 83 f8 08          	cmp    $0x8,%rax
     152:	75 d2                	jne    126 <swap_glyph_pointers+0x6>
     154:	8b 46 4c             	mov    0x4c(%rsi),%eax
     157:	89 47 4c             	mov    %eax,0x4c(%rdi)
     15a:	44 89 4e 4c          	mov    %r9d,0x4c(%rsi)
     15e:	c3                   	retq
     15f:	90                   	nop
Comment 1 Richard Biener 2012-04-20 09:25:46 UTC
Seems to be similar to other existing cases.  You very likely have an
out-of-bound array access in your loop.

No testcase.
Comment 2 jim 2012-04-20 10:28:35 UTC
when I add printf ("%u\n", i); before the end of the loop, it prints values up to about 128K before segfaulting.
Comment 3 jim 2012-04-20 10:43:28 UTC
Created attachment 27201 [details]
preprocessed source

PS, gcc was built via this:
CC=/usr/bin/gcc ./configure --prefix=$prefix --disable-multilib \
  --disable-libmudflap --disable-nls --enable-languages=c && make bootstrap
Comment 4 Jakub Jelinek 2012-04-20 11:07:43 UTC
So what Richard says is true.
  short used[LAST_AREA];
...
  for (i = 0; i < LAST_AREA + 1; ++i)
...
      short used_tem = a->used[i];
This reads (and stores) used[LAST_AREA].
Comment 5 jim 2012-04-20 11:23:21 UTC
Oh!  I'm not used to seeing this sort of transformation (invalid code ->
effectively-skipped loop-termination test), but it certainly makes sense,
given an invalid input.

Thank you both.
definitely NOTABUG.
Comment 6 Richard Biener 2012-04-20 12:00:55 UTC
Thanks.