<div dir="ltr"><div><div><div>Hi <br><br></div>I am working on a bug that is caused by Scalar Evolution not being able to compute the iteration count of an unrolled loop (PR 28363). While I believe there is enough information for SCEV to do its job, I think the code that is generated by earlier transformations can be simpler. There is one bug in IndVarSimplify for which Sanjoy Das suggested a fix. With that fix if I disable loop strength reduction the problem is fixed. Below I have copied the code before and after loop strength reduction. <br><br></div>For this code pattern, it is possible to prove that truncs generated by LSR can be avoided (see bottom of the email). Andy Trick says that LSR generally thinks that trunc is free, but there might be ways to work around it or improve LSR target hooks. <br><br></div><div>1- Does anyone has any suggestion on how to fix this in LSR?<br></div><div>2- Any reason that we should not fix LSR, and instead focus on Scalar Evolution so it can handle more complicated code patterns properly?<br></div><div><br></div><div><b><br>Before LSR:</b><br><br><i>for.body.preheader</i>: <br>%xtraiter = and i32 %m, 7<br><br><i>for.body.preheader.new:</i><br>%unroll_iter = sub i32 %m, %xtraiter<br><br><i>for.body:</i><br>%niter = phi i32 [ %unroll_iter, %for.body.preheader.new ], [ %niter.nsub.7, %for.body ]<br>%indvars.iv = phi i64 [ 0, %for.body.preheader.new ], [ %indvars.iv.next.7, %for.body ]<br>%indvars.iv.next.7 = add nsw i64 %indvars.iv, 8<br>%niter.nsub.7 = add nsw i32 %niter, -8<br>%niter.ncmp.7 = icmp eq i32 %niter.nsub.7, 0<br><br><br><b>After LSR:</b><br><br><i>for.body.preheader:</i><br>%xtraiter = and i32 %m, 7<br><br><i>for.body.preheader.new: </i><br>%unroll_iter = sub i32 %m, %xtraiter<br>%2 = zext i32 %unroll_iter to i64<br><br><i>for.body:</i><br>%indvars.iv = phi i64 [ 0, %for.body.preheader.new ], [ %indvars.iv.next.7, %for.body ]<br>%indvars.iv.next.7 = add nsw i64 %indvars.iv, 8<br>%tmp = trunc i64 %indvars.iv.next.7 to i32<br>%tmp80 = trunc i64 %2 to i32<br>%niter.ncmp.7 = icmp eq i32 %tmp80, %tmp<br><br></div><div><b>Why trunc is not needed:</b> %indvars.iv starts from 0 and increments by 8. %2 is divsible by 8.  If indvars.iv.next.7 ever reaches a value, which has a non-zero bit in its upper 32 bits, it will repeat that pattern until it overflows. But the definition of %indvars.iv.next.7 is marked nsw. </div></div>