157 Commits

Author SHA1 Message Date
Peter Collingbourne
e3c72e1075
LowerTypeTests: Shrink check size by 1 instruction on x86.
We currently generate code like this on x86 for a jump table with 5 elements,
assuming the call target is in rbx:

lea global_addr(%rip), %rax # initialize temporary rax with base address
mov %rbx, %rcx              # initialize another temporary rcx for index (rbx will be used for the call, so it is still live)
sub %rax, %rcx              # compute `address - base`
ror $0x3, %rcx              # compute `(address - base) ror 3` i.e. index
cmp $0x4, %rcx              # check index <= 4
ja .Ltrap
[...]
.Ltrap:
ud1

A more efficient instruction sequence, that only needs one temporary
register and one fewer instruction, is possible by subtracting the
address we are testing from the fixed address instead of vice versa:

lea (global_addr + 4*8)(%rip), %rax # initialize temporary rax with address of last element
sub %rbx, %rax                      # compute `last element - address`
ror $0x3, %rax                      # compute `(last element - address) ror 3` i.e. 4 - index
cmp $0x4, %rax                      # check 4 - index <= 4 (same as above)
ja .Ltrap
[...]
.Ltrap:
ud1

Change LowerTypeTests to generate that sequence. As a consequence, the
order of bits in the bitsets is reversed. Because it doesn't matter how we
do the subtraction on other architectures (to the best of my knowledge),
do so unconditionally.

Reviewers: fmayer, vitalybuka

Reviewed By: fmayer

