When adding information for induction variables, add both unsigned and
signed constraints, with corresponding signed and unsigned
preconditions.
I believe the logic here is equally valid for signed/unsigned, we just
need to add preconditions of the same type.
shl nsw x, shift can be interpreted as mul nsw x, (1<<shift), except
when shift is bw-1 (https://alive2.llvm.org/ce/z/vDh2xT). Use this when
decomposing shl. The equivalent decomposition for the unsigned case
already exists.
When adding constraints for induction variables, if the step is not one,
we need to make sure that (end-start) is a multiple of step, otherwise
we might step over the end value.
Currently this only supports one specific pattern for pointers, where
the end is a gep of the start with an appropriate offset.
Generalize this by using SCEV to check for multiples, which also makes
this work for integer IVs.
The current patterns for NUWSub decompositions do not handle negative
constants correctly at the moment (causing #76713).
Replace the incorrect pattern by more general code that recursively
decomposes the operands and then combines the results. This is already
done in most other places that handle operators like add/mul.
This means we fall back to the general constant handling code (fixes the
mis-compile) while also being able to support reasoning about
decomposable expressions in the SUB operands.
Fixes https://github.com/llvm/llvm-project/issues/76713.
Use the or disjoint flag for decomposing or into add, which will handle
cases that haveNoCommonBitsSet() may not be able to reinfer (e.g.
because they require context-sensitive facts, which the call here does
not use.)
Move GEP offset collection to separate helper function and collect
variable and constant offsets in OffsetResult. For now, this only
supports 1 VariableOffset, but the new code structure can be more easily
extended to handle more offsets in the future.
The refactoring drops the check that the VariableOffset >= -1 * constant
offset. This is not needed to check whether the constraint is
monotonically increasing. The constant factors can be ignored, the
constraint will be monotonically increasing if all variables are
positive.
See https://alive2.llvm.org/ce/z/ah2uSQ,
https://alive2.llvm.org/ce/z/NCADNZ
This reverts commit 58286f9c665ad4aa748779d559f2f296de704094.
Now with the test correctly updated.
Original message:
Treat ConstantPointerNull (null) as constant offset 0 in the constraint
instead of a variable. This slightly reduces the number of variables. I
was not able to find a test case where this actually caused any changes.
Treat ConstantPointerNull (null) as constant offset 0 in the constraint
instead of a variable. This slightly reduces the number of variables. I
was not able to find a test case where this actually caused any changes.
Use isKnownNonNegative for information transfer. This can improve
results, in cases where ValueTracking can infer additional non-negative
info, e.g. for phi nodes.
This allows simplifying the check from
https://github.com/llvm/llvm-project/issues/63126 by
ConstraintElimination. It is also simplified by IndVarSimplify now; note
the changes in llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll,
due to this now being simplified earlier.
Update addInfoForInductions to also check if the add-rec is for the
current loop. Otherwise we might add incorrect facts or crash.
Fixes a miscompile & crash introduced by 00396e6a1a0b.
Our coefficients are 64-bits, so adding/multiplying them can wrap in
64-bits even if there would be no wrapping the full bit width.
The alternative would be to check for overflows during all adds/muls in
decomposition. I assume that we don't particularly care about handling
wide integers here, so I've opted to bail out.
Fixes https://github.com/llvm/llvm-project/issues/68751.
Support arbitray incoming values for AddRecs by getting the loop
predecessor and checking if its SCEV matches the AddRec start.
This is done after the existing check, which can help to catch cases
where the expression gets simplified by SCEV to either an IR constant or
existing value which can be used instead.
D152730 may add trivial pre-conditions of the form (ICMP_ULE, 0, B),
which won't be handled automatically by the constraint system, because
we don't add Var >= 0 for all variables in the unsigned system.
Handling the trivial condition explicitly here avoids having the
increase the number of rows in the system per variable.
https://alive2.llvm.org/ce/z/QC92ur
Depends on D152730.
Fixes#63125.
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D158776
This patch adds additional logic to add additional facts for A != B, if
A is a monotonically increasing induction phi. The motivating use case
for this is removing checks when using iterators with hardened libc++,
e.g. https://godbolt.org/z/zhKEP37vG.
The patch pulls in SCEV to detect AddRecs. If possible, the patch adds
the following facts for a AddRec phi PN with StartValue as incoming
value from the loo preheader and B being an upper bound for PN from a
condition in the loop header.
* (ICMP_UGE, PN, StartValue)
* (ICMP_ULT, PN, B) [if (ICMP_ULE, StartValue, B)]
The patch also adds an optional precondition to FactOrCheck (the new
DoesHold field) , which can be used to only add a fact if the
precondition holds at the point the fact is added to the constraint
system.
Depends on D151799.
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D152730
After 4a5bcbd5602, switch instructions can now be handled in a
straight-forward manner by adding (ICMP_EQ, ConditionVal, CaseVal) for
te successor blocks per case.
This allows to add facts even if no corresponding ICmp instruction
exists in the IR.
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D158837
Remove compares after replacing all uses. Cleaning dead compares can
enable additional simplifications when adjusting the position of the
pass slightly. In particular, it seems like the additional dead
instructions may prevent SimplifyCFG performing some folds.
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D158760
This patch represents a condition with `Pred + LHS + RHS` in ReproducerEntry instead of `CmpInst + Not`.
It avoids creating temporary ICmpInsts in D155412.
Reviewed By: nikic, fhahn
Differential Revision: https://reviews.llvm.org/D155782
Simplification of non-equality predicates for solving constraint
systems is now supported by checking the validity of related
inequalities and equalities.
Differential Revision: https://reviews.llvm.org/D152684
Delegate checking of the constraint & its preconditions to the existing
::isValid. This reduces duplication and allows additional optimizations
together with D152730.
This patch extends the existing logic to handle cases where we have
branch conditions of the form (AND icmp, icmp) where the first icmp
implies the second. This can improve results in some cases, e.g. if
SimplifyCFG folded conditions from multiple branches to an AND.
The implementation handles this by adding a new type of check
(AndImpliedCheck), which are queued before conditional facts for the same
block.
When encountering AndImpliedChecks during solving, the first condition
is optimistically added to the constraint system, then we check if the
second icmp can be simplified, and finally the newly added entries are
removed.
The reason for doing things this way is to avoid clashes with signed
<-> unsigned condition transfer, which require us to re-order facts to
increase effectiveness.
Reviewed By: nikic, antoniofrighetto
Differential Revision: https://reviews.llvm.org/D151799
Simplification of equality predicates is now supported by
transferring equalities into inequalities. This is achieved
by separately checking that both `isConditionImplied(A >= B)`
and `isConditionImplied(A <= B)` hold.
Differential Revision: https://reviews.llvm.org/D152067
Handling `true` and `false` constant replacements is now abstracted
out into a single lambda function `ReplaceCmpWithConstant`, so as to
reduce code duplication.