llvm / llvm/llvm-project

[SCEVExpander] Why is only gep nuw preserved, and not nusw?

Open
#208,399 1 comment 0 reactions 0 assignees View on GitHub
llvm:SCEV question
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

#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):

```llvm
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:`

```llvm
%scevgep = getelementptr i8, ptr %a, i64 %1 ; no nusw, no inbounds
```
even though SCEV proves the recurrence doesn't wrap ({...,+,-4}).

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/ no-wrap never reaches the GEP.
Would translating the recurrence's signed no-wrap (or inbounds-derived ) into nusw be sound and worthwhile here?

Contributor guide

Open the contributing guide

Research direction

Start in ScalarEvolutionExpander.cpp at lines 386-388 and 1366-1367, then reproduce the minimal example with opt -passes=indvars -S. Trace how the pointer AddRec flags reach expandAddToGEP and compare the emitted GEP with the SCEV no-wrap information. Done means the intended nusw propagation behavior is established and covered by a focused regression test.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.