843 Commits

Author SHA1 Message Date
Jeremy Morse
2fe81edef6 [NFC][RemoveDIs] Insert instruction using iterators in Transforms/
As part of the RemoveDIs project we need LLVM to insert instructions using
iterators wherever possible, so that the iterators can carry a bit of
debug-info. This commit implements some of that by updating the contents of
llvm/lib/Transforms/Utils to always use iterator-versions of instruction
constructors.

There are two general flavours of update:
 * Almost all call-sites just call getIterator on an instruction
 * Several make use of an existing iterator (scenarios where the code is
   actually significant for debug-info)
The underlying logic is that any call to getFirstInsertionPt or similar
APIs that identify the start of a block need to have that iterator passed
directly to the insertion function, without being converted to a bare
Instruction pointer along the way.

Noteworthy changes:
 * FindInsertedValue now takes an optional iterator rather than an
   instruction pointer, as we need to always insert with iterators,
 * I've added a few iterator-taking versions of some value-tracking and
   DomTree methods -- they just unwrap the iterator. These are purely
   convenience methods to avoid extra syntax in some passes.
 * A few calls to getNextNode become std::next instead (to keep in the
   theme of using iterators for positions),
 * SeparateConstOffsetFromGEP has it's insertion-position field changed.
   Noteworthy because it's not a purely localised spelling change.

