Commit Graph

12135 Commits

Author SHA1 Message Date
Ben Mudd
1f11d1bd12 [DebugInfo] Fix jump threading failing to update cloned dbg.values
This is a patch to fix duplicated dbg.values in the JumpThreading pass not
pointing towards their local value, and instead towards the variable in the
original block.
JumpThreadingPass::cloneInstructions is the changed function to target metadata
as well as normal cloned values.

Reviewed By: jmorse, StephenTozer

Differential Revision: https://reviews.llvm.org/D140006
2023-01-09 11:42:33 +00:00
Max Kazantsev
957952dbf2 [JumpThreading] Preserve profile metadata during select unfolding
Jump threading can replace select and unconditional branch with
conditional branch, but when doing so loses profile information.

This destructive transform can eventually lead to a performance
degradation due to folding of branches in
shouldFoldCondBranchesToCommonDestination as branch probabilities
are no longer known.

Patch by Roman Paukner!

Differential Revision: https://reviews.llvm.org/D138132
Reviewed By: mkazantsev
2023-01-09 16:14:58 +07:00
Max Kazantsev
ba7af0bf69 [NFC] Add missing 'static' notion in createReplacement 2023-01-09 14:13:05 +07:00
Benjamin Kramer
b6942a2880 [NFC] Hide implementation details in anonymous namespaces 2023-01-08 17:37:02 +01:00
Nikita Popov
c60149b49e Revert "[Dominator] Add findNearestCommonDominator() for Instructions (NFC)"
This reverts commit 7f0de9573f.

This is missing handling for !isReachableFromEntry() blocks, which
may be relevant for some callers. Revert for now.
2023-01-06 17:36:01 +01:00
Nikita Popov
7f0de9573f [Dominator] Add findNearestCommonDominator() for Instructions (NFC)
This is a recurring pattern: We want to find the nearest common
dominator (instruction) for two instructions, but currently only
provide an API for the nearest common dominator of two basic blocks.

Add an overload that accepts and return instructions.
2023-01-06 17:06:25 +01:00
David Green
161bfa5f53 [LoopFlattening] Check for extra uses on Mul
Similar to D138404, we were not guarding against extra uses of the Mul.
In most cases other checks would catch the issue due to unsupported
instructions in the outer loop, but certain non-canonical loop forms
could still get through.

Fixes #59339

Differential Revision: https://reviews.llvm.org/D141114
2023-01-06 15:32:38 +00:00
Nikita Popov
07bf39df80 [MemCpyOpt] Extract processStoreOfLoad() method (NFC) 2023-01-06 16:11:10 +01:00
Nikita Popov
a6a526ec54 [IR] Add AllocaInst::getAllocationSize() (NFC)
When fetching allocation sizes, we almost always want to have the
size in bytes, but we were only providing an InBits API. Also add
the corresponding byte-based conjugate to save some *8 and /8
juggling everywhere.
2023-01-06 15:36:16 +01:00
OCHyams
042107494d [DebugInfo][NFC] Rename is/setUndef to is/setKilllocation
These names better reflect the semantics and also the implementation, since
it's not just "undef" operands that are sentinels used to signal that the debug
intrinsic terminates dominating locations definitions.

Related to https://discourse.llvm.org/t/auto-undef-debug-uses-of-a-deleted-value

Reviewed By: StephenTozer

Differential Revision: https://reviews.llvm.org/D140903
2023-01-06 09:15:02 +00:00
serge-sans-paille
38818b60c5 Move from llvm::makeArrayRef to ArrayRef deduction guides - llvm/ part
Use deduction guides instead of helper functions.

The only non-automatic changes have been:

1. ArrayRef(some_uint8_pointer, 0) needs to be changed into ArrayRef(some_uint8_pointer, (size_t)0) to avoid an ambiguous call with ArrayRef((uint8_t*), (uint8_t*))
2. CVSymbol sym(makeArrayRef(symStorage)); needed to be rewritten as CVSymbol sym{ArrayRef(symStorage)}; otherwise the compiler is confused and thinks we have a (bad) function prototype. There was a few similar situation across the codebase.
3. ADL doesn't seem to work the same for deduction-guides and functions, so at some point the llvm namespace must be explicitly stated.
4. The "reference mode" of makeArrayRef(ArrayRef<T> &) that acts as no-op is not supported (a constructor cannot achieve that).

Per reviewers' comment, some useless makeArrayRef have been removed in the process.

This is a follow-up to https://reviews.llvm.org/D140896 that introduced
the deduction guides.

