Hi, I noticed there is below code/comments about may_be_zero field in loop niter desc:
tree may_be_zero; /* The boolean expression. If it evaluates to true, the loop will exit in the first iteration (i.e. its latch will not be executed), even if the niter field says otherwise. */ I had difficulty in understanding this because I ran into some cases in which it didn't behave as said. Example1, the dump of loop before sccp is like: <bb 2>: bnd_4 = len_3(D) + 1; <bb 3>: # ivtmp_1 = PHI <0(2), ivtmp_11(4)> _6 = ivtmp_1 + len_3(D); _7 = a[ivtmp_1]; _8 = b[ivtmp_1]; _9 = _7 + _8; a[_6] = _9; ivtmp_11 = ivtmp_1 + 1; if (bnd_4 > ivtmp_11) goto <bb 4>; else goto <bb 5>; <bb 4>: goto <bb 3>; The loop niter information analyzed in sccp is like: Analyzing # of iterations of loop 1 exit condition [1, + , 1] < len_3(D) + 1 bounds on difference of bases: -1 ... 4294967294 result: zero if len_3(D) == 4294967295 # of iterations len_3(D), bounded by 4294967294 Qeustion1, shouldn't it be like "len_3 +1 <= 1" because the latch won't be executed when "len_3 == 0", right? It seems that GCC deliberately skips boundary case. It's ok in this case we can still get zero from niter info "bnd_4 - ivtmp_11" when "bnd_4 == 1" (i,e. len_3 == 0) But when boundary condition is the only case that latch get ZERO executed, the may_be_zero info will not be computed. See example2, with dump of loop before sccp like: foo (int M) <bb 2>: if (M_4(D) > 0) goto <bb 4>; else goto <bb 3>; <bb 3>: return; <bb 4>: <bb 5>: # i_13 = PHI <0(4), i_10(6)> _5 = i_13 + M_4(D); _6 = a[i_13]; _7 = b[i_13]; _8 = _6 + _7; a[_5] = _8; i_10 = i_13 + 1; if (M_4(D) > i_10) goto <bb 6>; else goto <bb 3>; <bb 6>: goto <bb 5>; The niter information analyzed in sccp is like: Analyzing # of iterations of loop 1 exit condition [1, + , 1](no_overflow) < M_4(D) bounds on difference of bases: 0 ... 2147483646 result: # of iterations (unsigned int) M_4(D) + 4294967295, bounded by 2147483646 So may_be_zero is always false here, but the latch may be ZERO executed when "M_4 == 1". Start from Example1, we can create Example3 which makes no sense to me. Again, the dump of loop is like: <bb 2>: bnd_4 = len_3(D) + 1; <bb 3>: # ivtmp_1 = PHI <0(2), ivtmp_11(4)> _6 = ivtmp_1 + len_3(D); _7 = a[ivtmp_1]; _8 = b[ivtmp_1]; _9 = _7 + _8; a[_6] = _9; ivtmp_11 = ivtmp_1 + 4; if (bnd_4 > ivtmp_11) goto <bb 4>; else goto <bb 5>; <bb 4>: goto <bb 3>; <bb 5>: return 0; The niter info is like: Analyzing # of iterations of loop 1 exit condition [4, + , 4] < len_3(D) + 1 bounds on difference of bases: -4 ... 4294967291 result: under assumptions len_3(D) + 1 <= 4294967292 zero if len_3(D) == 4294967295 # of iterations len_3(D) / 4, bounded by 1073741823 The problem is: won't latch be ZERO executed when "len_3 == 0/1/2/3"? With these examples, my first feeling is that may_be_zero is computed wrongly, but searching code shows that may_be_zero is mostly used by ivopt. Considering ivopt works well with it now, I am wondering if it's designed behavior? Anyone help? Thanks very much. Thanks, bin -- Best Regards.