All this should be NFC.
2024-03-05 15:12:22 +00:00
Kazu Hirata
fc15731183 [Transforms] Use a range-based for loop (NFC) 2024-01-28 18:03:35 -08:00
Kazu Hirata
03dc806b12 [Transforms] Use {DenseMap,SmallPtrSet}::contains (NFC) 2023-12-22 14:51:22 -08:00
Nikita Popov
7f1733a252
[GVN] Fix use-after-free in load PRE with select available value (#69314)
replaceValuesPerBlockEntry() only handled simple and coerced load
values, however the load may also be referenced by a select value.

Additionally, I suspect that the previous code might have been incorrect
if a load had an offset, as it always constructed the AvailableValue
from scratch.

Fixes https://github.com/llvm/llvm-project/issues/69301.
2023-10-19 09:08:59 +02:00
Nikita Popov
fa5884770a [GVN] Always require LoopInfo
GVN behavior depends on LoopInfo in multiple ways, most notably
as a dependency for loop load PRE. As this is not a preserved-only
analysis, using a cached analysis is inappropriate.

In the actual optimization pipeline LoopInfo is always available
at the point GVN runs, but this will ensure it stays this way
even if the pipeline changes.
2023-10-11 11:28:26 +02:00
Jay Foad
b78f3ea7df
Clean up strange uses of getAnalysisIfAvailable (#65729)
After a pass calls addRequired<X>() it is strange to call
getAnalysisIfAvailable<X>() because analysis X should always be
available. Use getAnalysis<X>() instead.
2023-10-11 09:53:00 +01:00
Christian Sigg
c64a098ee4
[GVN] Fix after 46aac949bc
replaceUsersOf -> removeUsersOf
2023-10-05 11:31:35 +02:00
Nikita Popov
46aac949bc [GVN] Remove users from ICF when RAUWing loads
When performing store to load forwarding, replacing users of the
load may turn an indirect call into one with a known callee, in
which case it might become willreturn, invalidating cached ICF
information. Avoid this by removing users.

This is a bit more aggressive than strictly necessary (e.g. this
shouldn't be necessary when doing load-load CSE), but better safe
than sorry.

Fixes https://github.com/llvm/llvm-project/issues/48805.
2023-10-05 11:21:33 +02:00
Nikita Popov
18e77760ce [GVN] Also remove phi nodes from VN table (PR65447)
Followup to D158849: We also need to remove the phi node from the
VN table, which is not handled by removeInstruction().

Fixes https://github.com/llvm/llvm-project/issues/65447.
2023-09-15 11:50:34 +02:00
Nikita Popov
7c229f6e85 [GVN] Invalidate MDA when deduplicating phi nodes
Duplicate phi nodes were being directly removed, without
invalidating MDA. This could result in a new phi node being
allocated at the same address, incorrectly reusing a cache entry.

Fix this by optionally allowing EliminateDuplicatePHINodes() to
collect phi nodes to remove into a vector, which allows GVN to
handle removal itself.

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

Differential Revision: https://reviews.llvm.org/D158849
2023-09-15 07:04:32 +02:00
Sergey Kachkov
4b14148d24
[GVN] Skip debug instructions in findDominatingValue function (#65977)
findDominatingValue has a search limit, and when it is reached, optimization is
not applied. This patch fixes the issue that this limit also takes into account
debug intrinsics, so the result of optimization can depend from the presence of
debug info.
2023-09-13 11:23:26 +03:00
Jeremy Morse
6942c64e81 [NFC][RemoveDIs] Prefer iterator-insertion over instructions
Continuing the patch series to get rid of debug intrinsics [0], instruction
insertion needs to be done with iterators rather than instruction pointers,
so that we can communicate information in the iterator class. This patch
adds an iterator-taking insertBefore method and converts various call sites
to take iterators. These are all sites where such debug-info needs to be
preserved so that a stage2 clang can be built identically; it's likely that
many more will need to be changed in the future.

At this stage, this is just changing the spelling of a few operations,
which will eventually become signifiant once the debug-info bearing
iterator is used.

[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939

Differential Revision: https://reviews.llvm.org/D152537
2023-09-11 11:48:45 +01:00
Nikita Popov
4eafc9b6ff [IR] Treat callbr as special terminator (PR64215)
isLegalToHoistInto() currently return true for callbr instructions.
That means that a callbr with one successor will be considered a
proper loop preheader, which may result in instructions that use
the callbr return value being hoisted past it.

Fix this by adding callbr to isExceptionTerminator (with a rename
to isSpecialTerminator), which also fixes similar assumptions in
other places.

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

Differential Revision: https://reviews.llvm.org/D158609
2023-08-25 09:20:18 +02:00
Nikita Popov
9d2f8ecac8 [MSSAU] Clarify that the defining access does not matter (NFC)
New memory accesses are usually inserted by using one of the
createMemoryAccessXYZ() methods followed by insertUse() or
insertDef(). createMemoryAccessXYZ() accepts a defining access,
however this defining access will always be overwritten by
insertUse() / insertDef().

Update the documentation to clarify this, and stop passing
Definition to createMemoryAccessXYZ() if it's followed by
insertUse/insertDef.

Alternatively, we could also make insertUse / insertDef keep the
defining access if it is specified, and only recompute it if it's
missing.

Differential Revision: https://reviews.llvm.org/D157979
2023-08-16 09:00:32 +02:00
Bjorn Pettersson
fd05c34b18 Stop using legacy helpers indicating typed pointer types. NFC
Since we no longer support typed LLVM IR pointer types, the code can
be simplified into for example using PointerType::get directly instead
of using Type::getInt8PtrTy and Type::getInt32PtrTy etc.

Differential Revision: https://reviews.llvm.org/D156733
2023-08-02 12:08:37 +02:00
Nikita Popov
61e0822efa [llvm][clang] Remove uses of isOpaquePointerTy() (NFC)
This now always returns true (for pointer types).
2023-07-14 10:27:58 +02:00
Nikita Popov
282324aa4a [GVN] Fix verifyRemoved() verification
Fix the verification failure reported in
https://reviews.llvm.org/D141712#4413647. We need to remove the
load from the VN table as well, not just the leader table.

Also make sure that this verification always runs when assertions
are enabled, rather than only when -debug is passed.
2023-06-12 15:14:27 +02:00
David Green
2802739dfd [NFC] Replace ;; with ; 2023-06-11 10:25:24 +01:00
Guozhi Wei
84bcfa0e1b [GVN] Improve PRE on load instructions
This patch implements the enhancement proposed by
https://github.com/llvm/llvm-project/issues/59312.

Suppose we have following code

   v0 = load %addr
   br %LoadBB

LoadBB:
   v1 = load %addr
   ...

PredBB:
   ...
   br %cond, label %LoadBB, label %SuccBB

SuccBB:
   v2 = load %addr
   ...

Instruction v1 in LoadBB is partially redundant, edge (PredBB, LoadBB) is a
critical edge. SuccBB is another successor of PredBB, it contains another load
v2 which is identical to v1. Current GVN splits the critical edge
(PredBB, LoadBB) and inserts a new load in it. A better method is move the load
of v2 into PredBB, then v1 can be changed to a PHI instruction.

If there are two or more similar predecessors, like the test case in the bug
entry, current GVN simply gives up because otherwise it needs to split multiple
critical edges. But we can move all loads in successor blocks into predecessors.

Differential Revision: https://reviews.llvm.org/D141712
2023-06-06 19:45:34 +00:00
Jay Foad
c86a1e6903 [GVN] Do not combine convergent calls in GVN/NewGVN
Note that this is very conservative since it will not even combine
convergent calls that appear in the same basic block, but EarlyCSE will
handle that case.

Differential Revision: https://reviews.llvm.org/D150974
2023-05-19 21:27:35 +01:00
Jay Foad
d933c89534 [GVN] Simplify presplit coroutine handling. NFC. 2023-05-19 15:46:29 +01:00
Jay Foad
b6bf28fae3 [GVN] No else after return. NFC. 2023-05-19 15:07:31 +01:00
Guozhi Wei
a3fbe5f7e6 Revert "[GVN] Improve PRE on load instructions"
This reverts commit d6811826371d82de074d0c3e10040114eee69897.

It caused sanitized bootstrap failure.
2023-05-17 07:38:22 +00:00
Guozhi Wei
d681182637 [GVN] Improve PRE on load instructions
This patch implements the enhancement proposed by
https://github.com/llvm/llvm-project/issues/59312.

Suppose we have following code

     v0 = load %addr
     br %LoadBB

  LoadBB:
     v1 = load %addr
     ...

  PredBB:
     ...
     br %cond, label %LoadBB, label %SuccBB

  SuccBB:
     v2 = load %addr
     ...

Instruction v1 in LoadBB is partially redundant, edge (PredBB, LoadBB) is a
critical edge. SuccBB is another successor of PredBB, it contains another load
v2 which is identical to v1. Current GVN splits the critical edge
(PredBB, LoadBB) and inserts a new load in it. A better method is move the load
of v2 into PredBB, then v1 can be changed to a PHI instruction.

If there are two or more similar predecessors, like the test case in the bug
entry, current GVN simply gives up because otherwise it needs to split multiple
critical edges. But we can move all loads in successor blocks into predecessors.

Differential Revision: https://reviews.llvm.org/D141712
2023-05-17 01:09:01 +00:00
Nikita Popov
20e9b31f88 [GVN] Fix metadata combining for non-local loads
Make MaterializeAdjustedValue() responsible for adjusting load
metadata in all cases, so it also covers the non-local case.

In conjunction with that, we no longer need to call
patchReplacementInstruction() for the local case, which would
unnecessarily drop metadata if the replacement value just happened
to be a load (without actual load CSE).
2023-04-20 12:32:10 +02:00
Nikita Popov
8cdca96690 [GVN] Adjust metadata for coerced load CSE
When reusing a load in a way that requires coercion (i.e. casts or
bit extraction) we currently fail to adjust metadata. Unfortunately,
none of our existing tooling for this is really suitable, because
combineMetadataForCSE() expects both loads to have the same type.
In this case we may work on loads of different types and possibly
offset memory location.

As such, what this patch does is to simply drop all metadata, with
the following exceptions:

* Metadata for which violation is known to always cause UB.
* If the load is !noundef, keep all metadata, as this will turn
  poison-generating metadata into UB as well.

This fixes the miscompile that was exposed by D146629.

Differential Revision: https://reviews.llvm.org/D148129
2023-04-17 12:52:31 +02:00
Nikita Popov
ae28e016d3 [VNCoercion] Drop some redundant functions (NFC)
These load and store APIs now do the same thing, so combine them
into one.
2023-04-12 16:46:54 +02:00
Nikita Popov
6e78fd58cd [GVN][VNCoercion] Remove load widening leftovers (NFCI)
GVN load widening was disabled in D24096. This removes various
support code that is no longer relevant.

The way this works nowadays is that we return PartialAlias with
an offset from BasicAA and this gets passed on as a clobber by
MDA. However, PartialAlias will only be returned if the load is
properly nested inside the other load.

This just removes the bulk of the code, but some additional
cleanup can be done here now that we don't need to distinguish
between load and store cases.
2023-04-12 16:32:46 +02:00
Nikita Popov
e7618a6361 [GVN] Fix change reporting when removing assume (PR61574)
Report a change when removing a true/false assume.

Fixes https://github.com/llvm/llvm-project/issues/61574.
2023-03-22 15:23:31 +01:00
Sergey Kachkov
1aece0e5ed Revert "[GVN] Support address translation through select instructions"
This reverts commit b5bf6f6392a3408be1b7b7e036eb69358c5a2c29.
2023-02-27 12:57:59 +03:00
Sergey Kachkov
b5bf6f6392 [GVN] Support address translation through select instructions
Process cases when phi incoming in predecessor block has select
instruction, and this select address is unavailable, but there
are addresses translated from both sides of select instruction.

Differential Revision: https://reviews.llvm.org/D142705
2023-02-27 12:08:15 +03:00
Liren Peng
529ee9750b [NFC] Use single quotes for single char output during printPipline
Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D144365
2023-02-22 02:35:13 +00:00
Sergey Kachkov
6f9e3f3b33 [NFC] Fix function naming conventions in PHITransAddr methods
Differential Revision: https://reviews.llvm.org/D143166
2023-02-02 16:38:39 +03:00
Guozhi Wei
43969af627 Revert "[GVN] Improve PRE on load instructions"
This reverts commit 5f1448fe1585b5677d5f0064e4eeac3b493d8a18.
2023-02-01 22:48:31 +00:00
Guozhi Wei
3a5777f630 Revert "[GVN] Don't count debug instructions when limit the number of checked instructions"
This reverts commit f494b366ff8a076a72a8e1b7a6f401686d6eb0e6.
2023-02-01 22:48:06 +00:00
Guozhi Wei
f494b366ff [GVN] Don't count debug instructions when limit the number of checked instructions
Don't count debug instructions when limit the number of checked instructions.
Otherwise the debug information may impact optimization like the test case
shows.

Differential Revision: https://reviews.llvm.org/D142787
2023-01-31 21:04:03 +00:00
NAKAMURA Takumi
6595ef0900 GVN.cpp: Suppress a warning in D141712 [-Wunused-variable] 2023-01-26 09:53:59 +09:00
Guozhi Wei
5f1448fe15 [GVN] Improve PRE on load instructions
This patch implements the enhancement proposed by
https://github.com/llvm/llvm-project/issues/59312.

Suppose we have following code

   v0 = load %addr
   br %LoadBB

 LoadBB:
   v1 = load %addr
   ...

 PredBB:
   ...
   br %cond, label %LoadBB, label %SuccBB

 SuccBB:
   v2 = load %addr
   ...

Instruction v1 in LoadBB is partially redundant, edge (PredBB, LoadBB) is a
critical edge. SuccBB is another successor of PredBB, it contains another load
v2 which is identical to v1. Current GVN splits the critical edge
(PredBB, LoadBB) and inserts a new load in it. A better method is move the load
of v2 into PredBB, then v1 can be changed to a PHI instruction.

If there are two or more similar predecessors, like the test case in the bug
entry, current GVN simply gives up because otherwise it needs to split multiple
critical edges. But we can move all loads in successor blocks into predecessors.

Differential Revision: https://reviews.llvm.org/D141712
2023-01-25 19:45:01 +00:00
Sergey Kachkov
e1a702db2f [GVN] Refactor findDominatingLoad function
Improve findDominatingLoad implementation:
1. Result is saved into gvn::AvailableValue struct
2. Search is done in extended BB (while there is a single predecessor or
   limit is reached)

Differential Revision: https://reviews.llvm.org/D141680
2023-01-20 11:54:11 +03:00
Sergey Kachkov
bfd2dd49ff [GVN] Refactor handling of pointer-select in GVN pass
This patch extends Def memory dependency with support of select
instructions to consistently handle pointer-select conversion.

Differential Revision: https://reviews.llvm.org/D141619
2023-01-17 11:32:06 +03:00
Sergey Kachkov
868abc471d Revert "[GVN] Refactor handling of pointer-select in GVN pass"
This reverts commit fc7cdaa373308ce3d72218b4d80101ae19850a6c.
2023-01-16 15:13:17 +03:00
Sergey Kachkov
fc7cdaa373 [GVN] Refactor handling of pointer-select in GVN pass
This patch introduces new type of memory dependency - Select to
consistently handle it like Def/Clobber dependency.

Differential Revision: https://reviews.llvm.org/D141619
2023-01-16 14:12:28 +03:00
Sergey Kachkov
fc9b92e14f [GVN][NFC] Refactor GVN::AnalyzeLoadAvailability method
Simplify AnalyzeLoadAvailability code:
1. Use std::optional for return value
2. Use range-based loop for non-local dependencies

Differential Revision: https://reviews.llvm.org/D141664
2023-01-13 12:24:47 +03:00
Guozhi Wei
9852941f01 Revert "[GVN] Improve PRE on load instructions"
This reverts commit 1f1d501843e5cf8741599035d6ef66a3eb5e1e9e.

This patch caused several sanitizer tests failed. Revert it to unblock
others.
2023-01-10 02:35:35 +00:00
Benjamin Kramer
38c481ddcb [GVN] Fold variable into assert. NFC
Avoids unused variable warnings when asserts are disabled.
2023-01-10 00:39:51 +01:00
Guozhi Wei
1f1d501843 [GVN] Improve PRE on load instructions
This patch implements the enhancement proposed by
https://github.com/llvm/llvm-project/issues/59312.

Suppose we have following code

   v0 = load %addr
   br %LoadBB

 LoadBB:
   v1 = load %addr
   ...

 PredBB:
   ...
   br %cond, label %LoadBB, label %SuccBB

 SuccBB:
   v2 = load %addr
   ...

Instruction v1 in LoadBB is partially redundant, edge (PredBB, LoadBB) is a
critical edge. SuccBB is another successor of PredBB, it contains another load
v2 which is identical to v1. Current GVN splits the critical edge
(PredBB, LoadBB) and inserts a new load in it. A better method is move the load
of v2 into PredBB, then v1 can be changed to a PHI instruction.

If there are two or more similar predecessors, like the test case in the bug
entry, current GVN simply gives up because otherwise it needs to split multiple
critical edges. But we can move all loads in successor blocks into predecessors.

Differential Revision: https://reviews.llvm.org/D139582
2023-01-09 23:08:41 +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
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
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