Revision tags: llvmorg-15-init |
|
#
903c3d28 |
| 26-Jan-2022 |
Nikita Popov <npopov@redhat.com> |
[SCEVExpander] Always use i8 GEP for reused value offset
We could keep the non-i8 GEP code for non-opaque pointers, but there's two reasons I'm dropping it: First, this actually appears to be dead c
[SCEVExpander] Always use i8 GEP for reused value offset
We could keep the non-i8 GEP code for non-opaque pointers, but there's two reasons I'm dropping it: First, this actually appears to be dead code, at least it isn't hit in any of our tests. I expect that this is because we usually expand trip counts, and those are never pointers (anymore). Second, the non-i8 GEP was actually incorrect in multiple ways, because it used SCEV type sizes, which don't match DL type sizes (for pointers) and certainly don't match type alloc sizes (which is what GEPs actually use). As such, I'm simplifying the code to always use the i8 GEP code path if it does get hit.
show more ...
|
#
bec4e865 |
| 26-Jan-2022 |
Nikita Popov <npopov@redhat.com> |
[SCEVExpander] Remove pointer element type access in assertion
Assert directly on i8 rather than the element type of i8*.
|
#
aa97bc11 |
| 21-Jan-2022 |
Nikita Popov <npopov@redhat.com> |
[NFC] Remove uses of PointerType::getElementType()
Instead use either Type::getPointerElementType() or Type::getNonOpaquePointerElementType().
This is part of D117885, in preparation for deprecatin
[NFC] Remove uses of PointerType::getElementType()
Instead use either Type::getPointerElementType() or Type::getNonOpaquePointerElementType().
This is part of D117885, in preparation for deprecating the API.
show more ...
|
Revision tags: llvmorg-13.0.1, llvmorg-13.0.1-rc3, llvmorg-13.0.1-rc2 |
|
#
2d67a86b |
| 11-Jan-2022 |
Florian Hahn <flo@fhahn.com> |
[SCEVExpander] Use IntToPtr for temporary instruction.
Use PtrToInt instead Add when creating temporary instructions. The add might get folded away with more sophisticated folding.
|
#
82fb4f4b |
| 10-Jan-2022 |
Roman Lebedev <lebedev.ri@gmail.com> |
[SCEV] Sequential/in-order `UMin` expression
As discussed in https://github.com/llvm/llvm-project/issues/53020 / https://reviews.llvm.org/D116692, SCEV is forbidden from reasoning about 'backedge ta
[SCEV] Sequential/in-order `UMin` expression
As discussed in https://github.com/llvm/llvm-project/issues/53020 / https://reviews.llvm.org/D116692, SCEV is forbidden from reasoning about 'backedge taken count' if the branch condition is a poison-safe logical operation, which is conservatively correct, but is severely limiting.
Instead, we should have a way to express those poison blocking properties in SCEV expressions.
The proposed semantics is: ``` Sequential/in-order min/max SCEV expressions are non-commutative variants of commutative min/max SCEV expressions. If none of their operands are poison, then they are functionally equivalent, otherwise, if the operand that represents the saturation point* of given expression, comes before the first poison operand, then the whole expression is not poison, but is said saturation point. ``` * saturation point - the maximal/minimal possible integer value for the given type
The lowering is straight-forward: ``` compare each operand to the saturation point, perform sequential in-order logical-or (poison-safe!) ordered reduction over those checks, and if reduction returned true then return saturation point else return the naive min/max reduction over the operands ``` https://alive2.llvm.org/ce/z/Q7jxvH (2 ops) https://alive2.llvm.org/ce/z/QCRrhk (3 ops) Note that we don't need to check the last operand: https://alive2.llvm.org/ce/z/abvHQS Note that this is not commutative: https://alive2.llvm.org/ce/z/FK9e97
That allows us to handle the patterns in question.
Reviewed By: nikic, reames
Differential Revision: https://reviews.llvm.org/D116766
show more ...
|
#
aecad582 |
| 10-Jan-2022 |
Florian Hahn <flo@fhahn.com> |
[SCEVExpander] Only create trunc when needed.
9345ab3a4550 updated generateOverflowCheck to skip creating checks that always evaluate to false. This in turn means that we only need to create TruncTr
[SCEVExpander] Only create trunc when needed.
9345ab3a4550 updated generateOverflowCheck to skip creating checks that always evaluate to false. This in turn means that we only need to create TruncTripCount if it is actually used.
Sink the TruncTripCount creating into ComputeEndCheck, so it is only created when there's an actual check.
show more ...
|
#
ad1b8772 |
| 10-Jan-2022 |
Florian Hahn <flo@fhahn.com> |
[SCEVExpander] Only create multiplication if needed.
9345ab3a4550 updated generateOverflowCheck to skip creating checks that always evaluate to false. This in turn means that we only need to compute
[SCEVExpander] Only create multiplication if needed.
9345ab3a4550 updated generateOverflowCheck to skip creating checks that always evaluate to false. This in turn means that we only need to compute |Step| * Trip count if the result of the multiplication is actually used.
Sink the multiplication into ComputeEndCheck, so it is only created when there's an actual check.
show more ...
|
#
1ce01b7d |
| 09-Jan-2022 |
Florian Hahn <flo@fhahn.com> |
[SCEVExpander] Simplify cleanup, skip sorting by dominance.
There is no need to sort inserted instructions by dominance, as the deletion loop still requires RAUW with undef before deleting. Removing
[SCEVExpander] Simplify cleanup, skip sorting by dominance.
There is no need to sort inserted instructions by dominance, as the deletion loop still requires RAUW with undef before deleting. Removing instructions in reverse insertion order should still insure that the number of uselist updates is kept to a minimum.
show more ...
|
#
7f1bf68d |
| 06-Jan-2022 |
Florian Hahn <flo@fhahn.com> |
[SCEVExpander] Only check overflow if it is needed.
9345ab3a4550 updated generateOverflowCheck to skip creating checks that always evaluate to false. This in turn means that we only need to check fo
[SCEVExpander] Only check overflow if it is needed.
9345ab3a4550 updated generateOverflowCheck to skip creating checks that always evaluate to false. This in turn means that we only need to check for overflows if the result of the multiplication is actually used.
Sink the Or for the overflow check into ComputeEndCheck, so it is only created when there's an actual check.
show more ...
|
#
9345ab3a |
| 08-Jan-2022 |
Florian Hahn <flo@fhahn.com> |
[SCEVExpander] Skip creating <u 0 check, which is always false.
Unsigned compares of the form <u 0 are always false. Do not create such a redundant check in generateOverflowCheck.
The patch introdu
[SCEVExpander] Skip creating <u 0 check, which is always false.
Unsigned compares of the form <u 0 are always false. Do not create such a redundant check in generateOverflowCheck.
The patch introduces a new lambda to create the check, so we can exit early conveniently and skip creating some instructions feeding the check.
I am planning to sink a few additional instructions as follow-ups, but I would prefer to do this separately, to keep the changes and diff smaller.
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D116811
show more ...
|
#
f395a4f8 |
| 07-Jan-2022 |
Florian Hahn <flo@fhahn.com> |
[SCEVExpand] Only create required predicate checks.
Currently generateOverflowCheck always creates code for Step being negative and positive, followed by a select at the end depending on Step's sign
[SCEVExpand] Only create required predicate checks.
Currently generateOverflowCheck always creates code for Step being negative and positive, followed by a select at the end depending on Step's sign.
This patch updates the code to only create either the checks for step being positive or negative, if the sign is known.
Follow-up to D116696.
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D116747
show more ...
|
#
2aed0813 |
| 07-Jan-2022 |
Kazu Hirata <kazu@google.com> |
[llvm] Use true/false instead of 1/0 (NFC)
Identified with modernize-use-bool-literals.
|
#
86d113a8 |
| 06-Jan-2022 |
Florian Hahn <flo@fhahn.com> |
[SCEVExpand] Do not create redundant 'or false' for pred expansion.
This patch updates SCEVExpander::expandUnionPredicate to not create redundant 'or false, x' instructions. While those are triviall
[SCEVExpand] Do not create redundant 'or false' for pred expansion.
This patch updates SCEVExpander::expandUnionPredicate to not create redundant 'or false, x' instructions. While those are trivially foldable, they can be easily avoided and hinder code that checks the size/cost of the generated checks before further folds.
I am planning on look into a few other similar improvements to code generated by SCEVExpander.
I remember a while ago @lebedev.ri working on doing some trivial folds like that in IRBuilder itself, but there where concerns that such changes may subtly break existing code.
Reviewed By: reames, lebedev.ri
Differential Revision: https://reviews.llvm.org/D116696
show more ...
|
#
7787a8f1 |
| 14-Dec-2021 |
Kazu Hirata <kazu@google.com> |
[llvm] Use llvm::reverse (NFC)
|
#
8906a0fe |
| 29-Nov-2021 |
Philip Reames <listmail@philipreames.com> |
[SCEVExpander] Drop poison generating flags when reusing instructions
The basic problem we have is that we're trying to reuse an instruction which is mapped to some SCEV. Since we can have multiple
[SCEVExpander] Drop poison generating flags when reusing instructions
The basic problem we have is that we're trying to reuse an instruction which is mapped to some SCEV. Since we can have multiple such instructions (potentially with different flags), this is analogous to our need to drop flags when performing CSE. A trivial implementation would simply drop flags on any instruction we decided to reuse, and that would be correct.
This patch is almost that trivial patch except that we preserve flags on the reused instruction when existing users would imply UB on overflow already. Adding new users can, at most, refine this program to one which doesn't execute UB which is valid.
In practice, this fixes two conceptual problems with the previous code: 1) a binop could have been canonicalized into a form with different opcode or operands, or 2) the inbounds GEP case which was simply unhandled.
On the test changes, most are pretty straight forward. We loose some flags (in some cases, they'd have been dropped on the next CSE pass anyways). The one that took me the longest to understand was the ashr-expansion test. What's happening there is that we're considering reuse of the mul, previously we disallowed it entirely, now we allow it with no flags. The surrounding diffs are all effects of generating the same mul with a different operand order, and then doing simple DCE.
The loss of the inbounds is unfortunate, but even there, we can recover most of those once we actually treat branch-on-poison as immediate UB.
Differential Revision: https://reviews.llvm.org/D112734
show more ...
|
Revision tags: llvmorg-13.0.1-rc1 |
|
#
ae14fae0 |
| 09-Nov-2021 |
Dmitry Makogon <d.makogon@g.nsu.ru> |
[SCEVExpander] Use stable_sort to sort loop Phis in SCEVExpander::replaceCongruentIVs
This is a fix for test failures on expensive checks build caused by db289340c841990055a164e8eb2a3b5ff25677bf.
W
[SCEVExpander] Use stable_sort to sort loop Phis in SCEVExpander::replaceCongruentIVs
This is a fix for test failures on expensive checks build caused by db289340c841990055a164e8eb2a3b5ff25677bf.
With LLVM_ENABLE_EXPENSIVE_CHECKS enabled the llvm::sort shuffles the given container. However, the sort is only called when the TTI is passed to replaceCongruentIVs. In the mentioned patch we pass it TTI, so the sort happens. But due to shuffling equivalent Phis may appear in different order from run to run. With the stable_sort instead of sort this is impossible - the order of sorted Phis is preserved.
show more ...
|
#
156f10c8 |
| 27-Oct-2021 |
Roman Lebedev <lebedev.ri@gmail.com> |
[IR] `SCEVExpander::generateOverflowCheck()`: short-circuit `umul_with_overflow`-by-one
It's a no-op, no overflow happens ever: https://alive2.llvm.org/ce/z/Zw89rZ
While generally i don't like such
[IR] `SCEVExpander::generateOverflowCheck()`: short-circuit `umul_with_overflow`-by-one
It's a no-op, no overflow happens ever: https://alive2.llvm.org/ce/z/Zw89rZ
While generally i don't like such hacks, we have a very good reason to do this: here we are expanding a run-time correctness check for the vectorization, and said `umul_with_overflow` will not be optimized out before we query the cost of the checks we've generated.
Which means, the cost of run-time checks would be artificially inflated, and after https://reviews.llvm.org/D109368 that will affect the minimal trip count for which these checks are even evaluated. And if they aren't even evaluated, then the vectorized code certainly won't be run.
We could consider doing this in IRBuilder, but then we'd need to also teach `CreateExtractValue()` to look into chain of `insertvalue`'s, and i'm not sure there's precedent for that.
Refs. https://reviews.llvm.org/D109368#3089809
show more ...
|
#
11a8423d |
| 26-Oct-2021 |
Nikita Popov <nikita.ppv@gmail.com> |
[SCEV] Use reverse() (NFC)
|
#
3a995c91 |
| 24-Oct-2021 |
Nikita Popov <nikita.ppv@gmail.com> |
[SCEV] Move SCEVLostPoisonFlags() check into SCEVExpander
Always insert values into ExprValueMap, and instead skip using them in SCEVExpander if poison-generating flags have been lost. This ensures
[SCEV] Move SCEVLostPoisonFlags() check into SCEVExpander
Always insert values into ExprValueMap, and instead skip using them in SCEVExpander if poison-generating flags have been lost. This ensures that all values that are in ValueExprMap are also in ExprValueMap, so we can use the latter to invalidate the former.
This change is probably not entirely NFC for the case where originally the SCEV had no nowrap flags but they were inferred later, in which case that would now allow reusing the existing value for expansion.
Differential Revision: https://reviews.llvm.org/D112389
show more ...
|
#
477551fd |
| 25-Oct-2021 |
Nikita Popov <nikita.ppv@gmail.com> |
[SCEVExpander] Minor cleanup in value reuse (NFC)
Use dyn_cast_or_null and convert one of the checks into an assertion. SCEV is a per-function analysis.
|
#
69853f99 |
| 12-Oct-2021 |
Nikita Popov <nikita.ppv@gmail.com> |
[IVUsers] Move preheader check into SCEVExpander
Rather than checking for loop nest preheaders upfront in IVUsers, move this requirement into isSafeToExpand() from SCEVExpander.
Historically, LSR d
[IVUsers] Move preheader check into SCEVExpander
Rather than checking for loop nest preheaders upfront in IVUsers, move this requirement into isSafeToExpand() from SCEVExpander.
Historically, LSR did not check whether SCEVs are safe to expand and fully relied on IVUsers to validate this. Later, support for non-expandable SCEVs was added via rigid formulas.
Checking this in isSafeToExpand() makes it more obvious what exactly this check is guarding against, and avoids the awkward loop nest scan.
This is a followup to https://reviews.llvm.org/D111493#3055286.
Differential Revision: https://reviews.llvm.org/D111681
show more ...
|
Revision tags: llvmorg-13.0.0, llvmorg-13.0.0-rc4, llvmorg-13.0.0-rc3 |
|
#
735f4671 |
| 09-Sep-2021 |
Chris Lattner <clattner@nondot.org> |
[APInt] Normalize naming on keep constructors / predicate methods.
This renames the primary methods for creating a zero value to `getZero` instead of `getNullValue` and renames predicates like `isAl
[APInt] Normalize naming on keep constructors / predicate methods.
This renames the primary methods for creating a zero value to `getZero` instead of `getNullValue` and renames predicates like `isAllOnesValue` to simply `isAllOnes`. This achieves two things:
1) This starts standardizing predicates across the LLVM codebase, following (in this case) ConstantInt. The word "Value" doesn't convey anything of merit, and is missing in some of the other things.
2) Calling an integer "null" doesn't make any sense. The original sin here is mine and I've regretted it for years. This moves us to calling it "zero" instead, which is correct!
APInt is widely used and I don't think anyone is keen to take massive source breakage on anything so core, at least not all in one go. As such, this doesn't actually delete any entrypoints, it "soft deprecates" them with a comment.
Included in this patch are changes to a bunch of the codebase, but there are more. We should normalize SelectionDAG and other APIs as well, which would make the API change more mechanical.
Differential Revision: https://reviews.llvm.org/D109483
show more ...
|
#
c86e1ce7 |
| 01-Sep-2021 |
Nikita Popov <nikita.ppv@gmail.com> |
[SCEVExpander] Simplify pointer overflow check
This is a followup to D104662 to generate slightly nicer code for pointer overflow checks. Bypass expandAddToGEP and instead explicitly generate i8 GEP
[SCEVExpander] Simplify pointer overflow check
This is a followup to D104662 to generate slightly nicer code for pointer overflow checks. Bypass expandAddToGEP and instead explicitly generate i8 GEPs. This saves some bitcasts and negates the value in a more obvious way. In particular, this prevents SCEV from looking through the umul.with.overflow, same as in the integer case.
The wrapping-pointer-ni.ll test deserves a comment: Previously, this generated a typed GEP which used the umulo argument rather than the multiplication result. This results in more compact IR in that case, but effectively does the multiplication twice, the second one is just hidden in the GEP. Reusing the umulo result seems pretty reasonable to me.
Differential Revision: https://reviews.llvm.org/D109093
show more ...
|
#
e735f2bf |
| 01-Sep-2021 |
Philip Reames <listmail@philipreames.com> |
[SCEVExpander] Prefer pointer expansion for overflow checks
We'd special cased this logic to use pointer types for non-integral pointers, but there's no reason we can't do that for all pointer types
[SCEVExpander] Prefer pointer expansion for overflow checks
We'd special cased this logic to use pointer types for non-integral pointers, but there's no reason we can't do that for all pointer types. Doing it this was has a few advantages: a) The code itself becomes more straight forward, and easier to test. b) We avoid introducing ptrtoint into programs which didn't have them in the source. c) The resulting codegen is easier to analyze and simplify (mostly due to lack of ptrtoint).
Note that there are some test diffs, but a) running them through instcombine helps a ton, and b) there's enough missing obvious transforms on both before and after IR that it's clear this isn't performance sensitive.
This is mostly motivated by cleaning up mentions of non-integrals to have a clearer idea of what we actually need to support.
Differential Revision: https://reviews.llvm.org/D104662
show more ...
|
#
9f787378 |
| 29-Aug-2021 |
Nikita Popov <nikita.ppv@gmail.com> |
[SCEVExpander] Reuse removePointerBase() for canonical addrecs
ExposePointerBase() in SCEVExpander implements basically the same functionality as removePointerBase() in SCEV, so reuse it.
The SCEVE
[SCEVExpander] Reuse removePointerBase() for canonical addrecs
ExposePointerBase() in SCEVExpander implements basically the same functionality as removePointerBase() in SCEV, so reuse it.
The SCEVExpander code assumes that the pointer operand on adds is the last one -- I'm not sure that always holds. As such this might not be strictly NFC.
show more ...
|