This does the obvious thing, and recurses through operands searching for a tighter bound on the defining scope. I'm honestly surprised by how little this seems to mater. I think it's worth doing for completeness, but I have to admit the test diffs are unconvincing.
Details
Diff Detail
Event Timeline
Why does this not recover this regression? https://reviews.llvm.org/D109789#inline-1056586 I would have thought that looking through the mul/zext would have helped there.
Not sure, but it looks to be some negative interaction of PSE and LoopAccessAnalysis. The actual SCEV's look fine.
$ ./opt -enable-new-pm=0 -analyze -scalar-evolution scev-reduced.ll
Printing analysis 'Scalar Evolution Analysis' for function 'test1':
Classifying expressions for: @test1
....
%arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom --> ((4 * (zext i32 {1,+,1}<%for.body> to i64))<nuw><nsw> + %a)<nuw> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.body: Computable }
edit: actually, it does fix it. However lit does a prefix match not an exact match and the way the test line is written, that matches both regressed and unregressed. I'll update the test to show the more precise form. Good catch!
LGTM
llvm/lib/Analysis/ScalarEvolution.cpp | ||
---|---|---|
6609 | nit: This newline probably shouldn't be here. |
llvm/test/Analysis/LoopAccessAnalysis/memcheck-wrapping-pointers.ll | ||
---|---|---|
48 | The comment above is indeed outdated, but nuw is correct here. This is because inbounds only guarantees no overflow in the unsigned address space (despite the index being signed). |
nit: This newline probably shouldn't be here.