211 Commits

Author SHA1 Message Date
Ramkumar Ramachandra
856c47b884
ConstraintElim: assert on invalid union field (NFC) (#115898)
getContextInst currently returns an invalid union field, when it is
called with a ConditionFact, although existing callers don't do this. In
order to error out early and serve as documentation for future callers,
add an assert forbidding the behavior.
2024-11-13 12:05:53 +00:00
Jeremy Morse
96f37ae453
[NFC] Use initial-stack-allocations for more data structures (#110544)
This replaces some of the most frequent offenders of using a DenseMap that
cause a malloc, where the typical element-count is small enough to fit in
an initial stack allocation.

Most of these are fairly obvious, one to highlight is the collectOffset
method of GEP instructions: if there's a GEP, of course it's going to have
at least one offset, but every time we've called collectOffset we end up
calling malloc as well for the DenseMap in the MapVector.
2024-09-30 23:15:18 +01:00
Youngsuk Kim
d31e314131 [llvm] Don't call raw_string_ostream::flush() (NFC)
Don't call raw_string_ostream::flush(), which is essentially a no-op.
As specified in the docs, raw_string_ostream is always unbuffered.
( 65b13610a5226b84889b923bae884ba395ad084d for further reference )
2024-09-20 12:19:59 -05:00
Yingwei Zheng
85b6aac7c2
[ConstraintElim] Fix miscompilation caused by PR97974 (#105790)
Fixes https://github.com/llvm/llvm-project/issues/105785.
2024-08-23 16:06:00 +08:00
Nikita Popov
73d835ccec [ConstraintElimination] Use getAllOnesValue()
Split out from https://github.com/llvm/llvm-project/pull/80309.
2024-08-12 16:37:42 +02:00
Poseydon42
d18ca43edc
[ConstraintElimination] Add support for UCMP/SCMP intrinsics (#97974)
This adds checks to fold calls to `ucmp`/`scmp` where a comparative
relationship between the arguments can be established.
2024-07-10 21:59:59 +02:00
Florian Hahn
5b927130b0
[ConstraintElim] Use cond from header as upper bound on IV in exit BB. (#94610)
For loops, we can use the condition in the loop header as upper bound on
the compared induction in the unique exit block, if it exists. This can
be done even if there are multiple in-loop edges to the unique exit
block, as any other exit may only exit earlier.

More generally, we could add the OR of all exit conditions to the exit,
but that's a possible future extension.

PR: https://github.com/llvm/llvm-project/pull/94610
2024-07-09 19:37:38 +01:00
Nikita Popov
74deadf196
[IRBuilder] Don't include Module.h (NFC) (#97159)
This used to be necessary to fetch the DataLayout, but isn't anymore.
2024-06-29 15:05:04 +02:00
Nikita Popov
9df71d7673
[IR] Add getDataLayout() helpers to Function and GlobalValue (#96919)
Similar to https://github.com/llvm/llvm-project/pull/96902, this adds
`getDataLayout()` helpers to Function and GlobalValue, replacing the
current `getParent()->getDataLayout()` pattern.
2024-06-28 08:36:49 +02:00
Stephen Tozer
d75f9dd1d2 Revert "[IR][NFC] Update IRBuilder to use InsertPosition (#96497)"
Reverts the above commit, as it updates a common header function and
did not update all callsites:

  https://lab.llvm.org/buildbot/#/builders/29/builds/382

This reverts commit 6481dc57612671ebe77fe9c34214fba94e1b3b27.
2024-06-24 18:00:22 +01:00
Stephen Tozer
6481dc5761
[IR][NFC] Update IRBuilder to use InsertPosition (#96497)
Uses the new InsertPosition class (added in #94226) to simplify some of
the IRBuilder interface, and removes the need to pass a BasicBlock
alongside a BasicBlock::iterator, using the fact that we can now get the
parent basic block from the iterator even if it points to the sentinel.
This patch removes the BasicBlock argument from each constructor or call
to setInsertPoint.

This has no functional effect, but later on as we look to remove the
`Instruction *InsertBefore` argument from instruction-creation
(discussed
[here](https://discourse.llvm.org/t/psa-instruction-constructors-changing-to-iterator-only-insertion/77845)),
this will simplify the process by allowing us to deprecate the
InsertPosition constructor directly and catch all the cases where we use
instructions rather than iterators.
2024-06-24 17:27:43 +01:00
Florian Hahn
ba0e871db8
[ConstraintElim] Look through SExt with precond Op sge 0.
Look through SExt with a precondition that the operand is signed
positive.

https://alive2.llvm.org/ce/z/zvVVHj
2024-05-22 13:11:04 +01:00
Florian Hahn
8a5d51b039
[ConstraintElim] Use default depth for most calls of isNonNegative.
Helps to improve resuls in some cases, while being overall neutral with
respect to compile-time,
https://llvm-compile-time-tracker.com/compare.php?from=2c9b6c1b36b8185299de083c3058e0c1e7760442&to=5984b1649dc12741308089de235647cf036df95f&stat=instructions:u
2024-02-28 13:14:40 +00:00
Yingwei Zheng
87b1e735b2
[ConstraintElim] Decompose sext-like insts for signed predicates (#82344)
Alive2: https://alive2.llvm.org/ce/z/A8dtGp
Fixes #82271.
2024-02-23 01:16:39 +08:00
Alexander Shaposhnikov
4d8e849dfb
[ConstraintElim] Add facts for llvm.abs >= 0 (#79070)
Add facts for llvm.abs >= 0.

https://alive2.llvm.org/ce/z/GXnMHu
2024-02-06 15:16:41 -08:00
Yingwei Zheng
bc9c2be357
[ConstraintElim] Simplify MinMaxIntrinsic (#75306)
This patch replaces min/max intrinsic with one of its operands if
possible.
Alive2: https://alive2.llvm.org/ce/z/LoHfYf
Fixes #75155.
2024-02-04 21:07:40 +08:00
Kazu Hirata
1605bf5815
[ConstraintElimination] Use std::move in the constructor (NFC) (#79259)
Moving the contents of Coefficients saves 0.43% of heap allocations
during the compilation of a large preprocessed file, namely
X86ISelLowering.cpp, for the X86 target.
2024-01-24 09:18:57 -08:00
Florian Hahn
3d91d9613e
[ConstraintElim] Make sure min/max intrinsic results are not poison.
The result of umin may be poison and in that case the added constraints
are not be valid in contexts where poison doesn't cause UB. Only queue
facts for min/max intrinsics if the result is guaranteed to not be
poison.

This could be improved in the future, by only adding the fact when
solving conditions using the result value.

Fixes https://github.com/llvm/llvm-project/issues/78621.
2024-01-24 14:25:55 +00:00
Nikita Popov
ebb853fbe5 [ConstraintElim] Remove unused checkCondition() parameters (NFC) 2024-01-22 15:55:35 +01:00
Nikita Popov
ed1632b72e
[ConstraintElim] Support signed induction variables (#77103)
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.
2024-01-08 10:00:23 +01:00
Nikita Popov
71f56e49ce
[ConstraintElim] Decompose shl nsw for signed predicates (#76961)
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.
2024-01-05 09:53:05 +01:00
Nikita Popov
62144969bc [ConstraintElim] Add debug output for failed preconditions
Print debug output if a constraint does not get added due to a
failed precondition.
2024-01-04 14:29:07 +01:00
Nikita Popov
f812251875
[ConstraintElim] Use SCEV to check for multiples (#76925)
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.
2024-01-04 14:04:15 +01:00
Nikita Popov
c17af94b96 [ConstraintElim] Use SmallDenseMap (NFC)
The number of variables in the constraint is usually very small.
Use SmallDenseMap to avoid allocations.
2024-01-03 17:04:04 +01:00
Florian Hahn
3c127e83c0
[ConstraintElim] Replace NUWSub decomp with recursive decomp of ops.
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.
2024-01-02 22:05:57 +00:00
Alexander Shaposhnikov
3af59cfe0b
[ConstraintElim] Add facts implied by llvm.abs (#73189)
Add  "abs(x) >=s x" fact.

https://alive2.llvm.org/ce/z/gOrrU3

Test plan: ninja check-all
2024-01-02 11:00:03 -08:00
Florian Hahn
fbcf8a8cbb
[ConstraintElim] Add (UGE, var, 0) to unsigned system for new vars. (#76262)
The constraint system used for ConstraintElimination assumes all
varibles to be signed. This can cause missed optimization in the
unsigned system, due to missing the information that all variables are
unsigned (non-negative).

Variables can be marked as non-negative by adding Var >= 0 for all
variables. This is done for arguments on ConstraintInfo construction and
after adding new variables. This handles cases like the ones outlined in
https://discourse.llvm.org/t/why-does-llvm-not-perform-range-analysis-on-integer-values/74341

The original example shared above is now handled without this change,
but adding another variable means that instcombine won't be able to
simplify examples like https://godbolt.org/z/hTnra7zdY

Adding the extra variables comes with a slight compile-time increase
https://llvm-compile-time-tracker.com/compare.php?from=7568b36a2bc1a1e496ec29246966ffdfc3a8b87f&to=641a47f0acce7755e340447386013a2e086f03d9&stat=instructions:u

stage1-O3    stage1-ReleaseThinLTO    stage1-ReleaseLTO-g  stage1-O0-g
 +0.04%           +0.07%                   +0.05%           +0.02%
stage2-O3    stage2-O0-g    stage2-clang
  +0.05%         +0.05%        +0.05%

https://github.com/llvm/llvm-project/pull/76262
2023-12-23 15:53:48 +01:00
Florian Hahn
18170d0f28
[ConstraintElim] Extend AND implication logic to support OR as well. (#76044)
Extend the logic check if an operand of an AND is implied by the other
to also support OR. This is done by checking if !op1 implies op2 or vice
versa.
2023-12-20 18:13:41 +01:00
Florian Hahn
7cf499c63b
[ConstraintElim] Check if second op implies first for And. (#75750)
Generalize checkAndSecondOpImpliedByFirst to also check if the second
operand implies the first.
2023-12-20 11:58:35 +01:00
Kazu Hirata
f0ac6f92a7 [Transforms] Fix a warning
This patch fixes:

  llvm/lib/Transforms/Scalar/ConstraintElimination.cpp:1112:13: error:
  unused function 'dumpUnpackedICmp' [-Werror,-Wunused-function]
2023-12-13 08:31:46 -08:00
Yingwei Zheng
26fbdff458
[ConstraintElim] Refactor checkCondition. NFC. (#75319)
This patch refactors `checkCondition` to handle min/max intrinsic calls
in #75306.
2023-12-13 23:20:01 +08:00
Thomas Symalla
b010747a4f
[NFC] Fix typo in ConstraintElimination assertion. (#75151)
unsinged => unsigned

Co-authored-by: Thomas Symalla <tsymalla@amd.com>
2023-12-12 10:24:11 +01:00
Kazu Hirata
a16429365c [Transforms] Remove unnecessary includes (NFC) 2023-12-09 18:23:06 -08:00
Nikita Popov
ea4ce16da2
[ConstraintElim] Use disjoint flag for decomposition (#74478)
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.)
2023-12-06 10:36:55 +01:00
Florian Hahn
d045e23c2d
[ConstraintElim] Refactor GEP offset collection.
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
2023-11-27 09:05:58 +00:00
Florian Hahn
a9ea02d679
Recommit "[ConstraintElim] Treat ConstantPointerNull as constant offset 0."
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.
2023-11-23 15:56:37 +00:00
Florian Hahn
58286f9c66
Revert "[ConstraintElim] Treat ConstantPointerNull as constant offset 0."
This reverts commit 23628137ea9e7a2942d6a691ea74a7697564e65b.

Revert as this is causing some test failures.
2023-11-22 21:56:06 +00:00
Florian Hahn
23628137ea
[ConstraintElim] Treat ConstantPointerNull as constant offset 0.
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.
2023-11-22 20:03:04 +00:00
Florian Hahn
4ccdab3636
[ConstraintElim] Use isKnownNonNegative for condition transfer. (#72879)
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.
2023-11-21 10:09:35 +00:00
Florian Hahn
167b598648
[ConstraintElim] Remove redundant debug output (NFC).
The removed code was printing `Processing facts ...` a second time.
2023-11-11 13:01:12 +00:00
Florian Hahn
26ab444e88
[ConstraintElim] Make sure add-rec is for the current loop.
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.
2023-11-08 14:07:28 +00:00
Yingwei Zheng
4acc357a37
[ConstraintElim] Add missing check to make sure the bound is loop-invariant (#70555)
This PR adds a missing check for
e6a1657fa3
to make sure the bound is loop-invariant.

Example:
```
define i32 @main() {
entry:
  br label %for.header

for.header:
  %ind1 = phi i64 [ %ind1.i, %for.latch ], [ 0, %entry ]
  %ind2 = phi i64 [ %ind2.i, %for.latch ], [ 5, %entry ]
  %rem = srem i64 %ind2, 4
  %cmp6 = icmp eq i64 %ind1, %rem
  br i1 %cmp6, label %exit1, label %for.latch

for.latch:
  %ind2.i = add i64 %ind2, 1
  %ind1.i = add i64 %ind1, 1
  %cond = icmp eq i64 %ind1.i, 8
  br i1 %cond, label %exit2, label %for.header

exit2:
  %cmp = icmp eq i64 %rem, 0
  %ret = zext i1 %cmp to i32
  ret i32 %ret

exit1:
  ret i32 0
}
```
We cannot infer `%ind1 <u %rem` from `icmp eq i64 %ind1, %rem` in the
loop since `%rem` is not a loop-invariant.

Fixes #70510.
2023-11-02 23:38:05 +08:00
Nikita Popov
1d43096e16
[ConstraintElim] Don't decompose values wider than 64 bits (#68803)
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.
2023-10-16 12:03:49 +02:00
Florian Hahn
56a3e49a00
[ConstraintElim] Support decrementing inductions with step -1. (#68644)
Extend the logic in addInfoForInductions to support decrementing
inductions with a step of -1.

Fixes #64881.
2023-10-10 09:37:27 -07:00
Florian Hahn
00396e6a1a
[ConstraintElim] Support arbitrary incoming values for inductions (#68032)
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.
2023-10-03 12:27:56 +01:00
Florian Hahn
98e016d997
[ConstraintElim] Handle trivial (ICMP_ULE, 0, B) in doesHold.
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
2023-09-27 12:11:28 +01:00
Florian Hahn
e6a1657fa3
[ConstraintElim] Add A < B if A is an increasing phi for A != B.
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
2023-09-27 11:00:28 +01:00
Antonio Frighetto
241848b9b1 [ConstraintElimination] Extend unsigned-to-signed fact transfer
Minor addition of transferring unsigned facts to signed comparisons.

Proofs: https://alive2.llvm.org/ce/z/nqqzHb
2023-09-23 08:54:19 +00:00
Florian Hahn
39d7f700ce
[ConstraintElim] Support adding facts from switch terminators. (#67061)
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.
2023-09-22 11:18:42 +01:00
Florian Hahn
4a5bcbd560
[ConstraintElim] Store conditional facts as (Predicate, Op0, Op1).
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
2023-08-30 10:54:28 +01:00