llvm-project/llvm/test/Transforms/IRCE
Max Kazantsev c0b268f90c [IRCE] Fix miscompile with range checks against negative values
In the patch rL329547, we have lifted the over-restrictive limitation on collected range
checks, allowing to work with range checks with the end of their range not being
provably non-negative. However it appeared that the non-negativity of this value was
assumed in the utility function `ClampedSubtract`. In particular, its reasoning is based
on the fact that `0 <= SINT_MAX - X`, which is not true if `X` is negative.

The function `ClampedSubtract` is only called twice, once with `X = 0` (which is OK)
and the second time with `X = IRC.getEnd()`, where we may now see the problem if
the end is actually a negative value. In this case, we may sometimes miscompile.

This patch is the conservative fix of the miscompile problem. Rather than rejecting
non-provably non-negative `getEnd()` values, we will check it for non-negativity in
runtime. For this, we use function `smax(smin(X, 0), -1) + 1` that is equal to `1` if `X`
is non-negative and is equal to 0 if `X` is negative. If we multiply `Begin, End` of safe
iteration space by this function calculated for `X = IRC.getEnd()`, we will get the original
`[Begin, End)` if `IRC.getEnd()` was non-negative (and, thus, `ClampedSubtract` worked
correctly) and the empty range `[0, 0)` in case if ` IRC.getEnd()` was negative.

So we in fact prohibit execution of the main loop if at least one of range checks was
made against a negative value (and we figured it out in runtime). It is still better than
what we have before (non-negativity had to be proved in compile time) and prevents
us from miscompile, however it is sometiles too restrictive for unsigned range checks
against a negative value (which in fact can be eliminated).

Once we re-implement `ClampedSubtract` in a way that it handles negative `X` correctly,
this limitation can be lifted, too.

Differential Revision: https://reviews.llvm.org/D46860
Reviewed By: samparker

llvm-svn: 332809
2018-05-19 13:06:37 +00:00
..
add-metadata-pre-post-loops.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
bad-loop-structure.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
bad_expander.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
bug-loop-varying-upper-limit.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
bug-mismatched-types.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
clamp.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
conjunctive-checks.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
correct-loop-info.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
decrementing-loop.ll [SCEV] Prove implications for SCEVUnknown Phis 2018-04-04 05:46:47 +00:00
empty_ranges.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
eq_ne.ll [IRCE] Enable increasing loops of variable bounds 2018-03-26 09:29:42 +00:00
low-becount.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
multiple-access-no-preloop.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
non_known_positive_end.ll [IRCE] Relax restriction on collected range checks 2018-04-09 06:01:22 +00:00
not-likely-taken.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
only-lower-check.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
only-upper-check.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
optimistic_scev.ll [NFC] Remove overconfident assert from IRCE 2018-01-24 07:51:41 +00:00
pre_post_loops.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
range_intersect_miscompile.ll [IRCE] Relax restriction on collected range checks 2018-04-09 06:01:22 +00:00
ranges_of_different_types.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
rc-negative-bound.ll [IRCE] Fix miscompile with range checks against negative values 2018-05-19 13:06:37 +00:00
single-access-no-preloop.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
single-access-with-preloop.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
skip-profitability-checks.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
stride_more_than_1.ll [IRCE] Only check for NSW on equality predicates 2018-04-18 13:50:28 +00:00
unhandled.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
unsigned_comparisons_ugt.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
unsigned_comparisons_ult.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00
variable-loop-bounds.ll [IRCE] isKnownNonNegative helper function 2018-04-12 12:49:40 +00:00
with-parent-loops.ll [New PM][IRCE] port of Inductive Range Check Elimination pass to the new pass manager 2018-03-15 11:01:19 +00:00