https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112612
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Ever confirmed|0 |1 Last reconfirmed| |2023-11-20 --- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- Confirmed. Candidate 1: Var befor: ivtmp.5 Var after: ivtmp.5 Incr POS: before exit test IV struct: Type: unsigned long Base: 0 Step: 1 Biv: N Overflowness wrto loop niter: No-overflow ... Candidate 8: Var befor: ivtmp.10 Var after: ivtmp.10 Incr POS: before exit test IV struct: Type: unsigned int Base: 0 Step: 2 Biv: N Overflowness wrto loop niter: No-overflow Candidate 9: Var befor: ivtmp.11 Var after: ivtmp.11 Incr POS: before exit test IV struct: Type: unsigned long Base: (unsigned long) a_8(D) Step: 4 Object: (void *) a_8(D) Biv: N Overflowness wrto loop niter: Overflow so we do have this candidate. Improved to: cost: 16 (complexity 0) reg_cost: 4 cand_cost: 10 cand_group_cost: 2 (complexity 0) candidates: 8, 9 group:0 --> iv_cand:8, cost=(0,0) group:1 --> iv_cand:9, cost=(2,0) group:2 --> iv_cand:8, cost=(0,0) invariant variables: invariant expressions: Initial set of candidates: cost: 15 (complexity 2) reg_cost: 3 cand_cost: 5 cand_group_cost: 7 (complexity 2) candidates: 1 group:0 --> iv_cand:1, cost=(4,0) group:1 --> iv_cand:1, cost=(3,2) group:2 --> iv_cand:1, cost=(0,0) invariant variables: 1 invariant expressions: but somehow we fail to express(?) some of the uses with just candidate 8? It "works" with -m32 added: <bb 3> [local count: 1063004408]: # ivtmp.10_12 = PHI <ivtmp.10_11(5), 0(2)> val_7 = (int) ivtmp.10_12; MEM[(int *)a_8(D) + ivtmp.10_12 * 2] = val_7; ivtmp.10_11 = ivtmp.10_12 + 2; if (ivtmp.10_11 != 200) goto <bb 5>; [98.99%] so it might be the 32->64bit promotion is what gets us off. We might possibly want to consider a 'unsigned long' candidate with step 2. .L2: movl %eax, (%edx,%eax,2) addl $2, %eax cmpl $200, %eax jne .L2