Bug 32230 - [4.3 Regression] Segfault in set_bb_for_stmt with -O -ftree-vectorize
Summary: [4.3 Regression] Segfault in set_bb_for_stmt with -O -ftree-vectorize
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.3.0
: P1 normal
Target Milestone: 4.3.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2007-06-06 07:52 UTC by Martin Michlmayr
Modified: 2007-07-02 19:41 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.2.0
Known to fail: 4.3.0
Last reconfirmed: 2007-06-06 20:52:21


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Michlmayr 2007-06-06 07:52:11 UTC
I'm getting the following segfault on trunk with -O -ftree-vectorize.
This was introduced between 20070422 and 20070515.

(sid)25522:tbm@em64t: ~] /usr/lib/gcc-snapshot/bin/gcc -O -ftree-vectorize -c glame-waveform.c
glame-waveform.c: In function 'const_f':
glame-waveform.c:18: warning: comparison of distinct pointer types lacks a cast
glame-waveform.c:12: internal compiler error: Segmentation fault
Please submit a full bug report, [...]
(sid)25523:tbm@em64t: ~] /usr/lib/gcc-snapshot/bin/gcc -ftree-vectorize -c glame-waveform.c
glame-waveform.c: In function 'const_f':
glame-waveform.c:18: warning: comparison of distinct pointer types lacks a cast
(sid)25524:tbm@em64t: ~]

Testcase:


typedef struct filter_buffer filter_buffer_t;
struct filter_buffer
{
  char buf[1];
};
typedef struct sbuf_header sbuf_header_t;
struct sbuf_header
{
  char buf[1];
}
const_f (filter_buffer_t *buf)
{
  float val;
  int i;

  for (i = 0; i < 10; i++)
    ((float
      *) (&((sbuf_header_t *) ((buf) == &(buf)->buf[0]))->buf[0]))[i] = val;
}
Comment 1 Martin Michlmayr 2007-06-06 07:53:00 UTC
Program received signal SIGSEGV, Segmentation fault.
set_bb_for_stmt (t=0x0, bb=0x2b91a13c9960) at gcc/gcc/tree-cfg.c:2629
2629      if (TREE_CODE (t) == PHI_NODE)
(gdb) where
#0  set_bb_for_stmt (t=0x0, bb=0x2b91a13c9960) at gcc/gcc/tree-cfg.c:2629
#1  0x0000000000691a7d in bsi_insert_after (i=0x7fff0a04c690, t=0x0, m=BSI_NEW_STMT)
    at gcc/gcc/tree-cfg.c:2740
#2  0x0000000000692a97 in bsi_insert_on_edge_immediate (e=<value optimized out>, stmt=0x0)
    at gcc/gcc/tree-cfg.c:3007
#3  0x0000000000a1e309 in vect_do_peeling_for_alignment (loop_vinfo=0xf3f980)
    at gcc/gcc/tree-vect-transform.c:4946
#4  0x0000000000a2c8b9 in vect_transform_loop (loop_vinfo=0xf3f980)
    at gcc/gcc/tree-vect-transform.c:5284
#5  0x00000000007a7bd1 in vectorize_loops () at gcc/gcc/tree-vectorizer.c:2280
#6  0x000000000060c9a1 in execute_one_pass (pass=0xe370c0) at gcc/gcc/passes.c:1068
#7  0x000000000060cb5c in execute_pass_list (pass=0xe370c0)
    at gcc/gcc/passes.c:1120
#8  0x000000000060cb6e in execute_pass_list (pass=0xe36ee0)
    at gcc/gcc/passes.c:1121
#9  0x000000000060cb6e in execute_pass_list (pass=0xe36340)
    at gcc/gcc/passes.c:1121
#10 0x00000000006da8ef in tree_rest_of_compilation (fndecl=0x2b91a13d8000)
    at gcc/gcc/tree-optimize.c:406
#11 0x000000000082cf70 in cgraph_expand_function (node=0x2b91a13d8100)
    at gcc/gcc/cgraphunit.c:1073
#12 0x000000000082eae5 in cgraph_optimize () at gcc/gcc/cgraphunit.c:1142
#13 0x0000000000413cbe in c_write_global_declarations () at gcc/gcc/c-decl.c:7917
#14 0x00000000006855c8 in toplev_main (argc=<value optimized out>, argv=<value optimized out>) at gcc/gcc/toplev.c:1064
#15 0x00002b91a0dd28e4 in __libc_start_main () from /lib/libc.so.6
#16 0x0000000000403f99 in _start ()
Comment 2 Andrew Pinski 2007-06-06 20:52:21 UTC
Confirmed, there are two ways of fixing this bug, either check before calling bsi_insert_on_edge_immediate that we have a NULL statement or inside bsi_insert_on_edge_immediate, we could return NULL always if we don't have anything to insert on the edge.
Comment 3 Andrew Pinski 2007-06-06 20:53:11 UTC
In most of the cases we already check before calling bsi_insert_on_edge_immediate.
Comment 4 revital eres 2007-06-26 12:19:23 UTC
There are places which checks that bsi_insert_on_edge_immediate returns
NULL so checking for NULL before calling it would change the semantic.