Differential Revision: https://reviews.llvm.org/D140955
2023-01-05 14:11:08 +01:00
Florian Hahn
23ce9383ca [ConstraintElim] Add option to limit number of rows tracked in system.
Once the constraint system grows too large in terms of number of rows,
queries can become very slow. This patch adds a new option to limit the
number of rows tracked.

The python script below can be used to generate worst-case IR with a
chain of conditional branches with N branches.

With this limit, we get the following runtimes:
* python3 generate.py 100:   0.1s
* python3 generate.py 1000:  2s
* python3 generate.py 10000: 4s

Without the limit, the case with 1000 chained conditions takes 20+
seconds.

generate.py:
    import sys

    N = int(sys.argv[1])

    args = []
    checks = []

    for i in range(0, N):
        args.append('i32 %l{}'.format(i))
        checks.append("""
    bb{0}:
      %c{0} = icmp uge i32 %l{0}, 100
      br i1 %c{0}, label %bb{1}, label %exit
    """.format(i, i+1))

    print("""
    define i1 @foo({0}) {{
    {1}

    bb{2}:
      %c{2} = icmp uge i32 %l0, 100
      ret i1 %c{2}

    exit:
      ret i1 false
    }}
    """.format(' ,'.join(args), '\n'.join(checks), N))

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D140926
2023-01-04 13:59:23 +00:00
Florian Hahn
f8d008d19f [ConstraintElim] Remove legacy pass implementation.
The pass is exclusively used with the new pass manager now, so remove
the legacy PM implementation.
2023-01-04 11:21:12 +00:00
luxufan
aca7441c7a [LoopFusion] Exit early if one of fusion candidate has guarded branch but the another has not
Fixes: https://github.com/llvm/llvm-project/issues/59024

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D138269
2023-01-03 23:18:58 +08:00
luxufan
5b25a0bcb1 [CVP] Simplify SRem when constantrange abs(lhs) < abs(rhs)
For `srem x, y`, if abs(constant range of x) less than abs(constant
range of y), we can simplify it as:
`srem x, y => x` if y is guaranteed to be positive.
'srem x, y => -x' if y is guaranteed to be negative.

Differential Revision: https://reviews.llvm.org/D140405
2023-01-03 22:51:12 +08:00
Nikita Popov
09778940d1 [SimpleLoopUnswitch] Perform poison query before transform
I think this doesn't make any difference right now, but once
we take into account that branch on undef is UB in
programUndefinedIfUndefOrPoison() the new position of the branch
would imply that the condition can't be poison, which would
defeat the purpose of the freeze insertion here. We need to
perform the check before the branch is moved.
2023-01-02 12:25:55 +01:00
Roman Lebedev
08c2f4eb7a [CVP] When expanding urem, always freeze the nominator
As per the post-commit feedback - that was not the correct precondition
to avoid it here. I think we should generally start changing mentality
about `freeze`, the fact that we have been conditioned to be afraid of it
(or of anything in LLVM in general) is the key problem here.
2022-12-31 05:00:43 +03:00
Roman Lebedev
66efb98632 [CVP] Expand bound urems
This kind of thing happens really frequently in LLVM's very own
shuffle combining methods, and it is even considered bad practice
to use `%` there, instead of using this expansion directly.
Though, many of the cases there have variable divisors,
so this won't help everything.

Simple case: https://alive2.llvm.org/ce/z/PjvYf-
There's alternative expansion via `umin`:
https://alive2.llvm.org/ce/z/hWCVPb

BUT while we can transform the first expansion
into the `umin` one (e.g. for SCEV):
https://alive2.llvm.org/ce/z/iNxKmJ
... we can't go in the opposite direction.

Also, the non-`umin` expansion seems somewhat more codegen-friendly:
https://godbolt.org/z/qzjx5bqWK
https://godbolt.org/z/a7bj1axbx

There's second variant of precondition:
https://alive2.llvm.org/ce/z/zE6cbM
but there the numerator must be non-undef / must be frozen.
2022-12-30 19:40:46 +03:00
Roman Lebedev
3cb827f9d3 [NFC][CVP] processURem(): add statistic and increase readability 2022-12-30 19:40:46 +03:00
Owen Anderson
88e85aa580 Handle simple diamond CFG hoisting in DivRemPairs.
Previous we only handled triangle CFGs. This patch expands that
to support diamonds, where the div and rem appear in the then/else
sides of a condition. In that case, we can hoist the div into the
shared predecessor.

This could be generalized further to use nearest common ancestors,
but some of the conditions for hoisting would then require
post-dominator information.

Reviewed By: nikic, lebedev.ri

