| Issue |
208399
|
| Summary |
[SCEVExpander] Why is only gep nuw preserved, and not nusw?
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
mbhade-amd
|
#102133 taught SCEVExpander::expandAddToGEP to transfer nuw to the generated GEP, but it never emits nusw. So pointer arithmetic that's known not to signed-wrap — i.e. anything derived from inbounds — loses that information on expansion.
Minimal example (decrementing inbounds walk; every step is inbounds ⇒ nusw):
```bash
define ptr @back(ptr %a, i64 %n) {
entry:
%end = getelementptr inbounds i32, ptr %a, i64 %n
br label %loop
loop:
%p = phi ptr [ %end, %entry ], [ %p.next, %loop ]
%i = phi i64 [ %n, %entry ], [ %i.next, %loop ]
%p.next = getelementptr inbounds i32, ptr %p, i64 -1
%i.next = add nsw i64 %i, -1
%c = icmp sgt i64 %i.next, 0
br i1 %c, label %loop, label %exit
exit:
%pe = phi ptr [ %p.next, %loop ]
ret ptr %pe
}
```
> opt -passes=indvars -S produces a flagless GEP:
```
%scevgep = getelementptr i8, ptr %a, i64 %1 ; no nusw, no inbounds
```
even though SCEV proves the recurrence doesn't wrap ({...,+,-4}<nw>).
Question: is it intentional that only nuw is propagated? Two things stand in the way of a signed analogue, and I'm not sure which are deliberate:
expandAddToGEP only checks FlagNUW (ScalarEvolutionExpander.cpp:386-388).
the pointer-AddRec caller masks flags to FlagNUW before calling (:1366-1367), so a signed/<nw> no-wrap never reaches the GEP.
Would translating the recurrence's signed no-wrap (or inbounds-derived <nw>) into nusw be sound and worthwhile here?
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs