[llvm] [SCEV] Clear AddRec no-wrap flags when forgetting results (PR #212744)

via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 29 04:45:47 PDT 2026


Michael-Chen-NJU wrote:

> This is categorically wrong. Flags on SCEV expressions can never be dropped.
> 
> Please provide more context on what the issue here is, i.e. what the involved SCEV expression are, what LoopFlatten changes to make them invalid, etc.
> 
> Edit: Godbolt with the test case for reference: https://llvm.godbolt.org/z/on1hb6f3G I assume the issue here is along the lines of LoopFlatten changing the outer loop to have a larger tripcount, such that a `{0,+,1}` addrec of a certain width that was previously nuw no longer is nuw with the new larger tripcount?

Thanks. The previous SCEV-side flag mutation was wrong, and I removed it.

The issue is exactly along the lines you described. Before LoopFlatten, the outer i8 IV `%i.021.us` is `{0,+,1}<nuw>` because the original outer loop only runs `%N` iterations. The linearized value `%add.us = %j + %i * %N` is used by `%idxprom.us = zext i8 %add.us to i64`.

After LoopFlatten with IV widening, `%add.us` may be replaced by `%flatten.trunciv = trunc i64 %indvar1 to i8`, while the outer loop now runs `zext(%N) * zext(%N)` iterations. For example, with `N = 17`, this is 289 iterations, so the i8 truncation wraps. The old i8 `{0,+,1}<nuw>` fact was valid for the original loop, but not for the flattened iteration space.

The updated patch avoids creating this situation instead of changing SCEV flags: LoopFlatten does not use the widened narrow-IV replacement unless the flattened trip count is known to fit in the original narrow type, or the original `i*M+j` computation is already protected by matching nowrap flags.

https://github.com/llvm/llvm-project/pull/212744


More information about the llvm-commits mailing list