Differential Revision: https://reviews.llvm.org/D140647
2022-12-28 11:24:18 -07:00
Denis Antrushin
86ed0daae7 [RS4GC] Rematerialize derived pointers before uses.
Introduce an option to rematerialize derived pointers immediately
before their uses instead of after every statepoint. This can be
beneficial when pointer is live across many statepoints but has
few uses.
Initial implementation is simple and rematerializes derived pointer
before every use, even if there are several uses in the same block
or rematerialization instructions can be hoisted etc.
Transformation is considered profitable if we would insert less
instructions than we would insert after every live statepoint.

Depends on D138910, D138911

Reviewed By: anna, skatkov

Differential Revision: https://reviews.llvm.org/D138912
2022-12-27 17:08:57 +03:00
Nikita Popov
cb03470aef Reapply [MergeLoadStoreMotion] Don't require GEP for sinking
Reapply with a fix for a failing debuginfo assignment tracking test.

-----

Allow sinking stores where both operands are the same, don't require
them to have an identical GEP in each block.

This came up when migrating tests to opaque pointers, where
zero-index GEPs are omitted.
2022-12-27 12:49:30 +01:00
Nikita Popov
8bf3116387 Revert "[MergeLoadStoreMotion] Don't require GEP for sinking"
I missed a test failure in the DebugInfo directory.

This reverts commit 2c15b9d9e1.
This reverts commit fb435e1cb5.
2022-12-27 12:38:04 +01:00
Nikita Popov
2c15b9d9e1 [MergeLoadStoreMotion] Don't require GEP for sinking
Allow sinking stores where both operands are the same, don't require
them to have an identical GEP in each block.

This came up when migrating tests to opaque pointers, where
zero-index GEPs are omitted.
2022-12-27 12:17:58 +01:00
Max Kazantsev
df8cedfc3d [IndVars][NFC] Factor out condition creation in optimizeLoopExitWithUnknownExitCount
This is a preparation step to support optimization of conditions that are not immediately ICmp.
2022-12-26 15:00:27 +07:00
Owen Anderson
8256ddf78c Resolve a long-standing FIXME in memcpyopt.
Inspecting the downstream use of the cpyAlign, it is clear that
`performCallSlotOptzn` is expecting it to represent the alignment
of the copy destination, not the minimum of the src and dest
alignments. This patch renames the parameter to make this more
obvious.

I believe this change is NFC, because the downstream code has
alignment checks such that it all works out in the end. I have not
been able to construct a test case that actually triggers a change
in output.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D140603
2022-12-23 16:15:24 -07:00
Zhi Zhuang
b49ee01fe2 [LowerExpectIntrinsic] Propagate branch weights through phi values when ExpectedValue is unlikely in LowerExpectIntrinsic
Update handlePhiDef to consider the probability argument in an expect.with.probability intrinsic when annotating BranchInsts.
In addition, we also disallow non-constant probability arguments in this intrinsic.

Differential Revsion: https://reviews.llvm.org/D140337
2022-12-22 17:33:52 -05:00
Roman Lebedev
2cb393590e Reland "[NFC][SROA] speculateSelectInstLoads(): play nice with typed pointers for now"
This reverts commit bf88ba0f87,
relands 9f27f4536e, but without a bug:
we *REALLY* should not be defaulting to address space 0
when address space is not specified...
2022-12-22 00:47:40 +03:00
Yingchi Long
84733b0f17 [JT] check xor operand is exactly the same in processBranchOnXOR
Reproducer:

    ; RUN: opt -S -jump-threading < %s
    define void @test() {
    entry:
    br i1 false, label %loop, label %exit

    loop:
    %bool = phi i1 [ %xor, %loop.latch ], [ false, %entry ]
    %cmp = icmp eq i16 0, 1
    %xor = xor i1 %cmp, %bool
    br i1 %bool, label %loop.latch, label %exit

    loop.latch:
    %dummy = phi i16 [ 0, %loop ]
    br label %loop

    exit:
    ret void
    }

On this occassion, phi node %bool is actually %xor, and doing substitution causes assertion failure.

Fixes: https://github.com/llvm/llvm-project/issues/58812

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D139783
2022-12-21 21:43:55 +08:00
Max Kazantsev
bf88ba0f87 Revert "[NFC][SROA] speculateSelectInstLoads(): play nice with typed pointers for now"
This reverts commit 9f27f4536e.

Supposed to be NFC, but broke buildbots (test addrspacecast.ll is failing).
2022-12-21 11:21:56 +07:00
Roman Lebedev
9f27f4536e [NFC][SROA] speculateSelectInstLoads(): play nice with typed pointers for now
As requested in https://reviews.llvm.org/D138238#inline-1356685
2022-12-21 05:17:02 +03:00
Joshua Cranmer
e6b02214c6 [IR] Add a target extension type to LLVM.
Target-extension types represent types that need to be preserved through
optimization, but otherwise are not introspectable by target-independent
optimizations. This patch doesn't add any uses of these types by an existing
backend, it only provides basic infrastructure such that these types would work
correctly.

