[forwarded from http://bugs.debian.org/256452] HEAD 20040626, ok with 3.3.4 and 3.4.1. gcc -O bitcnt_4.i bitcnt_4.c: In function `btbl_bitcnt': bitcnt_4.c:54: error: PHI argument duplicated for edge 1->0 PHI argument x<D2622>_20 for PHI node x<D2622>_9 = PHI <x<D2622>_22(-1), x.146<D2631>_16(1), x<D2622>_20(1)>; bitcnt_4.c:54: internal compiler error: verify_ssa failed. Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://gcc.gnu.org/bugs.html> for instructions.
Created attachment 6636 [details] testcase
Confirmed, here is the reduced testcase: typedef unsigned long uint32; int ntbl_bitcnt(uint32 x); int btbl_bitcnt(uint32 x); char bits[256]; int btbl_bitcnt(uint32 x) { int cnt = bits[ ((char *)&x)[0] & 0xFF ]; if (0L != (x >>= 8)) cnt += btbl_bitcnt(x); return cnt; } I think this is caused by tail recursion.
I get a slightly different ICE now: pr16225.c: In function `btbl_bitcnt': pr16225.c:9: internal compiler error: in may_propagate_copy, at tree-ssa-copy.c:130 Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://gcc.gnu.org/bugs.html> for instructions. Here is a little simpler code: typedef unsigned long uint32; int ntbl_bitcnt(uint32 x); int btbl_bitcnt(uint32 x); char bits[256]; int btbl_bitcnt(uint32 x) { int cnt = *(char *)&x; if (0L != (x >>= 8)) return btbl_bitcnt(x); return cnt; } oh it looks like tree-loop-ch which causing this. Maybe this is the going in and out of ssa which is causing this problem and causing to loose aliasing info.
Indeed there is a problem in tailr that is confused by function argument that is also used as a name tag. Since tree-loop-ch does not go into and out of ssa and does not lose aliasing info, I don't understand the remark at the second bug (that maybe should get a separate PR?)
I believe the bug is caused by a problem in alias analysis. At the end of alias1, TMT.9 might alias x and bits: Variable: TMT.9, UID 13, is global, call clobbered, may aliases: { x bits } and was call-clobbered. However, add_may_alias () failed to set x call-clobbered: Variable: x, UID 1, is an alias tag, default def: x_9 This inconsistency resulted in the bug. At the one hand, add_stmt_operand () added x as a V_MAY_DEF when renaming variables at the end of alias1 because x wass an alias of TMT.9 and TMT.9 was call-clobbered. At the other hand, tailr1 pass failed to recognize that x was an alias of a call-clobbered variable. It was executed. This patch will make the call-clobbered information consistent and fix this bug. 2004-07-30 Jie Zhang <zhangjie@magima.com.cn> PR tree-optimization/16225 * tree-ssa-alias.c (add_may_alias): If 'alias' is call-clobbered, so are 'var' and its aliases. *** tree-ssa-alias.c.old 2004-07-24 09:05:44.000000000 +0800 --- tree-ssa-alias.c 2004-07-30 13:13:06.000000000 +0800 *************** add_may_alias (tree var, tree alias) *** 1678,1686 **** if (is_call_clobbered (var)) mark_call_clobbered (alias); ! /* Likewise. If ALIAS is call-clobbered, so is VAR. */ else if (is_call_clobbered (alias)) ! mark_call_clobbered (var); VARRAY_PUSH_TREE (v_ann->may_aliases, alias); a_ann->is_alias_tag = 1; --- 1678,1690 ---- if (is_call_clobbered (var)) mark_call_clobbered (alias); ! /* Likewise. If ALIAS is call-clobbered, so are VAR and its aliases. */ else if (is_call_clobbered (alias)) ! { ! mark_call_clobbered (var); ! for (i = 0; i < VARRAY_ACTIVE_SIZE (v_ann->may_aliases); i++) ! mark_call_clobbered (VARRAY_TREE (v_ann->may_aliases, i)); ! } VARRAY_PUSH_TREE (v_ann->may_aliases, alias); a_ann->is_alias_tag = 1;
If the patch is right, it could contain also an update to verify_alias to make it catch such situations earlier, in the future.
I add the following check in verify_flow_insensitive_alias_info (). It shows that there are some other mark_call_clobbered () call sites, which will fail the check. I'm going to look them closer. Index: tree-ssa.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/tree-ssa.c,v retrieving revision 2.26 diff -C3 -p -r2.26 tree-ssa.c *** tree-ssa.c 29 Jul 2004 20:16:26 -0000 2.26 --- tree-ssa.c 1 Aug 2004 14:38:57 -0000 *************** verify_flow_insensitive_alias_info (void *** 368,373 **** --- 368,386 ---- debug_variable (alias); goto err; } + + if (is_call_clobbered (var) && !is_call_clobbered (alias)) + { + error ("Variable is call-clobbered, but its alias is not."); + debug_variable (alias); + goto err; + } + else if (!is_call_clobbered (var) && is_call_clobbered (alias)) + { + error ("Variable is not call-clobbered, but its alias is."); + debug_variable (alias); + goto err; + } } }
Diego, can you have a quick look at these patches? At least, if you can comment on the patch to verify_flow_insensitive_alias_info, Jie would know whether it should work on making it bootstrap fixing the problems it exposes.
Jie's patch in comment #4 looks OK. I am working on something related that may remove this quirk altogether. We don't deal with call-clobberedness in any reasonable way right now. Giovanni's proposal is good, but I'm almost positive that it will trigger ICEs in the verifier. Zdenek, if you don't mind, I will assign this PR to myself. It's not a problem in your code.
(In reply to comment #5) > 2004-07-30 Jie Zhang <zhangjie@magima.com.cn> > > PR tree-optimization/16225 > * tree-ssa-alias.c (add_may_alias): If 'alias' is call-clobbered, so > are 'var' and its aliases. > This is OK, provided it passes bootstrap and testing. Diego.
(In reply to comment #10) > (In reply to comment #5) > > > 2004-07-30 Jie Zhang <zhangjie@magima.com.cn> > > > > PR tree-optimization/16225 > > * tree-ssa-alias.c (add_may_alias): If 'alias' is call-clobbered, so > > are 'var' and its aliases. > > > This is OK, provided it passes bootstrap and testing. > Never mind. The bug is not reproducible anymore. Diego.
Subject: Re: [3.5 regression] ICE: verify_ssa failed. On Sun, 2004-08-01 at 17:33, giovannibajo at libero dot it wrote: > ------- Additional Comments From giovannibajo at libero dot it 2004-08-01 21:33 ------- > Diego, can you have a quick look at these patches? At least, if you can comment > on the patch to verify_flow_insensitive_alias_info, Jie would know whether it > should work on making it bootstrap fixing the problems it exposes. > Well, call-clobberedness and aliasing are not necessarily related. foo (int i) { int *p, a, b; if (i > 10) p = &b; bar (&a); return *p; } Suppose that for some reason we couldn't use points-to information and end up with alias(*p) = { a, b }. You don't really want the call to 'bar()' to clobber 'b', so marking 'b' call-clobbered is too pessimistic. I'm testing a patch to only mark call-clobbered variables whose address escape. add_may_alias should not be setting call-clobbered bits. Diego.