https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118350
Bug ID: 118350 Summary: [12/13/14/15 Regression] Wrong number of loop iterations starting with r7-3839-gde0a3fa38e2ad8 Product: gcc Version: unknown Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: stefansf at gcc dot gnu.org Target Milestone: --- Target: s390*-*-* static volatile unsigned long x = 0; static unsigned int y = 0; int main (void) { { l: ++x; --y; if (y) goto l; } if (x != 0x100000000ul) __builtin_abort (); } On s390x compiling this e.g. via gcc -O2 -funroll-loops leads to wrong code. At the end of doloop2 we have: (insn 6 2 75 2 (set (reg:SI 62 [ y_lsm.6 ]) (mem/c:SI (symbol_ref:DI ("*.LANCHOR0") [flags 0x182]) [1 y+0 S4 A32])) 1507 {*movsi_zarch} (nil)) (note 75 6 72 9 [bb 9] NOTE_INSN_BASIC_BLOCK) (insn 72 75 73 9 (parallel [ (set (reg:SI 78) (plus:SI (reg:SI 62 [ y_lsm.6 ]) (const_int -1 [0xffffffffffffffff]))) (clobber (reg:CC 33 %cc)) ]) -1 (nil)) (insn 73 72 74 9 (parallel [ (set (reg:SI 79) (plus:SI (reg:SI 78) (const_int 1 [0x1]))) (clobber (reg:CC 33 %cc)) ]) -1 (nil)) That means reg 79 contains the initial value of y which is zero. During doloop2 we substitute the newly computed niter which is (insn 281 184 196 37 (set (reg:SI 82) (lshiftrt:SI (reg:SI 79) (const_int 3 [0x3]))) -1 (nil)) wich resulted from unroll2 desc->niter_expr = simplify_gen_binary (UDIV, desc->mode, old_niter, gen_int_mode (max_unroll + 1, desc->mode)); Since old_niter is just y which is initially zero, dividing it by the number of loop unrollings (in this case 8) leads to wrong code, i.e., the loop is executed 8 times more which means the final value of x is not 0x100000000 but 0x800000000. Although bisection stops at r7-3839-gde0a3fa38e2ad8 this doesn't seem to be the culprit to me since it is not affecting the computation of niters.