Reviewed By: nikic, barannikov88

Differential Revision: https://reviews.llvm.org/D135202
2022-12-20 11:02:11 -05:00
Sebastian Neubauer
bb7940e25f [llvm] Make llvm::Any similar to std::any
This facilitates replacing llvm::Any with std::any.
- Deprecate any_isa in favor of using any_cast(Any*) and checking for
  nullptr because C++17 has no any_isa.
- Remove the assert from any_cast(Any*), so it returns nullptr if the
  type is not correct. This aligns it with std::any_cast(any*).

Use any_cast(Any*) throughout LLVM instead of checks with any_isa.

This is the first part outlined in
https://discourse.llvm.org/t/rfc-switching-from-llvm-any-to-std-any/67176

Differential Revision: https://reviews.llvm.org/D139973
2022-12-20 13:28:30 +01:00
Nikita Popov
88419a30a0 [LICM] Allow load-only scalar promotion in the presence of aliasing loads
During scalar promotion, if there are additional potentially-aliasing
loads outside the promoted set, we can still perform a load-only
promotion. As the stores are retained, any potentially-aliasing
loads will still read the correct value.

This increases the number of load promotions in llvm-test-suite by
a factor of two:

                                |  Old |  New
    licm.NumPromotionCandidates | 4448 | 6038
    licm.NumLoadPromoted        |  479 | 1069
    licm.NumLoadStorePromoted   | 1459 | 1459

Unfortunately, this does have some impact on compile-time:
http://llvm-compile-time-tracker.com/compare.php?from=57f7f0d6cf0706a88e1ecb74f3d3e8891cceabfa&to=72b811738148aab399966a0435f13b695da1c1c8&stat=instructions
In part this is because we now have less early bailouts from
promotion, but also due to second order effects (e.g. for one case
I looked at we spend more time in SLP now).

Differential Revision: https://reviews.llvm.org/D133192
2022-12-20 10:02:46 +01:00
Anna Thomas
05b060b0b0 [LoopPeel] Expose ValueMap of last peeled iteration. NFC
The value map of last peeled iteration is computed within peelLoop API.
This patch exposes it for callers of peelLoop.
While this is not currently used by upstream passes, we have a usecase
downstream which benefits from this API update. Future users of peelLoop
can also use the ValueMap if needed.

Similar value maps are exposed by other loop utilities such as loop
cloning.

Differential Revision: https://reviews.llvm.org/D138228
2022-12-19 09:55:29 -05:00
Paul Walker
1dee7f9571 [SeparateConstOffsetFromGEP] Remove TypeSize error when collecting constant indices.
Differential Revision: https://reviews.llvm.org/D140229
2022-12-19 14:08:13 +00:00
Florian Hahn
8a3efcd40b [ValueTracking] Consider single poison operands in propgatesPoison.
This patch updates propgatesPoison to take a Use as argument and
propagatesPoison now returns true if the passed in operand causes the
user to yield poison if the operand is poison

This allows propagating poison if the condition of a select is poison.
This helps improve results for programUndefinedIfUndefOrPoison.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D111643
2022-12-19 11:47:51 +00:00
Fangrui Song
51b685734b [Transforms,CodeGen] std::optional::value => operator*/operator->
value() has undesired exception checking semantics and calls
__throw_bad_optional_access in libc++. Moreover, the API is unavailable without
_LIBCPP_NO_EXCEPTIONS on older Mach-O platforms (see
_LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS).
2022-12-16 23:21:27 +00:00
Roman Lebedev
96d3c82645 Revert "[SROA] isVectorPromotionViable(): memory intrinsics operate on vectors of bytes (take 3)"
While the PPC litte-endian miscompile did get addressed
by https://reviews.llvm.org/D140046
the PPV big-endian bots are still unhappy.
https://lab.llvm.org/buildbot/#/builders/93/builds/12560

This reverts commit 7bd358bcb4e358b4351c69e02ef76939e08acdc7.
2022-12-16 22:58:41 +03:00
Roman Lebedev
cfd594f8bb [SROA] isVectorPromotionViable(): memory intrinsics operate on vectors of bytes (take 3)
* This is a recommit of 3c4d2a0396,
* which was reverted in 25f01d593c,
  because it exposed a miscompile in PPC backend,  which was resolved
  in https://reviews.llvm.org/D140089 / cb3f415cd2.
