125 Commits

Author SHA1 Message Date
Florian Hahn
8fa81cfad4
[ConstraintElim] Address comments from D137840.
Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D139482
2022-12-07 14:12:53 +00:00
Florian Hahn
9eda78107c
[ConstraintElim] Fix sort order to not comparing insts in different bbs.
Update the sort order to make sure that comesBefore is never used from
conditional facts, which are instructions but may use DFS numbers from
different blocks.

This fixes a crash in the added test on some platforms.
2022-12-06 23:47:24 +00:00
Florian Hahn
6887cfb982
[ConstraintElim] Queue facts and checks directly.
This allows interleaving facts and checks in a single block. In
particular this enables using facts from assumes for conditions in the
same block that come after the assume.

This could be extended to only try to simplify checks at the point where
a condition is used.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D138452
2022-12-05 16:44:20 +00:00
Florian Hahn
6b940588a0
[ConstraintElim] Update comment after recent changes.
Update the comment to reflect the current code.
2022-12-05 12:19:09 +00:00
Florian Hahn
ee605b0acc
[ConstraintElim] Use collectOffset result for chained gep support.
This slightly simplifies the code and addresses a correctness issue
where the index scaling for the precondition was not considered
properly.

Thanks to @nikic for pointing that out in D137840.
2022-12-01 17:01:07 +00:00
Florian Hahn
6a834d2f2b
[ConstraintElim] Use collectOffset instead of custom GEP idx iteration.
Use collectOffset to collect scaled indices and constant offset for GEP
instead of custom code. This simplifies the logic in decomposeGEP and
allows to handle all cases supported by the generic helper.
2022-11-28 16:54:58 +00:00
Nikita Popov
42d9261417 [ConstraintElimination] Use SmallVectorImpl (NFC)
When passing a SmallVector by reference, don't specify its size.
2022-11-14 11:01:15 +01:00
Nikita Popov
e82b5b5bbd [ConstraintElimination] Add Decomposition struct (NFCI)
Replace the vector of DecompEntry with a struct that stores the
constant offset separately. I think this is cleaner than giving the
first element special handling.

This probably also fixes some potential ubsan errors by more
consistently using addWithOverflow/multiplyWithOverflow.
2022-11-14 10:44:16 +01:00
Nikita Popov
30982a595d [ConstraintElimination] Make decompose() infallible
decompose() currently returns a mix of {} and 0 + 1*V on failure.
This changes it to always return the 0 + 1*V form, thus making
decompose() infallible.

This makes the code marginally more powerful, e.g. we now fold
sub_decomp_i80 by treating the constant as a symbolic value.

Differential Revision: https://reviews.llvm.org/D137847
2022-11-14 10:42:04 +01:00
Florian Hahn
8086b0c8a8
[ConstraintElim] Drop bail out for scalable vectors after using getTrue
ConstantInt::getTrue/getFalse can materialize scalable vectors with all
lanes true/false.
2022-11-03 19:05:45 +00:00
Florian Hahn
44d8f80b26
[ConstraintElim] Use ConstantInt::getTrue to create constants (NFC).
Use existing ConstantInt::getTrue/getFalse functionality instead of
custom getScalarConstOrSplat as suggested by @nikic.
2022-11-03 12:20:23 +00:00
Florian Hahn
74d8628cf7
[ConstraintElimination] Skip compares with scalable vector types.
Materializing scalable vectors with boolean values is not implemented
yet. Skip those cases for now and leave a TODO.
2022-11-02 23:57:14 +00:00
Florian Hahn
b478d8b966
[ConstraintElimination] Generate true/false vectors for vector cmps.
This fixes crashes when vector compares can be simplified to true/false.
2022-11-02 18:13:35 +00:00
Bjorn Pettersson
44bb4099cd [ConstraintElimination] Do not crash on vector GEP in decomposeGEP
Commit 359bc5c541ae4b02 caused
 Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"'
failures in decomposeGEP when the GEP pointer operand is a vector.

Fix is to use DataLayout::getIndexTypeSizeInBits when fetching the
index size, as it will use the scalar type in case of a ptr vector.

