28958 Commits

Author SHA1 Message Date
Arthur Eubanks
71497cc7a4
[CGSCC] Fix compile time blowup with large RefSCCs (#94815)
In some modules, e.g. Kotlin-generated IR, we end up with a huge RefSCC
and the call graph updates done as a result of the inliner take a long
time. This is due to RefSCC::removeInternalRefEdges() getting called
many times, each time removing one function from the RefSCC, but each
call to removeInternalRefEdges() is proportional to the size of the
RefSCC.

There are two places that call removeInternalRefEdges(), in
updateCGAndAnalysisManagerForPass() and
LazyCallGraph::removeDeadFunction().

1) Since LazyCallGraph can deal with spurious (edges that exist in the
graph but not in the IR) ref edges, we can simply not call
removeInternalRefEdges() in updateCGAndAnalysisManagerForPass().

2) LazyCallGraph::removeDeadFunction() still ends up taking the brunt of
compile time with the above change for the original reason. So instead
we batch all the dead function removals so we can call
removeInternalRefEdges() just once. This requires some changes to
callers of removeDeadFunction() to not actually erase the function from
the module, but defer it to when we batch delete dead functions at the
end of the CGSCC run, leaving the function body as "unreachable" in the
meantime. We still need to ensure that call edges are accurate. I had
also tried deleting dead functions after visiting a RefSCC, but deleting
them all at once at the end was simpler.

Many test changes are due to not performing unnecessary revisits of an
SCC (the CGSCC infrastructure deems ref edge refinements as unimportant
when it comes to revisiting SCCs, although that seems to not be
consistently true given these changes) because we don't remove some ref
edges. Specifically for devirt-invalidated.ll this seems to expose an
inlining order issue with the inliner. Probably unimportant for this
type of intentionally weird call graph.

Compile time:
https://llvm-compile-time-tracker.com/compare.php?from=6f2c61071c274a1b5e212e6ad4114641ec7c7fc3&to=b08c90d05e290dd065755ea776ceaf1420680224&stat=instructions:u
2024-06-11 09:50:13 -07:00
Nikita Popov
da5f45f593 [ConstantFolding] Preserve nowrap flags in gep of gep fold
A caveat here is that we can only preserve nusw if the offset
additions did not overflow.