* which was a recommit of cf624b23bc,
* which was reverted in 5cfc22cafe,
  because the cut-off on the number of vector elements was not low enough,
  and it triggered both SDAG SDNode operand number assertions,
  5and caused compile time explosions in some cases.

Let's try with something really *REALLY* conservative first,
just to get somewhere, and try to bump it later.

FIXME: should this respect TTI reg width * num vec regs?

Original commit message:

Now, there's a big caveat here - these bytes
are abstract bytes, not the i8 we have in LLVM,
so strictly speaking this is not exactly legal,
see e.g. https://github.com/AliveToolkit/alive2/issues/860
^ the "bytes" "could" have been a pointer,
and loading it as an integer inserts an implicit ptrtoint.

But at the same time,
InstCombine's `InstCombinerImpl::SimplifyAnyMemTransfer()`
would expand a memtransfer of 1/2/4/8 bytes
into integer-typed load+store,
so this isn't exactly a new problem.

Note that in memory, poison is byte-wise,
so we really can't widen elements,
but SROA seems to be inconsistent here.

Fixes #59116.
2022-12-16 19:27:38 +03:00
Nikita Popov
04d652994d [SCEV] Return ArrayRef for SCEV operands() (NFC)
Use a consistent type for the operands() methods of different SCEV
types. Also make the API consistent by only providing operands(),
rather than also providin op_begin() and op_end() for some of them.
2022-12-16 15:36:19 +01:00
Vasileios Porpodas
32b38d248f [NFC] Rename Instruction::insertAt() to Instruction::insertInto(), to be consistent with BasicBlock::insertInto()
Differential Revision: https://reviews.llvm.org/D140085
2022-12-15 12:27:45 -08:00
Simon Pilgrim
d46f6cd767 [GVN] reportMayClobberedLoad - avoid repeated cast<> calls. NFCI.
Just perform each cast<Instruction> once - we can make OtherAccess a Instruction* type as we only ever assign it from a known LoadInst/StoreInst
2022-12-15 15:44:35 +00:00
Kazu Hirata
6eb0b0a045 Don't include Optional.h
These files no longer use llvm::Optional.
2022-12-14 21:16:22 -08:00
Simon Pilgrim
23e3e107dc [GVN] GVNPass::ValueTable::lookupOrAdd - merge isa<> and cast<> into single dyn_cast<>. NFCI.
Avoid calling separate isa<> and cast<> if we can - dyn_cast<> can more efficiently check for a safe cast and give the casted pointer.
2022-12-14 19:47:57 +00:00
Simon Pilgrim
636089d8dc [GVN] hasUsersIn - merge isa<> and cast<> into single dyn_cast<> and convert for-range loop to any_of() test. NFCI.
Avoid running isa<> and cast<> if we can - dyn_cast<> can more efficiently check for a safe cast and give the casted pointer.
2022-12-14 19:42:42 +00:00
Fangrui Song
d4b6fcb32e [Analysis] llvm::Optional => std::optional 2022-12-14 07:32:24 +00:00
Joshua Cao
5004320590 [LoopFusion] sink second loop PHIs
Fixes https://github.com/llvm/llvm-project/issues/59023

PHI nodes that are in the second loop only have the first loop as its
predecessor. These PHI nodes should be sunk to the end of the fused
loop. If the second loop uses the PHI, then the loops cannot be fused.

I don't think this should happen in typical compilation workflows.
The PHI will be in a dedicated exit block of the first loop following
LCSSA transformations.

Reviewed By: aeubanks

Differential Revision: https://reviews.llvm.org/D139812
2022-12-13 10:13:39 -08:00
OCHyams
f354716b05 Reapply [Assignment Tracking][13/*] Account for assignment tracking in SROA
The Assignment Tracking debug-info feature is outlined in this RFC:

https://discourse.llvm.org/t/
rfc-assignment-tracking-a-better-way-of-specifying-variable-locations-in-ir

Split dbg.assign intrinsics into fragments similarly to what SROA already does
for dbg.declares, except that there's many more intrinsics to split. The
function migrateDebugInfo generates new dbg.assigns intrinsic for each part of
a split store.

Reviewed By: jmorse

Differential Revision: https://reviews.llvm.org/D133296
2022-12-13 12:52:45 +00:00
Joshua Cao
cca01df291 [CVP] Eliminate urem when LHS < RHS
Fol `X % Y -> X` when we can determine `X < Y` based on constant
range information.

Fixes https://github.com/llvm/llvm-project/issues/58408.

Differential Revision: https://reviews.llvm.org/D138360
2022-12-13 11:40:44 +01:00