Here is the fix for this SIGSEGV:

Index: tree-cfg.c
===================================================================
--- tree-cfg.c  (revision 125997)
+++ tree-cfg.c  (working copy)
@@ -3003,6 +3003,9 @@

   gcc_assert (!PENDING_STMT (e));

+  if (stmt == NULL_TREE)
+    return NULL;
+
   if (tree_find_edge_insert_loc (e, &bsi, &new_bb))
     bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
   else

Revital
Comment 5 Ira Rosen 2007-06-28 09:02:30 UTC
I think it is better to check that the statement is not NULL before calling bsi_insert_on_edge_immediate. I am going to prepare a patch for this.

Ira
Comment 6 Ira Rosen 2007-06-28 11:41:48 UTC
((float*) (&((sbuf_header_t *) ((buf) == &(buf)->buf[0]))->buf[0]))[i] = val;

is (after ommiting the casts)

*(1B + (i * 4)) = val;

Is that legal?

Vectorizer assumes that every data-ref has base_address. In the above case we get the following data-ref structure:
        base_address: 0B
        offset from base address: 0
        constant offset from base address: 1
        step: 4
        aligned to: 128
        base_object: *0B
        symbol tag: SMT.5

therefore, creating an empty stmt for the first access of the data-ref in the loop.

Before Zdenek's rewrite of data-refs analysis, it failed to create a dr here, and thus no segfault occurred.

Ira


Comment 7 rguenther@suse.de 2007-06-28 12:20:12 UTC
Subject: Re:  [4.3 Regression] Segfault in
 set_bb_for_stmt with -O -ftree-vectorize

On Thu, 28 Jun 2007, irar at il dot ibm dot com wrote:

> 
> 
> ------- Comment #6 from irar at il dot ibm dot com  2007-06-28 11:41 -------
> ((float*) (&((sbuf_header_t *) ((buf) == &(buf)->buf[0]))->buf[0]))[i] = val;
> 
> is (after ommiting the casts)
> 
> *(1B + (i * 4)) = val;
> 
> Is that legal?

"Legal" as far as that you are not allowed to reject it at compile-time.
Of course runtime behavior looks completely undefined ;)

> Vectorizer assumes that every data-ref has base_address. In the above case we
> get the following data-ref structure:
>         base_address: 0B
>         offset from base address: 0
>         constant offset from base address: 1
>         step: 4
>         aligned to: 128
>         base_object: *0B
>         symbol tag: SMT.5
> 
> therefore, creating an empty stmt for the first access of the data-ref in the
> loop.
> 
> Before Zdenek's rewrite of data-refs analysis, it failed to create a dr here,
> and thus no segfault occurred.

I suppose rejecting NULL bases should work here?

Richard.
Comment 8 Ira Rosen 2007-06-28 12:29:24 UTC
(In reply to comment #7)
> I suppose rejecting NULL bases should work here?

Yes, only it's not NULL it's zero (0B). 
We can reject it in the vectorizer or not create a dr for it...

Ira
Comment 9 rguenther@suse.de 2007-06-28 12:30:46 UTC
Subject: Re:  [4.3 Regression] Segfault in
 set_bb_for_stmt with -O -ftree-vectorize

On Thu, 28 Jun 2007, irar at il dot ibm dot com wrote:

> 
> 
> ------- Comment #8 from irar at il dot ibm dot com  2007-06-28 12:29 -------
> (In reply to comment #7)
> > I suppose rejecting NULL bases should work here?
> 
> Yes, only it's not NULL it's zero (0B). 
> We can reject it in the vectorizer or not create a dr for it...

I suppose all INTEGER_CST bases should be rejected.

Richard.
Comment 10 Ira Rosen 2007-06-28 12:38:34 UTC
(In reply to comment #9)
>> I suppose all INTEGER_CST bases should be rejected.
> Richard.

Right. The value actually doesn't matter since the constant part is split to the init part in (tree-data-ref.c:656):
split_constant_offset (base_iv.base, &base_iv.base, &dinit);

I only don't know where it is better to fail - in dr analysis on in the vectorizer.

Thanks,
Ira

Comment 11 patchapp@dberlin.org 2007-07-01 11:15:13 UTC
Subject: Bug number PR 32230

A patch for this bug has been added to the patch tracker.
The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2007-07/msg00018.html
Comment 12 irar 2007-07-02 10:27:37 UTC
Subject: Bug 32230

Author: irar
Date: Mon Jul  2 10:27:27 2007
New Revision: 126196

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=126196
Log:
	PR tree-optimization/32230
	PR tree-optimization/32477
	* tree-vect-analyze.c (vect_analyze_data_refs): Fail if base
	address is a constant.


Added:
    trunk/gcc/testsuite/gcc.dg/vect/pr32230.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-vect-analyze.c

Comment 13 Andrew Pinski 2007-07-02 19:41:27 UTC
Fixed.