109 Commits

Author SHA1 Message Date
Hongyu Chen
8b5e95b1fd
[InferAddressSpaces] Initialize op(generic const, generic const, ...) -> generic (#172143)
Fixes #171890
If the pointer operands of an instruction are all constants with generic
AS, we always infer the AS of the instruction as uninitialized finally.
And the rewrite process will skip cloning the instruction, producing
invalid IR.
This patch fixes it by inferring the AS of this kind of instruction as
flat. Maybe we can fold the operator with all constants to get better
performance, but I think this case is rare in the real world.
2026-02-08 01:20:19 +08:00
Robert Imschweiler
71cc38736c
[InferAddressSpaces] Handle unconverted ptrmask (#140802)
In case a ptrmask cannot be converted to the new address space due to an
unknown mask value, this needs to be detcted and an addrspacecast is
needed to not hinder a future use of the unconverted return value of
ptrmask. Otherwise, users of this value will become invalid by receiving
a nullptr as an operand.

This LLVM defect was identified via the AMD Fuzzing project.

(See https://reviews.llvm.org/D80129 for an explanation of why some
ptrmasks are impossible to convert to other addrspaces.)
2026-01-14 09:10:05 +01:00
Kerang Mao
3890c97fc0
[InferAddressSpaces] Fix bad addrspacecast insertion for phinode (#163528)
The IR verifier will carsh if there is any instructions located before
phi-node. The `infer-address-spaces` pass would like to insert
`addrspacecast` before phi-node in some corner cases. Indeed, since the
operand pointer(phi-node's incoming value) has been determined to
`NewAS` by the pass, it is safe to `addrspacecast` it immediately after
the position where defined it.

Co-authored-by: Kerang Mao <krmao@birentech.com>
2025-11-14 18:55:05 +08:00
Wenju He
dd669c32ec
[InferAddressSpaces] Mark ConstantAggregateZero as safe to cast to a ConstantExpr addrspacecast (#159695)
This PR extends isSafeToCastConstAddrSpace to treat
ConstantAggregateZero like ConstantPointerNull.
Tests shows an extra addrspacecast instruction is removed and icmp
pointer vector operand's address space is now inferred.

This change is motivated by inspecting the test in commit f7629f5945f6.
2025-09-19 14:15:40 +08:00
Wenju He
f7629f5945
[InferAddressSpaces] Extend undef pointer operand support to phi inst (#159548)
Previously undef pointer operand is only supported for select inst,
where undef in generic AS behaves like `take the other side`.

This PR extends the support to other instructions, e.g. phi inst. Defer
joining and inferring constant pointer operand until all other operand
AS states considered.

---------

Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
2025-09-19 09:14:00 +08:00
Nikita Popov
c23b4fbdbb
[IR] Remove size argument from lifetime intrinsics (#150248)
Now that #149310 has restricted lifetime intrinsics to only work on
allocas, we can also drop the explicit size argument. Instead, the size
is implied by the alloca.

This removes the ability to only mark a prefix of an alloca alive/dead.
We never used that capability, so we should remove the need to handle
that possibility everywhere (though many key places, including stack
coloring, did not actually respect this).
2025-08-08 11:09:34 +02:00
Nikita Popov
92c55a315e
[IR] Only allow lifetime.start/end on allocas (#149310)
lifetime.start and lifetime.end are primarily intended for use on
allocas, to enable stack coloring and other liveness optimizations. This
is necessary because all (static) allocas are hoisted into the entry
block, so lifetime markers are the only way to convey the actual
lifetimes.

However, lifetime.start and lifetime.end are currently *allowed* to be
used on non-alloca pointers. We don't actually do this in practice, but
just the mere fact that this is possible breaks the core purpose of the
lifetime markers, which is stack coloring of allocas. Stack coloring can
only work correctly if all lifetime markers for an alloca are
analyzable.

* If a lifetime marker may operate on multiple allocas via a select/phi,
we don't know which lifetime actually starts/ends and handle it
incorrectly (https://github.com/llvm/llvm-project/issues/104776).
* Stack coloring operates on the assumption that all lifetime markers
are visible, and not, for example, hidden behind a function call or
escaped pointer. It's not possible to change this, as part of the
purpose of lifetime markers is that they work even in the presence of
escaped pointers, where simple use analysis is insufficient.

I don't think there is any way to have coherent semantics for lifetime
markers on allocas, while also permitting them on arbitrary pointer
values.

This PR restricts lifetimes to operate on allocas only. As a followup, I
will also drop the size argument, which is superfluous if we always
operate on an alloca. (This change also renders various code handling
lifetime markers on non-alloca dead. I plan to clean up that kind of
code after dropping the size argument as well.)

In practice, I've only found a few places that currently produce
lifetimes on non-allocas:

* CoroEarly replaces the promise alloca with the result of an intrinsic,
which will later be replaced back with an alloca. I think this is the
only place where there is some legitimate loss of functionality, but I
don't think this is particularly important (I don't think we'd expect
the promise in a coroutine to admit useful lifetime optimization.)
* SafeStack moves unsafe allocas onto a separate frame. We can safely
drop lifetimes here, as SafeStack performs its own stack coloring.
* Similar for AddressSanitizer, it also moves allocas into separate
memory.
* LSR sometimes replaces the lifetime argument with a GEP chain of the
alloca (where the offsets ultimately cancel out). This is just
unnecessary. (Fixed separately in
https://github.com/llvm/llvm-project/pull/149492.)
* InferAddrSpaces sometimes makes lifetimes operate on an addrspacecast
of an alloca. I don't think this is necessary.
2025-07-21 15:04:50 +02:00
QiYue
758fea0e99
[InferAddressSpaces] Handle llvm.lifetime (#141045)
Co-authored-by: Zhenhao Yang <zhenhao.yang@nio.com>
Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
2025-05-22 18:06:01 +02:00
Matt Arsenault
9f8d798942
InferAddressSpaces: Stop trying to insert pointer bitcasts (#140873) 2025-05-21 14:18:40 +02:00
Philip Reames
f0d7fea98b
[IRBuilder] Use AAMDNodes helper class in CreateMem* routines [nfc-ish] (#139950)
I'm not 100% sure this is NFC because we have the possibility we're
propagating additional metadata we'd missed before. We don't see any
test changes resulting from this though.
2025-05-15 10:18:54 -07:00
Philip Reames
c0a264e6a9
[IntrinsicInst] Remove MemCpyInlineInst and MemSetInlineInst [nfc] (#138568)
I'm looking for ways to simplify the Mem*Inst class structure, and these
two seem to have fairly minimal justification, so let's remove them.
2025-05-05 14:07:31 -07:00
Alex MacLean
ba0a52a04b
[InferAS] Support getAssumedAddrSpace for Arguments for NVPTX (#133991) 2025-04-03 16:47:36 -07:00
Kazu Hirata
cde58bfc16
[Transforms] Use range constructors of *Set (NFC) (#133203) 2025-03-27 07:51:58 -07:00
Jeremy Morse
8e70273509
[NFC][DebugInfo] Use iterator moveBefore at many call-sites (#123583)
As part of the "RemoveDIs" project, BasicBlock::iterator now carries a
debug-info bit that's needed when getFirstNonPHI and similar feed into
instruction insertion positions. Call-sites where that's necessary were
updated a year ago; but to ensure some type safety however, we'd like to
have all calls to moveBefore use iterators.

This patch adds a (guaranteed dereferenceable) iterator-taking
moveBefore, and changes a bunch of call-sites where it's obviously safe
to change to use it by just calling getIterator() on an instruction
pointer. A follow-up patch will contain less-obviously-safe changes.

We'll eventually deprecate and remove the instruction-pointer
insertBefore, but not before adding concise documentation of what
considerations are needed (very few).
2025-01-24 10:53:11 +00:00
Kazu Hirata
94f9cbbe49
[Scalar] Remove unused includes (NFC) (#114645)
Identified with misc-include-cleaner.
2024-11-02 08:32:26 -07:00
Rahul Joshi
fa789dffb1
[NFC] Rename Intrinsic::getDeclaration to getOrInsertDeclaration (#111752)
Rename the function to reflect its correct behavior and to be consistent
with `Module::getOrInsertFunction`. This is also in preparation of
adding a new `Intrinsic::getDeclaration` that will have behavior similar
to `Module::getFunction` (i.e, just lookup, no creation).
2024-10-11 05:26:03 -07:00
Matt Arsenault
fbd2a91865
InferAddressSpaces: Handle llvm.fake.use (#109567) 2024-10-09 09:24:37 +04:00
Matt Arsenault
90a8e5a7ac
InferAddressSpaces: Factor replacement loop into function [NFC] (#104430) 2024-08-20 19:41:24 +04:00
Matt Arsenault
2ccbf92f87 InferAddressSpaces: Restore non-instruction user check
Fixes regression after 79658d65c3c7a075382b74d81e74714e2ea9bd2d.
We were missing test coverage for the nested constant expression
case.
2024-08-15 15:55:09 +04:00
Matt Arsenault
79658d65c3
InferAddressSpaces: Make getPredicatedAddrSpace less confusing (#104052)
This takes a pointer value and the user instruction. Name them as
such, and remove the null check which should be dead.
2024-08-15 14:42:08 +04:00
Matt Arsenault
7a51dde4e6
InferAddressSpaces: Improve handling of instructions with multiple pointer uses (#101922)
The use list iteration worked correctly for the load and store case. The atomic
instructions happen to have the pointer value as the last visited operand, but we
rejected the instruction as simple after the first encountered use.

Ignore the use list for the recognized load/store/atomic instructions, and just
try to directly replace the known pointer use.
2024-08-08 13:19:35 +04:00
Matt Arsenault
2ef553c05f
InferAddressSpaces: Handle llvm.is.constant (#102010) 2024-08-06 00:20:01 +04:00
Matt Arsenault
47fc4c37bb
InferAddressSpaces: Handle masked load and store intrinsics (#102007) 2024-08-06 00:17:07 +04:00
Matt Arsenault
f01a6f5ecb
InferAddressSpaces: Handle prefetch intrinsic (#101982) 2024-08-06 00:14:02 +04:00
Matt Arsenault
35b4f83745 InferAddressSpaces: Simplify check of volatile allowed
Avoid redundant dyn_cast to instruction before chain of dyn_cast
to specific instructions.
2024-08-05 09:30:08 +04:00
Matt Arsenault
3c483b887e
InferAddressSpaces: Fix mishandling stores of pointers to themselves (#101877) 2024-08-04 16:36:00 +04:00
Shan Huang
a355c2d074
[DebugInfo][InferAddressSpaces] Fix the missing debug location update for the new addrspacecast (#97038)
Fix #97006 .
2024-07-03 09:39:17 +08: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
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
Pierre van Houtryve
c831d83bb1
[InferAddrSpaces] Correctly replace identical operands of insts (#82610)
It's important for PHI nodes because if a PHI node has multiple edges
coming from the same block, we can have the same incoming value multiple
times in the list of incoming values. All of those need to be consistent
(exact same Value*) otherwise verifier complains.

Fixes SWDEV-445797
2024-02-22 13:59:04 +01:00
Wenju He
fe146e9b59
[InferAddressSpaces] Fix constant replace to avoid modifying other functions (#70611)
A constant value is unique in llvm context. InferAddressSpaces was
replacing its users in other functions as well. This leads to unexpected
behavior in our downstream use case after the pass.

InferAddressSpaces is a function passe, so it shall not modify functions
other than currently processed one.

Co-authored-by: Abhinav Gaba <abhinav.gaba@intel.com>

---------

Co-authored-by: Abhinav Gaba <abhinav.gaba@intel.com>
2023-11-13 13:28:56 +08:00
Wenju He
d199ff1765
[InferAddressSpaces] collect flat address expression from return value (#70610)
If function return value's type is pointer, we can try to collect flat
address expression from it.
This PR also fixes noop_ptrint_pair_ce2 in noop-ptrint-pair.ll in #70611
2023-11-01 13:32:38 +08:00
Harald van Dijk
04224d1ae7
[InferAddressSpaces] Register pass. (#65639)
InferAddressSpaces failed to call its initialization function. It was
still called through initializeScalarOpts in llc and opt, but it was
skipped entirely in clang. When the initialization function is not
called, this results in confusing behavior where the pass appears to
run, but not entirely as it should, e.g. the pass is excluded from
-print-before-all and -print-after-all.
2023-09-07 21:35:16 +01:00
Fraser Cormack
e0c60bff8c [InferAddressSpaces][NFC] Fix code formatting 2023-08-31 12:19:13 +01:00
Nuno Lopes
89552f3a38 [InferAddressSpaces] Use poison instead of undef as placeholder [NFC]
This placeholder is only used during the execution of the algorithm, and it's patched with a
concrete value at the end
2023-07-16 22:33:09 +01:00
Nikita Popov
06807957c5 [llvm] Remove uses of hasSameElemenTypeAs() (NFC)
Always returns true with opaque pointers.
2023-07-14 10:32:43 +02:00
CaprYang
44096e6904 [InferAddressSpaces] Handle vector of pointers type & Support intrinsic masked gather/scatter 2023-05-17 23:40:06 +01:00
Nikita Popov
bbfb13a5ff [ConstExpr] Remove select constant expression
This removes the select constant expression, as part of
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179.
Uses of this expressions have already been removed in advance,
so this just removes related infrastructure and updates tests.

Differential Revision: https://reviews.llvm.org/D145382
2023-03-16 10:32:08 +01:00
Juan Manuel MARTINEZ CAAMAÑO
52545e603b [DebugInfo][InferAddressSpaces] Propagate DebugLoc when cloning an instruction in InferAddressSpaces
Differential Revision: https://reviews.llvm.org/D134428
2022-09-29 08:43:37 +00:00
Guillaume Chatelet
dc9c2eac98 [NFC][Alignment] Simplify code 2022-06-10 15:25:28 +00:00
Wenju He
96d3be8443 [InferAddressSpaces] Check if AS are the same in isNoopPtrIntCastPair
isNoopAddrSpaceCast is expecting SrcAS is different from DestAS.
If the two AS are the same, consider ptrtoint/inttoptr as noop cast.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D123573
2022-04-28 11:10:55 +08:00
Austin Kerbow
26b14c3ea7 [InferAddressSpaces] Fix assert on invalid bitcast placement
Similar to the problem in 0bb25b4603, bitcasts that are inserted must
dominate all uses. When rewriting "values" with "new values" that have
the updated address space, we may replace the "new value" with a bitcast
if one of the original users is an addresspace cast. This bitcast must
be inserted before ALL users, not only before the addresspace cast.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D122964
2022-04-07 20:07:53 -07:00
psamolysov-intel
2ed030ba88 [InferAddressSpaces][NFC] Small code improvements for the InferAddressSpaces pass
There is a bunch of code improvements in the patch: marking as const everything what can be
const and fixing some typos in comments.

Also the patch removes the shadowing parameter TTI from the rewriteWithNewAddressSpaces
method, the TTI parameter is not required because the same field is in the class.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D121671
2022-03-21 11:03:12 -05:00
serge-sans-paille
59630917d6 Cleanup includes: Transform/Scalar
Estimated impact on preprocessor output line:
before: 1062981579
after:  1062494547

Discourse thread: https://discourse.llvm.org/t/include-what-you-use-include-cleanup
Differential Revision: https://reviews.llvm.org/D120817
2022-03-03 07:56:34 +01:00
Austin Kerbow
0bb25b4603 [InferAddressSpaces] Fix assert on invalid cast ordering
If a cast is needed when replacing uses with newly created values, the
cast must be inserted after the instruction that defines the new value.

Fixes: SWDEV-321215

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D119524
2022-02-11 10:02:30 -08:00
Matt Arsenault
52fbb786a6 InferAddressSpaces: Fix assert on inferred source for inttoptr/ptrtoint
If we had some source value we could infer an address space from that
went through a ptrtoint/inttoptr pair, this would fail since bitcast
can't change the address space.

Fixes issue 53665.
2022-02-11 10:35:29 -05:00
Kazu Hirata
732e8968a8 [Scalar] Remove a redundant declaration (NFC)
InitializePasses.h contains the proper declaration.

Identified with readability-redundant-declaration.
2021-12-31 14:02:29 -08:00
Michael Liao
bf225939bc [InferAddressSpaces] Support assumed addrspaces from addrspace predicates.
- CUDA cannot associate memory space with pointer types. Even though Clang could add extra attributes to specify the address space explicitly on a pointer type, it breaks the portability between Clang and NVCC.
- This change proposes to assume the address space from a pointer from the assumption built upon target-specific address space predicates, such as `__isGlobal` from CUDA. E.g.,

```
  foo(float *p) {
    __builtin_assume(__isGlobal(p));
    // From there, we could assume p is a global pointer instead of a
    // generic one.
  }
```

This makes the code portable without introducing the implementation-specific features.

Note that NVCC starts to support __builtin_assume from version 11.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D112041
2021-11-08 16:51:57 -05:00
Arthur Eubanks
ae27c57b18 [InferAddressSpaces] Make pass work with opaque pointers
Avoid getPointerElementType().
2021-10-26 23:53:20 -07:00
Artem Belevich
b988d69ea2 [infer-address-spaces] Handle complex non-pointer constexpr arguments.
Fixes https://bugs.llvm.org/show_bug.cgi?id=51099

Differential Revision: https://reviews.llvm.org/D106098
2021-07-19 12:15:52 -07:00