Differential Revision: https://reviews.llvm.org/D137185
2022-11-02 10:04:11 +01:00
Florian Hahn
27f6091bb0
[ConstraintElimination] Fix nested GEP check.
At the moment, the implementation requires that the outer GEP has a
single index, the inner GEP can have an arbitrary indices, because the
general `decompose` helper is used.
2022-11-01 14:43:42 +00:00
Simon Pilgrim
3c71253eb7 ConstraintElimination - pass const DataLayout by reference in (recursive) MergeResults lambda capture. NFC.
There's no need to copy this and fixes a coverity remark about large copy by value
2022-10-28 11:20:09 +01:00
Florian Hahn
6db71b8f14
[ConstraintElim] Use helper to allow overflow for coefficients of GEPs
If the arithmetic for indices of inbounds GEPs overflows, the result is
poison. This means it is also OK for the coefficients to overflow. GEP
decomposition is limited to cases where the index size is <= 64 bit,
which can be represented by int64_t used for the coefficients in the
constraint system.
2022-10-17 20:30:43 +01:00
Florian Hahn
462ab9810d
[ConstraintElim] Fix signed integer overflow for inbounds GEP.
For inbounds GEPs, signed overflow yields poison, so it is fine for the
coefficients to wrap as well. This fixes an UBSan failure.
2022-10-16 23:25:28 +01:00
Florian Hahn
aec0c1009f
[ConstraintElim] Replace custom GEP index handling by using existing code
Instead of duplicating the existing decomposition code for GEP indices
just use the existing code by calling the existing decompose function on
the index expression and multiply the result's coefficients by the scale of
the index.

This both reduces code duplication and generalizes the pattern we can
handle.
2022-10-16 21:53:11 +01:00
Florian Hahn
a4635ec710
[ConstraintElim] Support add nsw for unsigned preds with positive ops.
If both operands of an `add nsw` are known positive, it can be treated
the same as `add nuw` and added to the unsigned system.

https://alive2.llvm.org/ce/z/6gprff
2022-10-16 20:25:14 +01:00
Florian Hahn
7c1b80e35c
[ConstraintElim] Support unsigned decomposition of mul/shl nuw..const
Support decomposition for `mul/shl nuw` with constant operand for unsigned
queries. Those expressions should not wrap in the unsigned sense and can
be added directly to the unsigned system.
2022-10-15 21:28:08 +01:00
Florian Hahn
f12684d36e
[ConstraintElim] Support signed decomposition of add nsw.
Add support decomposition for `add nsw` for signed queries.
`add nsw` won't wrap and can be directly added to the signed
system.
2022-10-15 18:34:03 +01:00
Zain Jaffal
0c8dde551c [ConstraintElimination] Move logic for replacing ssub overflow users (NFC)
Reviewed By: fhahn

Differential Revision: https://reviews.llvm.org/D134044
2022-10-14 21:14:21 +01:00
Florian Hahn
5a68e578ca
[ConstraintElim] Add debug message when decomposition fails. 2022-10-14 11:02:05 +01:00
Florian Hahn
572d5d374c
[ConstraintElim] Add support for GEPs with multiple indices.
Lift restriction on GEPs with a single index by iterating over all
indices and joining the {Coefficient, Variable} entries for all indices
together.
2022-10-13 21:08:33 +01:00
Florian Hahn
71c49d189a
[ConstraintElim] Move check-and-replace logic to helper function (NFC).
Move logic to check and replace conditions to a helper function. This
isolates the code, allows using early returns, reduces the
indentation and simplifies eliminateConstraints.
2022-10-13 18:58:37 +01:00
Florian Hahn
019049a1ca
[ConstraintElim] Use MulOverflow to avoid UB on signed overflow.
This fixes an UBSan failure after 359bc5c541ae. For inbounds GEP with
index sizes <= 64, having the coefficients overflowing is fine.
2022-10-13 13:57:43 +01:00
Florian Hahn
359bc5c541
[ConstraintElim] Bail out for GEPs when index size > 64 bits.
Limit pointer decomposition to pointers with index sizes of at most 64
bits. int64_t is used for coefficients, so as long as the index size <=
64 bits we should be able to represent all pointer offsets.

Pointer decomposition is limited to inbounds GEPs, so if a index
computation would overflow the result is poison, so it doesn't matter
that the coefficient overflows.

This allows replacing MulOverflow with regular multiplications.
2022-10-13 10:19:30 +01:00
Florian Hahn
0ebd288338
[ConstraintElim] Move GEP decomposition code to separate fn (NFC).
Breaks up a large function and allows for the use to early exits.
2022-10-12 20:39:05 +01:00
Florian Hahn
80e49f49e4
[ConstraintElimination] Bail out for GEPs with scalable vectors.
This fixes a crash with scalable vectors, thanks @nikic for spotting
this!
2022-10-10 16:01:20 +01:00
Florian Hahn
fee8f561bd
[ConstraintElimination] Include index type scale.
The current decomposition for GEPs did not correctly handle cases where
GEPs access different source types. Adjust the constraints by including
the indexed type-size as coefficients.

Further generalization to allow GEPs with more than one index is a
needed general follow-up improvement.
2022-10-09 21:53:30 +01:00
Florian Hahn
11a6e64ba7
[ConstraintElim] Move logic to get constraint for solving to helper.
Move common logic shared by callers of getConstraint that use the result
to query the constraint system to a new helper getConstraintForSolving.