Proofs: https://alive2.llvm.org/ce/z/u56z_u
2024-06-11 15:03:10 +02:00
Matt Arsenault
a2bc50aa8b AMDGPU: Add more tests for vector typed atomicrmw fadd
Some cases should be legal for gfx940.
2024-06-11 14:44:28 +02:00
Simon Pilgrim
264bcbe1c8 [InstCombine] Add #38139 test coverage 2024-06-11 12:35:49 +01:00
c8ef
e5bdb7af86
[InstCombine] fold ldexp(x, sext(i1 y)) to fmul x, (select y, 0.5, 1.0) (#95073)
Follow up of #94887.

Context:
https://github.com/llvm/llvm-project/pull/94887#pullrequestreview-2106213891
2024-06-11 11:42:19 +02:00
Paul Kirth
607afa0b63
Revert "[llvm][IR] Extend BranchWeightMetadata to track provenance of weights" (#95060)
Reverts llvm/llvm-project#86609

This change causes compile-time regressions for stage2 builds
(https://llvm-compile-time-tracker.com/compare.php?from=3254f31a66263ea9647c9547f1531c3123444fcd&to=c5978f1eb5eeca8610b9dfce1fcbf1f473911cd8&stat=instructions:u).
It also introduced unintended changes to `.text` which should be
addressed before relanding.
2024-06-11 08:06:06 +02:00
Min-Yih Hsu
1fe4f2d1a4
[Inliner][test] Fix incorrect REQUIRE line in inline-switch-default.ll (NFC) (#95009)
It should be `x86-registered-target` because we only need the X86 target
in this case. `x86_64-linux` will be too strict here as it puts a
prerequisite on the default target triple.
2024-06-10 15:32:35 -07:00
Vitaly Buka
d3c0ed387c
[NFCI][metadata][LibCallsShrinkWrap] Use create{Unlikely,Likely}BranchWeights (#89465)
It does not look like 2000 is needed here in particular.

Follow up to #89464
2024-06-10 13:13:08 -07:00
Paul Kirth
c5978f1eb5
[llvm][IR] Extend BranchWeightMetadata to track provenance of weights (#86609)
This patch implements the changes to LLVM IR discussed in

https://discourse.llvm.org/t/rfc-update-branch-weights-metadata-to-allow-tracking-branch-weight-origins/75032

In this patch, we add an optional field to MD_prof metadata nodes for
branch weights, which can be used to distinguish weights added from
`llvm.expect*` intrinsics from those added via other methods, e.g.
from profiles or inserted by the compiler.

One of the major motivations, is for use with MisExpect diagnostics,
which need to know if branch_weight metadata originates from an
llvm.expect intrinsic. Without that information, we end up checking
branch weights multiple times in the case if ThinLTO + SampleProfiling,
leading to some inaccuracy in how we report MisExpect related
diagnostics to users.

Since we change the format of MD_prof metadata in a fundamental way, we
need to update code handling branch weights in a number of places.

We also update the lang ref for branch weights to reflect the change.
2024-06-10 11:27:21 -07:00
Noah Goldstein
77f75b45fd [InstCombine] Extend (icmp eq/ne (and Z, X), (and Z, Y)) folds
Two ways to relaxed:
    1) Only require one of the `and` ops to be single-use if both `X`
       and `Y` are constant.
    2) Special case, if `X ^ Y` is a negative power of 2, then
       `Z ^ NegP2 ==/!= 0` will fold to `Z u</u>= -NegP2` which
       creates no additional instructions so fold irrelivant of
       use counts.

Closes #94867
2024-06-10 13:00:28 -05:00
Noah Goldstein
4ac158e04c [InstCombine] Add tests for combining (icmp eq/ne (and X, P2), (and X, -P2)); NFC 2024-06-10 13:00:28 -05:00
Simon Pilgrim
0c97ac0a46 [InstCombine] Regenerate some old bool math tests to use FileCheck and UTC scripts
Don't use %a and %A in the same test as FileCheck doesn't like it.
2024-06-10 17:59:25 +01:00
Matt Arsenault
8788b666aa
SimplifyLibCalls: Don't require ldexp to emit intrinsic in exp2 combine (#92707)
When folding exp2(itofp(x)) to ldexp(1, x), don't require an ldexp
libcall to emit the intrinsic.

The intrinsic needs to be handled regardless of whether the system has a
libcall, and we have an inline implementation of ldexp already. This
fixes the instance in the exp2->ldexp fold. Another instance exists for
the pow(2) -> ldexp case

The LTO test change isn't ideal, since it's just moving the problem to
another instance where we're relying on implied libm behavior for an
intrinsic transform. Use exp10 since that's a harder case to solve in
the libcall house of cards we have.
2024-06-10 18:21:20 +02:00
c8ef
f26bc5f0c4
[InstCombine] fold ldexp(x, zext(i1 y)) to fmul x, (select y, 2.0, 1.0) (#94887)
close: #92538
2024-06-10 16:40:37 +02:00
Florian Hahn
2e4c06780c
[LV] Add extra X86 cost tests for any_of reduction and multi-exit loops.
Add extra test coverage to ensure decisions do not change when
transitioning to a VPlan-based cost model.
2024-06-10 13:13:04 +01:00
Jay Foad
18ec885a26
[RFC][AMDGPU] Remove old llvm.amdgcn.buffer.* and tbuffer intrinsics (#93801)
They have been superseded by llvm.amdgcn.raw.buffer.* and
llvm.amdgcn.struct.buffer.*.
2024-06-10 12:14:51 +01:00
Nikita Popov
cc158d4c0b Reapply [ConstantFold] Remove non-trivial gep-of-gep fold (#93823)
Reapply after https://github.com/llvm/llvm-project/pull/93956, which
changed clang array initialization codegen to avoid size regressions
for unoptimized builds.

-----

This fold is subtly incorrect, because DL-unaware constant folding does
not know the correct index type to use, and just performs the addition
in the type that happens to already be there. This is incorrect, since
sext(X)+sext(Y) is generally not the same as sext(X+Y). See the
`@constexpr_gep_of_gep_with_narrow_type()` for a miscompile with the
current implementation.

One could try to restrict the fold to cases where no overflow occurs,
but I'm not bothering with that here, because the DL-aware constant
folding will take care of this anyway. I've only kept the
straightforward zero-index case, where we just concatenate two GEPs.
2024-06-10 10:12:55 +02:00
Yingwei Zheng
e4b0655b29
[InstCombine] Fix missing argument typo in InstCombinerImpl::foldICmpShlConstant (#94899)
Closes #94897.
2024-06-10 03:17:01 +08:00
Florian Hahn
2f4ebf8545
[VPlan] Handle more cases in VPInstruction::onlyFirstPartUsed.
Handle binary ops and a few other instructions in onlyFirstPartUsed;
they only use the first part if they themselves only have their first
part used.
2024-06-09 13:19:44 +01:00
Noah Goldstein
2900d035f4 [InstCombine] Propagate flags when folding consecutative shifts
When we fold `(shift (shift C0, x), C1)` we can propagate flags that
are common to both shifts.

Proofs: https://alive2.llvm.org/ce/z/LkEzXD

Closes #94872
2024-06-08 16:46:45 -05:00
Noah Goldstein
c2d68c42a4 [InstCombine] Add tests for propagating flags when folding consecutative shifts; NFC 2024-06-08 16:46:45 -05:00
Florian Hahn
998c33e5fc
[VPlan] Mark FirstOrderRecurrenceSplice as not having side-effects.
Now that FOR exit and resume value creation is explicitly modeled in
VPlan (05e1b5340b0caf1, 07b330132c0b) it doesn't depend on the first
order recurrence splice being preserved and it can now be marked as not
having side-effects. This allows removal of first-order-recurrence-splce
if the FOR is only used in the exit or as scalar ph resume value.
2024-06-08 21:40:30 +01:00
Florian Hahn
a43d999d14
[VPlan] Check if only first part is used for all per-part VPInsts.
Apply the onlyFirstPartUsed logic generally to all per-part
VPInstructions. Note that the test changes remove the second part
of an unsued first-order recurrence splice.
2024-06-08 20:31:54 +01:00
Yingwei Zheng
645fb04a33
[Reassociate] Use uint64_t for repeat count (#94232)
This patch relands #91469 and uses `uint64_t` for repeat count to avoid
a miscompilation caused by overflow
https://github.com/llvm/llvm-project/pull/91469#discussion_r1623925158.
2024-06-08 22:28:56 +08:00
DaPorkchop_
540f68c44f
[SimplifyCFG] Don't use a mask for lookup tables generated from switches with an unreachable default case (#94468)
When transforming a switch with holes into a lookup table, we currently
use a mask to check if the current index is handled by the switch or if
it is a hole. If it is a hole, we skip loading from the lookup table.
Normally, if the switch's default case is unreachable this has no
impact, as the mask test gets optimized away by subsequent passes.
However, if the switch is large enough that the number of lookup table
entries exceeds the target's register width, we won't be able to fit all
the cases into a mask and the switch won't get transformed into a lookup
table. If we know that the switch's default case is unreachable, we know
that the mask is unnecessary and can skip constructing it entirely,
which allows us to transform the switch into a lookup table.

[Example](https://godbolt.org/z/7x7qfx8M1)

In the future, it might be interesting to consider allowing lookup table
masks to be more than one register large (e.g. using a constant array of
bit flags, similar to `std::bitset`).
2024-06-08 21:32:34 +08:00
csstormq
96af114941
[InstCombine] Preserve the nsw/nuw flags for (X | Op01C) + Op1C --> X + (Op01C + Op1C) (#94586)
This patch simplifies `sdiv` to `udiv` by preserving the `nsw` flag for
`(X | Op01C) + Op1C --> X + (Op01C + Op1C)` if the sum of `Op01C` and
`Op1C` will not overflow, and preserves the `nuw` flag unconditionally.

Alive2 Proofs (provided by @nikic): https://alive2.llvm.org/ce/z/nrdCZT,
https://alive2.llvm.org/ce/z/YnJHnH
2024-06-08 08:38:27 +08:00
Teresa Johnson
7536474ea7
[MemProf] Add matching statistics and tracing (#94814)
To help debug or surface matching issues, add more statistics to the
matching. Also add optional emission of each context seen in the
function profiles along with its allocation type, size in bytes, and
whether it was matched. This information is emitted along with a hash of
the full stack context, to allow deduplication across modules for
allocations within header files.
2024-06-07 16:26:41 -07:00
David Green
d1b5a4b0c5 [VectorCombine] Add tests for shuffleToIdentity of concats. NFC 2024-06-07 22:28:00 +01:00
Min-Yih Hsu
37e309f163
[AArch64][LoopIdiom] Generalize AArch64LoopIdiomTransform into LoopIdiomVectorize (#94081)
To facilitate sharing LoopIdiomTransform between AArch64 and RISC-V,
this first patch moves AArch64LoopIdiomTransform from lib/Target/AArch64
to lib/Transforms/Vectorize and renames it to LoopIdiomVectorize. The
following patch (#94082) will teach LoopIdiomVectorize how to generate VP
intrinsics (in addition to the current masked vector style) in favor of
RVV.
2024-06-07 14:06:11 -07:00
Matt Arsenault
75b89cc00c
InstCombine: Fix testing of pow libcall in errno case (#94772)
There were some tests in this file with "noerrno" in the name, but all
the tests were no errno since all the libcalls were declared with
memory(none). Ensure we have adequate coverage for the errno and
no-errno cases by duplicating the libcall transform cases into errno and
non-errno versions with callsite attributes.
2024-06-07 22:37:49 +02:00
Noah Goldstein
166c1849d6 [InstCombine] Fold (icmp eq/ne (xor x, y), C1) even if multiuse
Two folds unlocked:
    `(icmp eq/ne (xor x, C0), C1)` -> `(icmp eq/ne x, C2)`
    `(icmp eq/ne (xor x, y), 0)` -> `(icmp eq/ne x, y)`

This fixes regressions assosiated with #87180

Closes #87275
2024-06-07 15:06:41 -05:00
Noah Goldstein
27084f73e3 [InstCombine] Add tests for folding (icmp eq/ne (xor x, C0), C1); NFC 2024-06-07 15:06:40 -05:00
Lei Wang
e20b904721
[PseudoProbe] Make probe discriminator compatible with dwarf base discriminator (#94506)
It's useful if the probe-based build can consume a dwarf based
profile(e.g. the profile transition), before there is a conflict for the
discriminator, this change tries to mitigate the issue by encoding the
dwarf base discriminator into the probe discriminator.
As the num of probe id(num of basic block and calls) starts from 1,
there are some unused space. We try to reuse some bit of the probe id.
The new encode rule is:
- Use a bit to [28:28] to indicate whether dwarf base discriminator is
encoded.(fortunately we can borrow this bit from the `PseudoProbeType`)
- If the bit is set, use [15:3] for probe id, [18:16] for dwarf base
discriminator. Otherwise, still use [18:3] for probe id.

Note that these doesn't affect the original probe id capacity, we still
prioritize probe id encoding, i.e. the base discriminator is not encoded
when probe id is bigger than [15:3].
 
Then adjust `getBaseDiscriminatorFromDiscriminator` to use the base
discriminator from the probe discriminator.
2024-06-07 11:37:49 -07:00
Simon Pilgrim
97b12df2cc [Reassociate] shifttest.ll - generate test checks to replace custom grep expression
(and remove an unused argument)
2024-06-07 16:33:52 +01:00
Florian Hahn
4f9c0fa223
[LV] Add test with dead load and vector pointer. 2024-06-07 16:14:02 +01:00
Farzon Lotfi
2f0308ed02
[arm64] Add tan intrinsic lowering (#94545)
This change is an implementation of
https://github.com/llvm/llvm-project/issues/87367's investigation on
supporting IEEE math operations as intrinsics.
Which was discussed in this RFC:
https://discourse.llvm.org/t/rfc-all-the-math-intrinsics/78294

This PR is just for Tan.

Now that x86 tan backend landed:
https://github.com/llvm/llvm-project/pull/90503 we can add other
backends since the shared pieces are in tree now.

Changes:
- `llvm/include/llvm/Analysis/VecFuncs.def` - vectorization of tan for
arm64 backends.
- `llvm/lib/Target/AArch64/AArch64FastISel.cpp` - Add tan to the libcall
table
- `llvm/lib/Target/AArch64/AArch64ISelLowering.cpp` - Add tan expansion
for f128, f16, and vector\neon operations
- `llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp` define
`G_FTAN` as a legal arm64 instruction

resolves #94755
2024-06-07 09:42:06 -04:00
Nikita Popov
8719cb88e3 [SimplifyCFG] Regenerate switch to lookup tests (NFC)
Regenerate these with --check-globals. The manual global CHECKS
get dropped during regeneration otherwise.

Annoyingly UTC insists on putting the globals directly before the
first function, so the first comment is a bit out of place now.
2024-06-07 11:51:51 +02:00
Nikita Popov
1934c1aa36 [SimplifyCFG] Remove bogus UTC line from test (NFC)
The check lines in this test were clearly not generated by UTC.
2024-06-07 11:51:51 +02:00
Noah Goldstein
7e7c29ba08 [InstCombine] Improve coverage of foldSelectValueEquivalence for constants
We don't need the `noundef` check if the new simplification is a
constant.

This cleans up regressions from folding multiuse:
    `(icmp eq/ne (sub/xor x, y), 0)` -> `(icmp eq/ne x, y)`.

Closes #88298
2024-06-06 20:02:57 -05:00
Noah Goldstein
59003d714a [InstCombine] Add tests for expanding foldSelectValueEquivalence; NFC 2024-06-06 20:02:57 -05:00
Noah Goldstein
3716a3c1bc [InstCombine] Folding multiuse (icmp eq/ne (or X, Y), Y) for 2 uses of Y
The fold will replace 2 uses of `Y` we should also do fold if `Y` has
2 uses (not only oneuse).

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D159062
2024-06-06 12:42:07 -05:00
Noah Goldstein
7cfad77a5e [InstCombine] Add tests for folding multiuse (icmp eq/ne (or X, Y), Y); NFC 2024-06-06 12:42:07 -05:00
Florian Hahn
b7b8d02896
[ConstraintElim] Add induction tests with different start values.
Extra tests for https://github.com/llvm/llvm-project/pull/94610.
2024-06-06 15:33:24 +01:00
Graham Hunter
e16f2f5d24
[AArch64] Override isLSRCostLess, take number of instructions into account (#84189)
Adds an AArch64-specific version of isLSRCostLess, changing the relative
importance of the various terms from the formulae being evaluated.

This has been split out from my vscale-aware LSR work, see the RFC for
reference:
https://discourse.llvm.org/t/rfc-vscale-aware-loopstrengthreduce/77131
2024-06-06 14:45:36 +01:00
Florian Hahn
41d73504c9
[ConstraintElim] Add set of tests where a loop iv is used in exit.
Test cases inspired by
https://github.com/llvm/llvm-project/issues/90417.
2024-06-06 13:43:55 +01:00
Jon Chesterfield
8516f54e6a
[AMDGPU] Implement variadic functions by IR lowering (#93362)
This is a mostly-target-independent variadic function optimisation and
lowering pass. It is only enabled for AMDGPU in this initial commit.

The purpose is to make C style variadic functions a zero cost
abstraction. They are lowered to equivalent IR which is then amenable to
other optimisations. This is inherently slightly target specific but
much less so than one might expect - the C varargs interface heavily
constrains the ABI design divergence.

The pass is primarily tested from webassembly. This is because wasm has
a straightforward variadic lowering strategy which coincides exactly
with what this pass transforms code into and a struct passing convention
with few cases to check. Adding further targets conventions is
straightforward and elided from this patch primarily to simplify the
review. Implemented in other branches are Linux X86, AMD64, AArch64 and
NVPTX.

Testing for targets that have existing lowering for va_arg from clang is
most efficiently done by checking that clang | opt completely elides the
variadic syntax from test cases. The lowering produces a struct for each
call site which can be inspected to check the various alignment and
indirections are correct.

AMDGPU presently has no variadic support other than some ad hoc printf
handling. Combined with the pass being inactive on all other targets
landing this represents strict increase in capability with zero risk.
Testing and refining will continue post commit.

In addition to the compiler tests included here, a self contained x64
clang/musl toolchain was constructed using the "lowering" instead of the
systemv ABI and used to build various C programs like lua and libxml2.
2024-06-06 10:44:53 +01:00
Noah Goldstein
c3c443bb41 [InstCombine] Add transforms (icmp spred (and X, Y), X) if X or Y are known signed/unsigned
Several transforms:
    1) If known `Y < 0`:
        - slt -> ult: https://alive2.llvm.org/ce/z/9zt2iK
        - sle -> ule: https://alive2.llvm.org/ce/z/SPoPNF
        - sgt -> ugt: https://alive2.llvm.org/ce/z/IGNxAk
        - sge -> uge: https://alive2.llvm.org/ce/z/joqTvR
    2) If known `Y >= 0`:
        - `(X & PosY) s> X --> X s< 0`
            - https://alive2.llvm.org/ce/z/7e-5BQ
        - `(X & PosY) s> X --> X s< 0`
            - https://alive2.llvm.org/ce/z/jvT4Gb
    3) If known `X < 0`:
        - `(NegX & Y) s> NegX --> Y s>= 0`
            - https://alive2.llvm.org/ce/z/ApkaEh
        - `(NegX & Y) s<= NegX --> Y s< 0`
            - https://alive2.llvm.org/ce/z/oRnfHp

Closes #94417
2024-06-06 03:05:41 -05:00
Sameer Sahasrabuddhe
e0ac087ff0
[LoopUnroll] Consider convergence control tokens when unrolling (#91715)
- There is no restriction on a loop with controlled convergent
operations when
  the relevant tokens are defined and used within the loop.

- When a token defined outside a loop is used inside (also called a loop
convergence heart), unrolling is allowed only in the absence of
remainder or
  runtime checks.

- When a token defined inside a loop is used outside, such a loop is
said to be
"extended". This loop can only be unrolled by also duplicating the
extended part
  lying outside the loop. Such unrolling is disabled for now.

- Clean up loop hearts: When unrolling a loop with a heart, duplicating
the
heart will introduce multiple static uses of a convergence control token
in a
cycle that does not contain its definition. This violates the static
rules for
tokens, and needs to be cleaned up into a single occurrence of the
intrinsic.

- Spell out the initializer for UnrollLoopOptions to improve
readability.


Original implementation [D85605] by Nicolai Haehnle
<nicolai.haehnle@amd.com>.
2024-06-06 13:13:46 +05:30
Nikita Popov
16e2ec82ac [ValueTracking] Make undef element check more precise
If we're only checking for undef, then also only look for undef
elements in the vector (rather than undef and poison).
2024-06-06 09:39:33 +02:00
Nikita Popov
9bea770b63 [InstCombine] Only requite not-undef in select equiv fold
As the comment already indicates, only replacement with undef
is problematic, as it introduces an additional use of undef.
Use the correct ValueTracking helper.
2024-06-06 09:38:08 +02:00