Bug 23350 - [4.1 Regression] ICE in vect_update_ivs_after_vectorizer, at tree-vect-transform.c:2418
Summary: [4.1 Regression] ICE in vect_update_ivs_after_vectorizer, at tree-vect-transf...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.1.0
: P2 normal
Target Milestone: 4.1.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2005-08-12 10:52 UTC by Michael Cieslinski
Modified: 2005-09-08 19:38 UTC (History)
4 users (show)

See Also:
Host:
Target: i?86-*-*, x86_64-*-*
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-08-12 22:10:48


Attachments
preprocessed source (79.49 KB, text/plain)
2005-08-12 10:53 UTC, Michael Cieslinski
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Cieslinski 2005-08-12 10:52:08 UTC
When I compile ace542 with the actual snapshot (20050806) of gcc41 I get an ICE
when I use -O3 and autovectorisation.

last working snapshot is:   gcc-4.1-20050604
first failing snapshot is:  gcc-4.1-20050611

Michael Cieslinski


g++41j -O3 -ftree-vectorize -c -o .obj/Reactive_Logging_Server_Ex.o 
Reactive_Logging_Server_Ex.ii
Reactive_Logging_Server_Ex.h: In member function 'virtual int 
Reactive_Logging_Server_Ex::handle_connections()':
Reactive_Logging_Server_Ex.h:54: internal compiler error: in 
vect_update_ivs_after_vectorizer, at tree-vect-transform.c:2418
Please submit a full bug report, with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.


g++41j -v
Using built-in specs.
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-4.1-20050806/configure --prefix=/usr/local/gcc41j
 --program-suffix=41j --with-arch=opteron --enable-languages=c,c++
 --enable-checking
Thread model: posix
gcc version 4.1.0 20050806 (experimental)
Comment 1 Michael Cieslinski 2005-08-12 10:53:34 UTC
Created attachment 9478 [details]
preprocessed source
Comment 2 Andrew Pinski 2005-08-12 17:46:34 UTC
Reducing.
Comment 3 Andrew Pinski 2005-08-12 22:10:47 UTC
Confirmed, reduced testcase (about 50 lines):
 typedef struct   {
   long fds_bits[1024 / (8 * 4)];
 } fd_set;
 struct ACE_Hash {
  unsigned long operator () (int t) const;
 };
 struct ACE_Handle_Set {void set_bit ();fd_set mask_;};
 inline void ACE_Handle_Set::set_bit (){
 do {
        unsigned int __i;
        fd_set *__arr = (&this->mask_);
        for (__i = 0;
        __i < sizeof (fd_set) / 4;
        ++__i) ((__arr)->fds_bits)[__i] = 0;
        }
 while (0);
 }
 struct ACE_Hash_Map_Entry {
   ACE_Hash_Map_Entry (int ext_id) : ext_id_ (ext_id){}
   int ext_id_;
   int int_id_;
 };
 struct ACE_Hash_Map_Manager_Ex {
   int bind_i (const int&ext_id);
   ACE_Hash hash_key_;
   unsigned int total_size_;
 };
 inline int ACE_Hash_Map_Manager_Ex::bind_i (const int&ext_id) {
 this->hash_key_(ext_id);
 void *ptr;
 new ACE_Hash_Map_Entry (ext_id);
 };
 int get_handle(void);
 int accept (void);
 struct Reactive_Logging_Server_Ex{
 ACE_Handle_Set master_handle_set_;
 ACE_Hash_Map_Manager_Ex log_map_;
 virtual int handle_connections ();
 };

int Reactive_Logging_Server_Ex:: handle_connections () {
  while (accept () != -1) {
    log_map_.bind_i (get_handle ());
    master_handle_set_.set_bit ();
  }         
}  
Comment 4 Dorit Naishlos 2005-08-28 13:47:45 UTC
The patch below fixes the problem.

We fail on this assert:
	gcc_assert (evolution_part != NULL_TREE);
in 'vect_update_ivs_after_vectorizer'.