Pull Request: https://github.com/llvm/llvm-project/pull/142887
2025-06-06 12:43:24 -07:00
Jeremy Morse
c84f2c79da
[DebugInfo][RemoveDIs] Delete experimental-iterator test-flags from tests (#140045)
Over in 6a45fce, this flag (experimental-debuginfo-iterators) was
switched to do nothing, to flush out anything that depended on the
debug-intrinsics way of doing things. It's been a month and nothing's
super-broken, so we'll start to rip things out.

This commit deletes MergeFunc's debuginfo-iterators test: in d2942a86d7
it's documented that that test is specifically because of differences
between intrinsic/non-intrinsic data structures, and we're deleting the
possibility of that difference.
2025-06-02 18:20:12 +01:00
Nikita Popov
8422c3df63
[LowerTypeTests] Generate fshr for rotate pattern (#141735)
The canonical representation for a rotate right is fshr with two equal
arguments, so generate that instead of a lshr/shl/or sequence.
2025-05-30 10:16:16 +02:00
Peter Collingbourne
c7ea01b8a0
LowerTypeTests: Switch to emitting one inline asm call per jump table entry.
With the previous approach of emitting one inline asm call for all jump
table entries we would encounter SelectionDAG's limit on the number
of operands per node (65536) when the number of jump table entries
exceeded that number. Fix the problem by switching to one inline asm
per jump table entry so that each DAG node only needs one operand.

Reviewers: fmayer, vitalybuka

Reviewed By: fmayer

Pull Request: https://github.com/llvm/llvm-project/pull/136265
2025-04-21 17:49:48 -07:00
Tobias Stadler
1302610f03
[MergeFunc] Fix crash caused by bitcasting ArrayType (#133259)
createCast in MergeFunctions did not consider ArrayTypes, which results
in the creation of a bitcast between ArrayTypes in the thunk function,
leading to an assertion failure in the provided test case.

The version of createCast in GlobalMergeFunctions does handle
ArrayTypes, so this common code has been factored out into the
IRBuilder.
2025-04-04 10:16:40 +01:00
Jeremy Morse
792a6f8119
[RemoveDIs] Remove "try-debuginfo-iterators..." test flags (#130298)
These date back to when the non-intrinsic format of variable locations
was still being tested and was behind a compile-time flag, so not all
builds / bots would correctly run them. The solution at the time, to get
at least some test coverage, was to have tests opt-in to non-intrinsic
debug-info if it was built into LLVM.

Nowadays, non-intrinsic format is the default and has been on for more
than a year, there's no need for this flag to exist.

(I've downgraded the flag from "try" to explicitly requesting
non-intrinsic format in some places, so that we can deal with tests that
are explicitly about non-intrinsic format in their own commit).
2025-03-14 15:50:49 +00:00
Florian Hahn
c7f7ac7591
[MergeFunc] Keep comdat on new function, not thunk. (#130583)
MergeFunc uses the original function F as Thunk and creates a new function NewF for the original function F. Preserve F's comdat info on NewF instead of the thunk.

This fixes a crash when trying to lower comdat on the thunk during codegen.
2025-03-10 18:14:32 +00:00
Florian Hahn
dd86ece554
[MergeFunc] Check full IR and comdat keys in comdat.ll. 2025-03-10 11:11:03 +00:00
Pedro Lobo
3c80d9b8dd
[Instruction] Set metadata to poison on deletion (#129449)
Represent extant metadata uses of a deleted instruction with `poison`
instead of `undef`.
2025-03-03 07:17:01 +07:00
Florian Hahn
3afc3f43f0
[MergeFunc] Remove discardables function before writing alias or thunk. (#128865)
Update writeThunkOrAlias to only create an alias or thunk if it is
actually needed. Drop discardable linkone_odr functions if they are not
used before.

PR: https://github.com/llvm/llvm-project/pull/128865
2025-02-27 15:27:05 +00:00
Florian Hahn
3c4fa5a20a
[MergeFunc] Add tests showing incorrect handling of metadata call args. 2025-02-26 13:47:24 +00:00
Florian Hahn
178b9e5375
[MergeFunc] Add linkonce test with discardable functions. 2025-02-26 11:28:38 +00:00
Florian Hahn
f10e0f7321
[MergeFuncs] Don't introduce calls to (linkonce,weak)_odr functions. (#125050)
Avoid creating new calls to linkonce_odr/weak_odr functions when
merging 2 functions, as this may introduce an infinite call
cycle.

Consider 2 functions below, both present in 2 modules. 

Module X

--
define linkonce_odr void @"A"() {
  call void @"foo"()
}

define linkonce_odr void @"B"() {
  call void @"foo"()
}
--- 

Module Y
---
global @"g" = @"B"

define linkonce_odr void @"A"() {
  %l = load @"g"
  call void %l()
}

define linkonce_odr void @"B"() {
  call void @"foo"()
}
---

 @"A" and @"B" in both modules are semantically equivalent

Module X after function merging:

---
define linkonce_odr void @"A"() {
  call void @"foo"()
}

define linkonce_odr void @"B"() {
  call void @"A"()
}
---

Module Y is unchanged.

Then the linker picks @"A" from module Y and @"B" from module X. Now there's an infinite call cycle


PR: https://github.com/llvm/llvm-project/pull/125050
2025-02-25 15:55:25 +00:00
Florian Hahn
aa770857ee
[MergeFunc] Add tests for (merging weak|linkonce)_odr functions.
Tests for https://github.com/llvm/llvm-project/pull/125050.
2025-02-24 14:24:01 +00:00
Nikita Popov
29441e4f5f
[IR] Convert from nocapture to captures(none) (#123181)
This PR removes the old `nocapture` attribute, replacing it with the new
`captures` attribute introduced in #116990. This change is
intended to be essentially NFC, replacing existing uses of `nocapture`
with `captures(none)` without adding any new analysis capabilities.
Making use of non-`none` values is left for a followup.

Some notes:
* `nocapture` will be upgraded to `captures(none)` by the bitcode
   reader.
* `nocapture` will also be upgraded by the textual IR reader. This is to
   make it easier to use old IR files and somewhat reduce the test churn in
   this PR.
* Helper APIs like `doesNotCapture()` will check for `captures(none)`.
* MLIR import will convert `captures(none)` into an `llvm.nocapture`
   attribute. The representation in the LLVM IR dialect should be updated
   separately.
2025-01-29 16:56:47 +01:00
Nikita Popov
9a24f2198e [MergeFuncs] Handle ConstantRangeList attributes
Support comparison of ConstantRangeList attributes in
FunctionComparator.
2024-12-06 12:21:45 +01:00
Kyungwoo Lee
1941c5180b Reland (2nd attempt) [StructuralHash] Refactor (#112621)
This is largely NFC, and it prepares for #112638.
 - Use stable_hash instead of uint64_t
 - Rename update* to hash* functions. They compute stable_hash locally and return it.

This is a patch for
https://discourse.llvm.org/t/rfc-global-function-merging/82608.
2024-10-26 16:12:28 -07:00
Kyungwoo Lee
d104b8e827 Revert "Reland [StructuralHash] Refactor (#112621)"
This reverts commit 98ca9a635bd2fb98cee473a9558687a5b522e219.
2024-10-26 13:55:46 -07:00
Kyungwoo Lee
98ca9a635b Reland [StructuralHash] Refactor (#112621)
This is largely NFC, and it prepares for #112638.
 - Use stable_hash instead of uint64_t
 - Rename update* to hash* functions. They compute stable_hash locally and return it.

This is a patch for
https://discourse.llvm.org/t/rfc-global-function-merging/82608.
2024-10-26 12:07:57 -07:00
Kyungwoo Lee
9672375623 Revert "[StructuralHash] Refactor (#112621)"
This reverts commit b667d161f0a9ff6b29cda0ccdb0081610c1e8b8c.
2024-10-26 09:55:21 -07:00
Kyungwoo Lee
b667d161f0
[StructuralHash] Refactor (#112621)
This is largely NFC, and it prepares for #112638.
 - Use stable_hash instead of uint64_t
- Rename update* to hash* functions. They compute stable_hash locally and return it.
 
This is a patch for
https://discourse.llvm.org/t/rfc-global-function-merging/82608.
2024-10-26 09:20:26 -07:00
Stephen Tozer
094572701d
[RemoveDIs] Print IR with debug records by default (#91724)
This patch makes the final major change of the RemoveDIs project, changing the
default IR output from debug intrinsics to debug records. This is expected to
break a large number of tests: every single one that tests for uses or
declarations of debug intrinsics and does not explicitly disable writing
records. 

If this patch has broken your downstream tests (or upstream tests on a
configuration I wasn't able to run):
1. If you need to immediately unblock a build, pass
`--write-experimental-debuginfo=false` to LLVM's option processing for all
failing tests (remember to use `-mllvm` for clang/flang to forward arguments to
LLVM).
2. For most test failures, the changes are trivial and mechanical, enough that
they can be done by script; see the migration guide for a guide on how to do
this: https://llvm.org/docs/RemoveDIsDebugInfo.html#test-updates
3. If any tests fail for reasons other than FileCheck check lines that need
updating, such as assertion failures, that is most likely a real bug with this
patch and should be reported as such.

For more information, see the recent PSA:
https://discourse.llvm.org/t/psa-ir-output-changing-from-debug-intrinsics-to-debug-records/79578
2024-06-14 15:07:27 +01:00
Nikita Popov
deab451e7a
[IR] Remove support for icmp and fcmp constant expressions (#93038)
Remove support for the icmp and fcmp constant expressions.

This is part of:
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179

As usual, many of the updated tests will no longer test what they were
originally intended to -- this is hard to preserve when constant
expressions get removed, and in many cases just impossible as the
existence of a specific kind of constant expression was the cause of the
issue in the first place.
2024-06-04 08:31:03 +02:00
Andreas Jonson
844b532713
[MergeFunc] Handle ConstantRange attributes (#88584)
It is possible to update
[AttributeImpl::operator<](a9da350aad/llvm/lib/IR/Attributes.cpp (L744))
instead but feels strange to say that a range is less then an other
range.
2024-04-13 20:01:36 +09:00
Oskar Wirga
a9d4ddd98a
[MergeFuncs/CFI] Ensure all type metadata is propogated for CFI (#88218)
I noticed that we weren't propagating ALL type metadata that was
attached to CFI functions:

# BEFORE

```
; Function Attrs: minsize nounwind optsize ssp uwtable(sync)
define internal void @foo(ptr nocapture noundef readonly %0) #0 !dbg !62311 !type !34028 !type !34029 !type !34030
... fn merging
; Function Attrs: minsize nounwind optsize ssp uwtable(sync)
define internal void @foo(ptr nocapture noundef readonly %0) #0 !type !34028
```

# AFTER

```
; Function Attrs: minsize nounwind optsize ssp uwtable(sync)
define internal void @foo(ptr nocapture noundef readonly %0) #0 !dbg !62311 !type !34028 !type !34029 !type !34030
... fn merging
; Function Attrs: minsize nounwind optsize ssp uwtable(sync)
define internal void @foo(ptr nocapture noundef readonly %0) #0 !type !type !34028 !type !34029 !type !34030
```

This patch makes sure that the entire vector of metadata is copied over.
2024-04-10 15:37:27 -07:00
Nikita Popov
0f46e31cfb
[IR] Change representation of getelementptr inrange (#84341)
As part of the migration to ptradd
(https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699),
we need to change the representation of the `inrange` attribute, which
is used for vtable splitting.

Currently, inrange is specified as follows:

```
getelementptr inbounds ({ [4 x ptr], [4 x ptr] }, ptr @vt, i64 0, inrange i32 1, i64 2)
```

The `inrange` is placed on a GEP index, and all accesses must be "in
range" of that index. The new representation is as follows:

```
getelementptr inbounds inrange(-16, 16) ({ [4 x ptr], [4 x ptr] }, ptr @vt, i64 0, i32 1, i64 2)
```

This specifies which offsets are "in range" of the GEP result. The new
representation will continue working when canonicalizing to ptradd
representation:

```
getelementptr inbounds inrange(-16, 16) (i8, ptr @vt, i64 48)
```

The inrange offsets are relative to the return value of the GEP. An
alternative design could make them relative to the source pointer
instead. The result-relative format was chosen on the off-chance that we
want to extend support to non-constant GEPs in the future, in which case
this variant is more expressive.

This implementation "upgrades" the old inrange representation in bitcode
by simply dropping it. This is a very niche feature, and I don't think
trying to upgrade it is worthwhile. Let me know if you disagree.
2024-03-20 10:59:45 +01:00
Shoaib Meenai
d2942a86d7
[MergeFunctions] Fix thunks for non-instruction debug info (#82080)
When MergeFunctions creates new thunk functions, it needs to copy over
the debug info format kind from the original function, otherwise we'll
mix debug info formats and run into assertions. This was exposed by a
downstream change that runs MergeFunctions before inlining, which caused
assertions when inlining attempted to inline thunks created by merging,
and the added test covers both scenarios where merging creates thunks.
2024-02-20 09:42:18 -08:00
Jeremy Morse
34f61cfa66
[DebugInfo][RemoveDIs] Instrument MergeFunctions for DPValues (#80974)
The MergeFunctions pass has a "preserve some debug-info" mode that tries
to preserve parameter values. This patch generalises its decision-making
so that it applies to both debug-info stored in intrinsics, and
debug-info stored in DPValue objects. For the most part this involves
using a generic lambda and applying it to each type of object.

(Normally we avoid debug-info affecting the code generated, but this is
hidden behind a command line switch, so won't usually be encountered by
users).

Note that this diff is messy, but that's because I'm hoisting some code
into lambdas. The actual decision making processes here are identical.
2024-02-07 18:19:39 +00:00
Nikita Popov
8b8f2ef06e [MergeFunc] Fix comparison of constant expressions
Functions using different constant expressions were incorrectly
merged, because a lot of state was missing from the comparison,
including the opcode, the comparison predicate, the GEP element
type, as well as the inbounds, inrange and nowrap poison flags.
2023-12-20 15:59:02 +01:00
Nikita Popov
836e71a425 [MergeFunc] Adjust GEP indices in test (NFC)
Otherwise inbounds will be inferred, and we don't actually end
up testing the case of one gep without inbounds and one with.
2023-12-20 15:08:13 +01:00
Nikita Popov
3dd2db08a2 [MergeFunc] Add another test for incorrect constexpr merging (NFC)
Looks like we don't even check the opcode :(
2023-12-20 14:53:25 +01:00
Nikita Popov
1ff9fb78c8 [MergeFunc] Add tests for incorrect const expr merging (NFC) 2023-12-20 14:42:21 +01:00
Nuri Amari
049993eae6
[FunctionComparator] Differentiate instructions passing different MDStrings (#69543)
Prior to this patch, differing metadata operands to two otherwise
identical instructions was not enough to consider the instructions
different in the eyes of the function comparator. This breaks LLVM
virtual function elimination, among other features.

In this patch, we handle the case where two associated operands are
MDStrings of different value. This patch does not differentiate more
complex metadata operands.

---------

Co-authored-by: Nuri Amari <nuriamari@fb.com>
2023-10-19 13:59:57 -07:00
Oskar Wirga
c9b7d21dc5
[CFI/MergeFunctions] Modify MergeFunctions to propagate type information (#68628)
When MergeFuncs creates a thunk, it does not modify the function in
place, but creates a new one altogether. If type metadata is not
properly forwarded to this new function, LowerTypeTests will be unable
to put this thunk into the dispatch table.

The fix here is to just forward the type metadata to the newly created
functions.
2023-10-18 11:22:35 -07:00
Oskar Wirga
b48450c209
[MergeFuncs] Use sizeWithoutDebug to decide if we create a thunk (#68627)
I noticed that when we determine the size of the function to figure out
if its profitable, we include debug instructions which can end up making
larger functions than necessary.
2023-10-11 17:32:41 -07:00
Oskar Wirga
e06fc2b2e0
Fix: Distinguish CFI Metadata Checks in MergeFunctions Pass (#65963)
This diff fixes an issue in the MergeFunctions pass where two different
Control Flow Integrity (CFI) metadata checks were incorrectly considered
identical. These merges would lead to runtime violations down the line
as two separate objects contained a single destructor which itself
contained checks for only one of the objects.

Here I update the comparison logic to take into account the metadata at
llvm.type.test checks. Now, only truly identical checks will be
considered for merging, thus preserving the integrity of each check.

Previous discussion: https://reviews.llvm.org/D154119
2023-09-23 12:28:29 +02:00
Noah Goldstein
3391bdc255 Revert "[FunctionAttrs] Propagate some func/arg/ret attributes from caller to callsite (WIP)"
Accidental commit/push!

This reverts commit 4fa971ff62c3c48c606b792c572c03bd4d5906ee.
2023-06-13 00:53:31 -05:00
Noah Goldstein
4fa971ff62 [FunctionAttrs] Propagate some func/arg/ret attributes from caller to callsite (WIP)
This is the consolidation of D151644 and D151943 moved from
InstCombine to FunctionAttrs. This is based on discussion in the above
patches as well as D152081 (Attributor). This patch was written in a
way so it can have an immediate impact in currently active passes
(FunctionAttrs), but should be easy to port elsewhere (Attributor or
Inliner) if that makes more sense later on.

Some function attributes imply the attribute for all/some instructions
in the function. These attributes can be safely propagated to
callsites within the function that are missing the attribute. This can
be useful when 1) analyzing individual instructions in a function
and 2) if the original caller is later inlined, as if the attributes are
not propagated, they will be lost.

This patch implements propagation in a new class/file
`InferCallsiteAttrs` which can hypothetically be included elsewhere.

At the moment this patch infers the following:

Function Attributes:
    - mustprogress
    - nofree
    - willreturn
    - All memory attributes (readnone, readonly, writeonly, argmem,
      etc...)
        - The memory attributes are only propagated IFF the set of
          pointers available to the callsite is the same as the set
          available outside the caller (i.e no local memory arguments
          from alloca or local malloc like functions).

Argument Attributes:
    - noundef
    - nonnull
    - nofree
    - readnone
    - readonly
    - writeonly
    - nocapture
        - nocapture is only propagated IFF the set of pointers
          available to the callsite is the same as the set available
          outside the caller and its guranteed that between the
          callsite and function return, the state of any capture
          pointers will not change (so the nocaptured gurantee of the
          caller has been met by the instruction preceding the
          callsite and will not changed).

Argument are only propagated to callsite arguments that are also function
arguments, but not derived values.

Return Attributes:
    - noundef
    - nonnull

Return attributes are only propagated if the callsite's return value
is used as the caller's return and execution is guranteed to pass from
callsite to return.

The compile time hit of this for -O3 and -O3+thinLTO is ~[.02, .37]%
regression. Proper LTO, however, has more significant regressions (up
to 3.92%):
https://llvm-compile-time-tracker.com/compare.php?from=94407e1bba9807193afde61c56b6125c0fc0b1d1&to=79feb6e78b818e33ec69abdc58c5f713d691554f&stat=instructions:u

Differential Revision: https://reviews.llvm.org/D152226
2023-06-13 00:47:43 -05:00
Krzysztof Drewniak
916425b2d1 [llvm] Use pointer index type for more GEP offsets (pre-codegen)
Many uses of getIntPtrType() were using that type to calculate the
neened type for GEP offset arguments. However, some time ago,
DataLayout was extended to support pointers where the size of the
pointer is not equal to the size of the values used to index it.

Much code was already migrated to, for example, use getIndexSizeInBits
instead of getPtrSizeInBits, but some rewrites still used
getIntPtrType() to get the type for GEP offsets.

This commit changes uses of getIntPtrType() to getIndexType() where
they are involved in a GEP-related calculation.

In at least one case (bounds check insertion) this resolves a compiler
crash that the new test added here would previously trigger.

This commit does not impact
- C library-related rewriting (memcpy()), which are operating under
the assumption that intptr_t == size_t. While all the mechanisms for
breaking this assumption now exist, doing so is outside the scope of
this commit.
- Code generation and below. Note that the use of getIntPtrType() in
CodeGenPrepare will be changed in a future commit.
- Usage of getIntPtrType() in any backend

Depends on D143435

Reviewed By: arichardson

Differential Revision: https://reviews.llvm.org/D143437
2023-03-28 16:41:02 +00:00
Nikita Popov
2f5fdbfab8 [MergeFunc] Don't assume constant metadata operands
We should not call mdconst::extract, unless we know that the
metadata in question is ConstantAsMetadata.

For now we consider all other metadata as equal. The noalias test
shows that this is not correct, but at least it doesn't crash
anymore.
2023-03-23 17:34:53 +01:00
Ding Xiang Fei
16b6826bdd [MergeFuncs] Add tests for D144682 (NFC)
I forgot to git add this test when committing the change.
2023-03-23 17:05:10 +01:00
Mikael Holmen
f5097ed846 Revert "[ADCE] Only remove debug intrinsics if non debug instructions are removed"
This reverts commit 8aa9ab336889ae2eb8e4188036faeb151379ab7b.

Reverting due to compile-time regressions as pointed out in
 https://reviews.llvm.org/D145051#4166656
E.g.
 "In particular tramp3d-v4 with debuginfo regressed by 15%."
2023-03-03 13:07:22 +01:00
Mikael Holmen
8aa9ab3368 [ADCE] Only remove debug intrinsics if non debug instructions are removed
We now limit ADCE to only remove debug intrinsics if it does something else
that would invalidate cached analyses anyway.
As we've seen in
 https://github.com/llvm/llvm-project/issues/58285
throwing away cached analysis info when only debug instructions are removed
can lead to different code when debug info is present or not present.

Differential Revision: https://reviews.llvm.org/D145051
2023-03-03 07:33:31 +01:00
Dmitri Gribenko
736e788c58 Revert "Add tests to reproduce pointer/index width confusion crashes"
This reverts commit 5a4f193afa0d73f7ec459648d8f02535577dd604.

See https://reviews.llvm.org/D144673, this change broke multiple
buildbots.
2023-02-24 13:24:51 +01:00
Krzysztof Drewniak
5a4f193afa Add tests to reproduce pointer/index width confusion crashes
Some calls to GEPOperator::accumulateConstantOffset(APInt) passed the
pointer bitwidth as the width of the APInt, while the function asserts
that the width of its argument is equal to the index width of the GEP
pointer input. These values are almost always the same, so mixing up
which call to use doesn't usually cause issues. However, when dealing
with data layouts where these values are different, the passes tested
here can crash.

This will be fixed in D143437 .

Differential Revision: https://reviews.llvm.org/D144673
2023-02-23 22:50:43 +00:00
Nikita Popov
ee2789001b [MergeFunc] Convert tests to opaque pointers (NFC) 2023-01-04 17:07:15 +01:00
Bjorn Pettersson
3528e63d89 [test] Remove duplicate RUN lines in Transform tests 2022-12-08 11:47:16 +01:00
Roman Lebedev
f38f99bd76
[NFC] Port all MergeFunc tests to -passes= syntax 2022-12-07 22:22:08 +03:00
Leonard Chan
21b03bf970 [llvm] Handle dso_local_equivalent in FunctionComparator
This addresses https://github.com/llvm/llvm-project/issues/51066.

Prior to this, dso_local_equivalent would lead to an llvm_unreachable in
a switch in the FunctionComparator. This adds a conservative case in
that switch that just compares the underlying functions.

Differential Revision: https://reviews.llvm.org/D134300
2022-09-22 18:42:31 +00:00
Nuno Lopes
53dc0f1078 [NFC] Switch a few uses of undef to poison as placeholders for unreachble code 2022-07-03 14:34:03 +01:00