This includes common legality checks (i.e. not an equality constraint,
no new variables) and the logic to query the unsigned system if possible
for signed predicates.
2022-10-09 10:44:36 +01:00
Florian Hahn
e0136a62cc
[ConstraintElimination] Support chained GEPs with constant offsets.
Handle the (gep (gep ....), C) case by incrementing the constant
coefficient of the inner GEP, if C is a constant.
2022-10-08 16:59:27 +01:00
Florian Hahn
be858bda69
[ConstraintElimination] Remove unused function (NFC). 2022-10-08 16:05:56 +01:00
Florian Hahn
9d31d1c214
[ConstraintElimination] Use logic from 3771310eed for queries only.
The logic added in 3771310eed was placed sub-optimally. Applying the
transform in ::getConstraint meant that it would also impact conditions
that are added to the system by the signed <-> unsigned transfer logic.

This meant we failed to add some signed facts to the signed system. To
make sure we still add as many useful facts to the signed/unsigned
systems, move the logic to the point where we query the system.
2022-10-08 11:03:45 +01:00
Florian Hahn
3771310eed
[ConstraintElimination] Convert to unsigned Pred if possible.
Convert SLE/SLT predicates to unsigned equivalents if both operands are
known to be signed-positive.

https://alive2.llvm.org/ce/z/tBeiZr
2022-10-07 12:27:36 +01:00
Florian Hahn
a7ac0dd0cf
[ConstraintElimination] Generalize AND matching.
Extend more general matching used for chains of ORs to also support
chains of ANDs.
2022-10-06 17:17:38 +01:00
Florian Hahn
8e3e96298f
[ConstraintElimination] Order cmps for signed <-> unsigned transfer first.
Make sure conditions with constant operands come before conditions
without constant operands. This increases the effectiveness of the
current signed <-> unsigned fact transfer logic.
2022-10-06 15:56:25 +01:00
Florian Hahn
349375d093
[ConstraintElimination] Generalize OR matching.
Extend OR handling to traverse chains of ORs.
2022-10-06 11:56:22 +01:00
Florian Hahn
7449570ff7
[ConstraintElimination] Use ConstraintTy::IsSigned instead of Predicate.
This should be NFC and ensure the sign of the constraint is used
consistently in the future.
2022-10-06 07:51:49 +01:00
Florian Hahn
9aa004a04c
[ConstraintElimination] Convert NewIndices to vector and rename (NFCI).
The callers of getConstraint only require a list of new variables.
Update the naming and types to make this clearer.
2022-10-05 16:25:00 +01:00
Florian Hahn
b2daeb9706
[ConstraintElimination] Re-enable debug print when adding facts. (NFC)
Also add test coverage for important debug output.
2022-10-03 20:51:58 +01:00
Florian Hahn
bdfe986d66
[ConstraintElimination] Simplify logic for using inverse predicate (NFC)
Recent improvements to the code structure mean we don't need to reset
the condition's predicate in the IR and later restore it. Remove the
restorer logic.
2022-10-03 18:35:59 +01:00
Florian Hahn
017552e8b8
[ConstraintElimination] Remove stray comment (NFC).
The comment doens't apply in the current context, remove it.
2022-10-03 18:20:48 +01:00
Florian Hahn
a2efc29e99
[ConstraintElimination] Remove unused StackEntry::IsNot field. (NFC)
The field is no unused and can be removed.
2022-10-03 18:05:25 +01:00
Florian Hahn
3fe6ddd999
[ConstraintElimination] Update Changed status in ssub simplification.
Update tryToSimplifyOverflowMath to indicate whether the function made
any changes to the IR.
2022-10-02 14:25:51 +01:00
Florian Hahn
04c711c78d
[ConstraintElimination] Make sure the variable is available before use.
This fixes a crash when trying to access an index for a value where we
don't have a known index.

Fixes #58009.
2022-09-30 18:09:01 +01:00
serge-sans-paille
16544cbe64 [iwyu] Move <cmath> out of llvm/Support/MathExtras.h
Interestingly, MathExtras.h doesn't use <cmath> declaration, so move it out of
that header and include it when needed.

No functional change intended, but there's no longer a transitive include
fromMathExtras.h to cmath.
2022-09-28 20:49:01 +02:00
Florian Hahn
7914e53e31
[ConstraintElimination] Fix crash when combining results.
f213128b292d didn't account for the possibility that the result of
decompose may be empty. Fix that by explicitly checking. Use a newly
introduced helper to also reduce some duplication.

Thanks @bjope for finding the issue!
2022-09-17 14:47:38 +01:00
Florian Hahn
7f3ff9d3c0
[ConstraintElimination] Track if variables are positive in constraint.
Keep track if variables are known positive during constraint
decomposition, aggregate the information when building the constraint
object and encode the extra information as constraints to be used during
reasoning.
2022-09-14 18:43:54 +01:00