This happens because we assume that 'vect_update_ivs_after_vectorizer' is 
called only if 'vect_can_advance_ivs_p' passes 
successfully. 'vect_can_advance_ivs_p' is supposed to be called during the 
analysis phase if we suspect that loop peeling will be required. Currently we 
only call it when we discover that peeling-for-loop-bound will be required, but 
we should also call it if peeling-for-alignment is required (cause usually it 
also involves peeling-for-loop-bound). The patch below adds the missing check.

This bit is actually included in Keith's versioning-for-alignment patch 
(http://gcc.gnu.org/ml/gcc-patches/2005-08/msg01372.html), which hopefully is 
going to be approved soon (I'd rather wait for that, than create a conflict for 
Keith's patch).

Even when this ICE is solved, this is not the end of the story, because this 
loop should get vectorized, and we are going to fail because of an invariant 
phi (phi with evolution NULL, that we don't know how to handle). This goes back 
to http://gcc.gnu.org/ml/gcc-patches/2005-08/msg00905.html. Hopefully 
Ira/Sebastian have a solution to resolve this.

Below is the loop from the testcase;
This:
D.2219_59 = PHI <D.2248_8(3), D.2248_8(1)> 
is the invariant phi:

  # BLOCK 2 freq:10000
  # PRED: 3 [100.0%]  (fallthru,exec) 1 [100.0%]  (fallthru,exec)
  # ivtmp.36D.2301_17 = PHI <ivtmp.36D.2301_18(3), 32(1)>;
  # TMT.9D.2268_2 = PHI <TMT.9D.2268_27(3), TMT.9D.2268_45(1)>;
  # D.2219_59 = PHI <D.2248_8(3), D.2248_8(1)>;
  # __iD.2254_58 = PHI <__iD.2254_24(3), 0(1)>;
<L3>:;
  #   TMT.9D.2268_27 = V_MAY_DEF <TMT.9D.2268_2>;
  thisD.2217_6->master_handle_set_D.2206.mask_D.2146.fds_bitsD.2134
[__iD.2254_58] = 0;
  __iD.2254_24 = __iD.2254_58 + 1;
  ivtmp.36D.2301_18 = ivtmp.36D.2301_17 - 1;
  if (ivtmp.36D.2301_18 != 0) goto <L11>; else goto <L12>;
  # SUCC: 3 [96.9%]  (dfs_back,true,exec) 4 [3.1%]  
(dfs_back,loop_exit,false,exec)

  # BLOCK 3 freq:9687
  # PRED: 2 [96.9%]  (dfs_back,true,exec)
<L11>:;
  goto <bb 2> (<L3>);
  # SUCC: 2 [100.0%]  (fallthru,exec)



Patch:

Index: tree-vect-analyze.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vect-analyze.c,v
retrieving revision 2.35
diff -c -3 -p -r2.35 tree-vect-analyze.c
*** tree-vect-analyze.c 13 Aug 2005 17:28:41 -0000      2.35
--- tree-vect-analyze.c 28 Aug 2005 13:26:31 -0000
*************** vect_enhance_data_refs_alignment (loop_v
*** 955,960 ****
--- 955,965 ----
             TODO: - consider accesses that are known to have the same
                     alignment, even if that alignment is unknown.  */
  
+  /* Often peeling for alignment will require peeling for loop-bound, which in
+     turn requires that we know how to adjust the loop ivs after the loop.  */
+  if (!vect_can_advance_ivs_p (loop_vinfo))
+    LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo) = 0;
+ 
    if (LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo))
      {
        int mis;
Comment 5 Dorit Naishlos 2005-09-08 13:54:25 UTC
(In reply to comment #4)
> This bit is actually included in Keith's versioning-for-alignment patch 
> (http://gcc.gnu.org/ml/gcc-patches/2005-08/msg01372.html), which hopefully is 
> going to be approved soon (I'd rather wait for that, than create a conflict 
for 
> Keith's patch).

It looks like this ICE is now solved (Ira committed Keith's patch a few days 
ago).
Comment 6 Andrew Pinski 2005-09-08 19:38:42 UTC
Fixed.