[Arith] Simplify to positive numerators in floordiv/floormod #13708
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Negative numerators to modulo/remainder operations are not supported by the Vulkan API. While the SPIR-V instructions
OpSRemandOpSModhave identical semantics totir::Modandtir::FloorMod, respectively, use of either instruction within Vulkan results in undefined behavior. From the Vulkan spec:This issue was first noticed in #13530, where use of integer arithmetic resulted in negative numerators. This hadn't caused issues previously, because most use of div/mod use a denominator that is a power of two. In these cases,
tir.LowerIntrinimplements floordiv and floormod using only bitwise operations. When the denominator isn't a power of two, bothtir::FloorDivandtir::FloorModare implemented in terms oftir::Mod, which triggers the undefined behavior for negative numerators.This commit implements additional simplification rules that preferentially removes negative values from the numerators. For example, simplifying
floormod(i - 2, 8)tofloormod(i + 6, 8), and simplifyingfloordiv(i - 2, 8)tofloordiv(i + 6, 8) - 1. These handle the most common case, where some index variable is being offset by a negative constant.