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; }
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 ()
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.
In most of the cases we already check before calling bsi_insert_on_edge_immediate.
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
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
((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
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.
(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
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.
(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
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
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
Fixed.