Summary: | [4.1 Regression] ICE in vect_update_ivs_after_vectorizer, at tree-vect-transform.c:2418 | ||
---|---|---|---|
Product: | gcc | Reporter: | Michael Cieslinski <micis> |
Component: | tree-optimization | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | gcc-bugs, irar, pinskia, sebastian.pop |
Priority: | P2 | Keywords: | ice-on-valid-code |
Version: | 4.1.0 | ||
Target Milestone: | 4.1.0 | ||
Host: | Target: | i?86-*-*, x86_64-*-* | |
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | 2005-08-12 22:10:48 | |
Attachments: | preprocessed source |
Description
Michael Cieslinski
2005-08-12 10:52:08 UTC
Created attachment 9478 [details]
preprocessed source
Reducing. 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 (); } } 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; (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). Fixed. |