<div dir="ltr">Hi folks,<div><br></div><div>I'm trying to analyse this piece of IR:</div><div><br></div><div><div>for.body:                                         ; preds = %for.body, %entry</div><div>  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]</div>
<div>  %0 = shl nsw i64 %indvars.iv, 1</div><div>  %arrayidx = getelementptr inbounds i32* %b, i64 %0</div><div>  %1 = load i32* %arrayidx, align 4, !tbaa !1</div><div>  %add = add nsw i32 %1, %I</div><div>  %arrayidx3 = getelementptr inbounds i32* %a, i64 %0</div>
<div>  store i32 %add, i32* %arrayidx3, align 4, !tbaa !1</div><div>  %2 = or i64 %0, 1</div><div>  %arrayidx7 = getelementptr inbounds i32* %b, i64 %2</div><div>  %3 = load i32* %arrayidx7, align 4, !tbaa !1</div><div>  %add8 = add nsw i32 %3, %I</div>
<div>  %arrayidx12 = getelementptr inbounds i32* %a, i64 %2</div><div>  store i32 %add8, i32* %arrayidx12, align 4, !tbaa !1</div><div>  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1</div><div>  %exitcond = icmp eq i64 %indvars.iv.next, 512</div>
<div>  br i1 %exitcond, label %for.end, label %for.body</div></div><div><br></div><div>And, when going through the GEP:</div><div><br></div><div><div>  %0 = shl nsw i64 %indvars.iv, 1</div><div>  %arrayidx = getelementptr inbounds i32* %b, i64 %0</div>
</div><div><br></div><div>ScalarEvolution::createNodeForGEP() is losing the SCEV::FlagNSW, and I believe it's because of this piece of code in getMulExpr():</div><div><br></div><div><div>      // Build the new addrec. Propagate the NUW and NSW flags if both the</div>
<div>      // outer mul and the inner addrec are guaranteed to have no overflow.</div><div>      //</div><div>      // No self-wrap cannot be guaranteed after changing the step size, but</div><div>      // will be inferred if either NUW or NSW is true.</div>
<div>      Flags = AddRec->getNoWrapFlags(clearFlags(Flags, SCEV::FlagNW));</div><div>      const SCEV *NewRec = getAddRecExpr(NewOps, AddRecLoop, Flags);</div><div><br></div><div>      // If all of the other operands were loop invariant, we are done.</div>
<div>      if (Ops.size() == 1) return NewRec;</div></div><div><br></div><div>I understand that you can't assume it won't wrap around with the new stride, but I couldn't find anything else later that would re-assign NSW/NUW. Maybe I need to add this code myself? Possibly in the GEP code, if I can detect the range will be safe, even for large strides?</div>
<div><br></div><div>cheers,<br></div><div>--renato</div></div>