Skip to content

[bazel] Fix bazelisk failures after ORC RTBridge removal and libc float128 - #1

Open
DeanSturtevant1 wants to merge 1 commit into
mainfrom
r630676
Open

DeanSturtevant1 wants to merge 1 commit into
mainfrom
r630676

Conversation

@DeanSturtevant1

Copy link
Copy Markdown
Owner

Commit f406aae removed the ORC/RTBridge directory and relocated its headers directly under include/llvm/ExecutionEngine/Orc/. This updates OrcJIT and OrcShared in llvm/BUILD.bazel to remove the obsolete RTBridge header glob patterns.

Additionally, this adds the missing :__support_fputil_float128 target in libc/BUILD.bazel and includes it in the dependencies of :__support_math_ceilf128 and :shared_math_headers_for_apfloat.

TAG=agy
CONV=cdc6d2a4-4a43-464a-ae1b-a56f935ee140

…at128

Commit f406aae removed the ORC/RTBridge directory and relocated its headers directly under include/llvm/ExecutionEngine/Orc/. This updates OrcJIT and OrcShared in llvm/BUILD.bazel to remove the obsolete RTBridge header glob patterns.

Additionally, this adds the missing :__support_fputil_float128 target in libc/BUILD.bazel and includes it in the dependencies of :__support_math_ceilf128 and :shared_math_headers_for_apfloat.

TAG=agy
CONV=cdc6d2a4-4a43-464a-ae1b-a56f935ee140
DeanSturtevant1 pushed a commit that referenced this pull request Sep 13, 2026
To match VirtualSize, and Microsoft's dumpbin which prints both as hex:
SECTION HEADER #1
   .text name
   440B4 virtual size
    1000 virtual address (0000000140001000 to 00000001400450B3)
   44200 size of raw data

llvm-readobj before this change:
    VirtualSize: 0x3478
    VirtualAddress: 0x74000
    RawDataSize: 3584

And after:
    VirtualSize: 0x3478
    VirtualAddress: 0x74000
    RawDataSize: 0xe00

This was pointed out on
llvm#220618, where I was having
to manually convert the numbers to compare them.
DeanSturtevant1 pushed a commit that referenced this pull request Sep 13, 2026
…m#205764 (llvm#221843)

New LifetimeSafetyOpts fields were added in
llvm#221610 but they are not
initialized in clang/unittests/Analysis/LifetimeSafetyTest.cpp, leading
to use-of-uninitialized-memory
(https://lab.llvm.org/buildbot/#/builders/164/builds/25165):
```
WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x555571559cbc in clang::lifetimes::internal::(anonymous namespace)::LifetimeChecker::LifetimeChecker(clang::lifetimes::internal::LoanPropagationAnalysis const&, clang::lifetimes::internal::MovedLoansAnalysis const&, clang::lifetimes::internal::LiveOriginsAnalysis const&, clang::lifetimes::internal::FactManager&, clang::AnalysisDeclContext&, clang::lifetimes::LifetimeSafetySemaHelper*, clang::lifetimes::LifetimeSafetyOpts const&) /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Analysis/LifetimeSafety/Checker.cpp:108:9
    #1 0x5555715453cd in clang::lifetimes::internal::runLifetimeChecker(clang::lifetimes::internal::LoanPropagationAnalysis const&, clang::lifetimes::internal::MovedLoansAnalysis const&, clang::lifetimes::internal::LiveOriginsAnalysis const&, clang::lifetimes::internal::FactManager&, clang::AnalysisDeclContext&, clang::lifetimes::LifetimeSafetySemaHelper*, clang::lifetimes::LifetimeSafetyOpts const&) /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Analysis/LifetimeSafety/Checker.cpp:575:19
    #2 0x555571524c1e in clang::lifetimes::internal::LifetimeSafetyAnalysis::run() /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp:98:3
    llvm#3 0x55555c3da25b in LifetimeTestRunner /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/unittests/Analysis/LifetimeSafetyTest.cpp:71:15
...
  Uninitialized value was stored to memory at
    #0 0x55555bcd06c7 in __msan_memcpy /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/compiler-rt/lib/msan/msan_interceptors.cpp:1760:3
    #1 0x5555715238ed in clang::lifetimes::internal::LifetimeSafetyAnalysis::LifetimeSafetyAnalysis(clang::AnalysisDeclContext&, clang::lifetimes::LifetimeSafetySemaHelper*, clang::lifetimes::LifetimeSafetyOpts const&) /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp:54:39
    #2 0x55555c3da1b9 in make_unique<clang::lifetimes::internal::LifetimeSafetyAnalysis, clang::AnalysisDeclContext &, std::nullptr_t, clang::lifetimes::LifetimeSafetyOpts &, 0> /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/libcxx_install_msan_track_origins/include/c++/v1/__memory/unique_ptr.h:713:30
    llvm#3 0x55555c3da1b9 in LifetimeTestRunner /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/unittests/Analysis/LifetimeSafetyTest.cpp:70:9
```

This patch fixes the issue by initializing the fields in the test to
true, which maintains the behavior prior to the new fields being added.

Additionally, this patch does a similar drive-by fix to the
SuggestAnnotations field (added in
llvm#205764). Although there has
been no MSan report, that's likely either an MSan false negative or
insufficient test coverage.
DeanSturtevant1 pushed a commit that referenced this pull request Sep 13, 2026
`target create` never returns for a little-endian 32-bit MIPS ELF file,
on any host whose platform advertises `armv7m`/`armv7em` compatibility.
On Darwin that is every platform, since
`PlatformDarwin::GetCompatibleArchs()`
lists both for every arm64/arm64e host and falls through to that same
list
for any other host core.  It is found by `lldb-target-fuzzer`.

Reproduce with a 52-byte ELF32 header (`ELFCLASS32`, `ELFDATA2LSB`,
`e_machine = EM_MIPS`, `e_flags = EF_MIPS_ARCH_32`, everything else
zero),
saved as `mips32el.elf`:

```
(lldb) target create mips32el.elf
```

This never returns.  Attaching a debugger to the hung process shows the
same three frames looping forever, with the call stack never growing:

```
frame #1: cores_match(core1=eCore_arm_armv7m, core2=eCore_mips32el, try_inverse=false, ...) at ArchSpec.cpp:1575 [inlined]
frame #2: ArchSpec::IsMatch(rhs=..., match=CompatibleMatch) at ArchSpec.cpp:1449
frame llvm#3: Platform::IsCompatibleArchitecture(...) at Platform.cpp:1193
```

`cores_match()` checks `core1` against `core2`. When nothing matches and
the caller did not ask for an exact match, it sets `try_inverse` and
retries once with the two cores swapped.  It retries because the rule
tables are not symmetric: a core lists only what it accepts, not
everything
that accepts it.

Every case that reaches this fallback must leave `try_inverse` false on
the
way out, so the swap happens at most once.  Three cases,
`eCore_arm_armv7em`, `eCore_arm_armv7m`, and `eCore_mips32el`, instead
set
it back to true unconditionally. When both sides of a comparison are one
of these three, the swapped call re-arms `try_inverse`, and the tail
call
back into `cores_match()` recurses forever.

This is a tail call, so an optimizing compiler turns the recursion into
a
loop instead of a growing stack. That is why the process spins instead
of
crashing with a stack overflow.

The three cases cannot simply leave `try_inverse` false like their
siblings. `ArchSpec("mipsel").IsCompatibleMatch(ArchSpec("mips64el"))`
is
true today only because of this same swap: `eCore_mips32el`'s own rule
says
nothing about 64-bit MIPS, but `eCore_mips64el`'s rule accepts any
32-bit
MIPS core with the same endianness, and only the inverted comparison
reaches that rule.

Instead, split the switch into a one-directional helper that never
recurses, and try both directions from a plain, non-recursive wrapper:

```
cores_match(A, B) := cores_match_one_direction(A, B) ||
                      cores_match_one_direction(B, A)
```

This keeps every existing one-directional rule exactly as it was,
including
the mips32el/mips64el rule above, and makes a second retry impossible no
matter what any case does.

Adds two regression tests to ArchSpecTest.cpp.  One asserts that the
previously-hanging pairs now return false right away. The other locks in
the two relationships that depend on checking both directions, so a
future
change cannot bring the recursion back by "fixing" the three cases the
naive way.

Assisted-by: claude
DeanSturtevant1 pushed a commit that referenced this pull request Sep 13, 2026
)

BufferedStackTrace::UnwindFast walks the stack assuming frame[0] is the
caller's frame pointer and frame[1] the return address. Alpha chains
neither, so the walk yields a few garbage frames and then stops:
```
  freed by thread T0 here:
      #0 0x020000971274 in free asan_malloc_linux.cpp:51
      #1 0x0200007fa48c  (<unknown module>)
```
Opt Alpha out of the fast unwinder the way Linux/MIPS already is. The
_Unwind_Backtrace based unwinder gives complete traces; with it, GCC's
g++.dg/asan/deep-stack-uaf-1.C passes on alpha-unknown-linux-gnu.
DeanSturtevant1 pushed a commit that referenced this pull request Sep 18, 2026
…219917)

`vector.outerproduct` builds its result type from dimension 0 of its
operands, which a 0-d vector does not have, so `mlir-opt` aborts while
parsing, before the verifier gets a chance to report anything:

```mlir
%0 = vector.outerproduct %a, %b : vector<f32>, vector<4xf32>
```

The parser now emits the same diagnostic the verifier already gives for
that operand, `expected 1-d vector for operand #1`. Only rank 0 is
caught here, rank 2 and above still reach the verifier unchanged.

This PR started out touching three parsers and was narrowed to
`outerproduct` at review request. The `transfer_read`/`transfer_write`
and `contract` parsers follow as separate PRs.
DeanSturtevant1 pushed a commit that referenced this pull request Sep 29, 2026
…lvm#224001)

Running the `HighlighterTests` unit test under AddressSanitizer aborts
on every Swift test case, for example `SwiftComments`:

```
==69424==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000008070 at pc 0x000116a1f36c bp 0x00016d07c3c0 sp 0x00016d07c3b8
READ of size 4 at 0x602000008070 thread T0
    #0 0x000116a1f368 in eat_raw_str_part scanner.c:700
    #1 0x000116a1b5f4 in tree_sitter_swift_external_scanner_scan scanner.c:858
    #2 0x00012cc77420 in ts_parser_parse
    llvm#3 0x00012cc79afc in ts_parser_parse_string
    llvm#4 0x00010a3536a4 in lldb_private::TreeSitterHighlighter::Highlight(...)

0x602000008071 is located 0 bytes after 1-byte region [0x602000008070,0x602000008071)
allocated by thread T0 here:
    #0 0x00012d68d560 in calloc
    #1 0x00012cc763b8 in ts_parser_parse
    #2 0x00012cc79afc in ts_parser_parse_string
```

`eat_raw_str_part` reads `state->ongoing_raw_str_hash_count` as its
first statement, a 4 byte field, but the scanner state was allocated
with:

```
void *tree_sitter_swift_external_scanner_create() {
  return calloc(0, sizeof(struct ScannerState));
}
```

`calloc` with an element count of 0 has no obligation to reserve room
for `sizeof(struct ScannerState)`, so it works by accident, but is
found by ASAN.

Fix it by allocating one instance, matching the Rust scanner and the
struct's actual use as a single persistent state object across calls.

The existing `HighlighterTest.Swift*` tests already exercise this path
end to end and catch the regression under AddressSanitizer; no new
test is needed.
DeanSturtevant1 pushed a commit that referenced this pull request Sep 29, 2026
…226936)

Fixes llvm#191859.

On Arm one of the functions has no name, which is a valid state.
```
Num frames: 7
0 frame #0: 0x092a151c a.out`baz at main.c:5:3 --name:  baz
1 frame #1: 0x092a1540 a.out`bar at main.c:10:10 --name:  bar
2 frame #2: 0x092a1560 a.out`foo at main.c:15:10 --name:  foo
3 frame llvm#3: 0x092a158c a.out`main at main.c:20:10 --name:  main
4 frame llvm#4: 0xf7ab939a libc.so.6` --name:  None
5 frame llvm#5: 0xf7ab943e libc.so.6`__libc_start_main + 94 --name:  __libc_start_main
6 frame llvm#6: 0x092a1434 a.out`_start + 40 --name:  _start
```
The prefix provider needs to handle that possibility.

Though the Python type annotations on ScriptedFrame say that the name
methods return string, in reality they can return None, which the C++
sides expect. I will fix that in another PR.
DeanSturtevant1 pushed a commit that referenced this pull request Sep 29, 2026
This test has been failing on AArch64 Linux recently. Either with
SIGSEGV or SIGABRT (less often that one).

I could reproduce it locally by varying system load, and got this out of
a core file:
```
* thread #1, name = 'test_python_sto', stop reason = SIGSEGV: address not mapped to object (fault address=0xc17d18317552db80)
   * frame #0: 0x0000ef7dc72ac6cc libc.so.6`__GI_memchr at memchr.S:68
     frame #1: 0x0000ef7dc727cf4c libc.so.6`_IO_getline_info(fp=0x0000b9b53a8bd180, buf="\xa9\xb4\t\xce}\xef", n=<unavailable>
, delim=10, extract_delim=1, eof=0x0000000000000000) at iogetline.c:85:17
     frame #2: 0x0000ef7dc727bdc4 libc.so.6`_IO_fgets(buf="\xa9\xb4\t\xce}\xef", n=<unavailable>, fp=0x0000b9b53a8bd180) at io
fgets.c:53:11
     frame llvm#3: 0x0000ef7dc80f2b80 liblldb.so.24.0git`lldb_private::IOHandlerEditline::GetLine(std::__cxx11::basic_string<char,
 std::char_traits<char>, std::allocator<char>>&, bool&) + 996
     frame llvm#4: 0x0000ef7dc80f41f4 liblldb.so.24.0git`lldb_private::IOHandlerEditline::Run() + 180
     frame llvm#5: 0x0000ef7dc80bf614 liblldb.so.24.0git`lldb_private::Debugger::RunIOHandlers() + 128
     frame llvm#6: 0x0000ef7dc80ccee8 liblldb.so.24.0git`std::_Function_handler<void* (), lldb_private::Debugger::StartIOHandlerTh
read()::$_0>::_M_invoke(std::_Any_data const&) + 28
     frame llvm#7: 0x0000ef7dc81e1608 liblldb.so.24.0git`lldb_private::HostNativeThreadBase::ThreadCreateTrampoline(void*) + 124
     frame llvm#8: 0x0000ef7dc72903c8 libc.so.6`start_thread(arg=0x000000000080e640) at pthread_create.c:442:8
     frame llvm#9: 0x0000ef7dc72f9fdc libc.so.6`thread_start at clone.S:79
```
What's happening is that the interpreter's input stream is set to stream
A, then we reset it to the default, then close stream A. There may still
be reads from stream A in flight when we close it, which lead to the
crash.

The solution is to wait on the interpreter thread to finish whatever
it's doing. SBDebuger::Destroy does that.

Normally that would be called by driver.cpp but it can be called on
already destroyed objects. So for this test we'll call it twice, but
that's not a problem.
DeanSturtevant1 pushed a commit that referenced this pull request Oct 28, 2026
…biner (llvm#234727)

The legalizer can create chains of shifts by constants that the
pre-legalizer combiner never sees. Adding `shift_immed_chain` to the
post-legalizer combiner merges them.

```llvm
define i16 @test(i16 %a) {
  %r = sdiv i16 %a, 7
  ret i16 %r
}
```

Before (7 instructions):
```
sxth w8, w0
mov  w9, llvm#18725
mul  w8, w8, w9
asr  w8, w8, llvm#16
asr  w8, w8, #1
ubfx w9, w8, llvm#15, #1
add  w0, w8, w9
```

After (6 instructions):
```
sxth w8, w0
mov  w9, llvm#18725
mul  w8, w8, w9
asr  w8, w8, llvm#17
ubfx w9, w8, llvm#15, #1
add  w0, w8, w9
```

The rule rewrites the existing shift in place with a new constant amount
of the same type, so it does not create illegal instructions. The same
applies to other i8/i16 division and remainder by a constant in
combine-sdiv.ll and rem-by-const.ll.
DeanSturtevant1 pushed a commit that referenced this pull request Oct 28, 2026
## Summary

Optimize Thumb-2 code generation for zero tests of values masked by
contiguous low-bit masks. For these tests, shifting the input can
preserve whether the masked value is zero while avoiding a `BIC`.

The four source forms covered by this pattern reduce to one of two
zero-test shapes: an `i32` test or an `i64` test lowered across two
`i32` halves.

## Changes

- Add a helper to recognize eligible single-use ANDs with contiguous low
masks and form an equivalent shifted value for a zero test.
- Apply the transform to Thumb-2 equality and inequality comparisons
against zero, including the OR of halves produced when an `i64`
comparison is lowered.
- Preserve existing lowering for byte and halfword masks
(`UXTB`/`UXTH`), as well as for masks and comparisons where shifting
does not preserve the relevant result.
- Add regression coverage for optimized `i32` and `i64` cases and for
cases where the transform must not apply, including noncontiguous masks,
signed comparisons, nonzero comparisons, and multiple uses.

## Related Issues and Extra Comments

Resolves llvm#224748

Thumb-2 may fold the shifted operand into the OR, producing the
equivalent `orr.w r0, r0, r1, lsl #1`.

`CLZ` and `LSRS llvm#5` remain because they convert the zero test into an
`i1`: `CLZ` returns 32 for zero and at most 31 for nonzero, so shifting
right by five yields 1 for zero and 0 otherwise.

The transform deliberately skips `0xff` and `0xffff` masks. Thumb-2
already lowers those efficiently with `UXTB` and `UXTH`, so shifting is
unnecessary for those cases.

## Testing

`llvm/test/CodeGen/ARM/icmp-mask-zero.ll`
DeanSturtevant1 pushed a commit that referenced this pull request Nov 2, 2026
…#235909)

When a scripted frame provider is loaded, Thread::ClearStackFrames saves
the provider-augmented frame list in m_prev_frames_sp, and the next base
unwinder frame list (ID 0) is created with it as its previous frames.
Once the unwinder list has fetched all its frames, it merges with the
previous list and adopts every previous frame whose StackID matches.
Scripted frames that mirror the CFA and PC of the frames they wrap have
matching StackIDs, so they replace the unwound frames in the unwinder
list. That means the unwinder backtrace shows the scripted frames
instead of the newly unwound ones:

```
(lldb) bt --provider 0
=== Provider 0: Base Unwinder ===
   frame #0: a.out`main at main.c:23:3 [synthetic]
   frame #1: dyld`start + 6652 [synthetic]
```

If a scripted frame wraps an SBFrame from its input frames, that SBFrame
finds its frame by StackID in the unwinder list, so it now resolves back
to the scripted frame itself, and forwarding a call such as
GetFunctionName to it recurses until the stack runs out. On macOS,
Python's recursion guard stops the loop after about 500 levels and
ScriptedFrame::GetFunctionName falls back to the symbol context, which
hides the bug. On Windows the native stack overflows first, and
TestFrameProviderStepping.py crashes.

This patch solves that by keeping the previous unwinder frame list
separate and creating every unwinder frame list from it. In the merge,
we now only adopt a previous frame that a list with the same identifier
produced.

This only affects the unwinder stack frame list: synthetic stack frame
lists build their frames from the provider at every stop and never merge
with their previous list. We still need m_prev_frames_sp, though: thread
plans record how many inlined frames to hide on the top list, and the
synthetic lists created at the next stop carry that count over.

Fixes llvm#234888
Assisted-by: Claude

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
DeanSturtevant1 pushed a commit that referenced this pull request Nov 2, 2026
…LSHR (llvm#235013)

If bit `Lsb` of a value is known to be a copy of its sign bit
(`computeNumSignBits(Src) >= BitWidth - Lsb`), a 1-bit `G_UBFX` of that
bit is the same as a `G_LSHR` by `BitWidth - 1`, which can fold into
users such as `G_ADD`.

```llvm
define i16 @test(i16 %a) {
  %r = sdiv i16 %a, 7
  ret i16 %r
}
```

Before (6 instructions):
```
sxth w8, w0
mov  w9, llvm#18725
mul  w8, w8, w9
asr  w8, w8, llvm#17
ubfx w9, w8, llvm#15, #1
add  w0, w8, w9
```

After (5 instructions, same as SelectionDAG):
```
sxth w8, w0
mov  w9, llvm#18725
mul  w8, w8, w9
asr  w8, w8, llvm#17
add  w0, w8, w8, lsr llvm#31
```

CC: @davemgreen
DeanSturtevant1 pushed a commit that referenced this pull request Nov 11, 2026
llvm#239799)

…(llvm#230468)"

This reverts commit 612fdc5.

With

https://github.com/google/ml-compiler-opt/releases/tag/regalloc-evict-v1.1,
this patch causes us to run out of registers on x86 when compiling
certain functions:
```bash
clang -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -O3 -disable-llvm-passes -mllvm -regalloc-enable-advisor=release -o /dev/null %s
```

```llvm
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #0

define fastcc void @snork(ptr %arg, ptr %arg1, ptr %arg2, ptr %arg3, ptr %arg4, i64 %arg5, i64 %arg6, i64 %arg7, i64 %arg8, ptr %arg9, ptr %arg10, i64 %arg11, i1 %arg12, i1 %arg13, i64 %arg14, i64 %arg15, i64 %arg16) #1 {
bbl:
  %load = load ptr, ptr null, align 8
  call void null(ptr null, ptr %load)
  %mul = mul i64 %arg5, %arg5
  %mul17 = mul i64 %mul, %arg8
  %mul18 = mul i64 %mul17, %arg7
  %mul19 = mul i64 %mul18, %arg6
  %load20 = load i64, ptr %arg, align 8
  %mul21 = mul i64 %arg11, %load20
  %mul22 = mul i64 %mul21, %arg11
  %load23 = load i64, ptr %arg2, align 8
  %icmp = icmp eq i64 %load23, 0
  %load24 = load i64, ptr %arg10, align 8
  %icmp25 = icmp slt i64 %load24, 0
  %select = select i1 %icmp25, i1 false, i1 %arg12
  %load26 = load i64, ptr %arg9, align 8
  %icmp27 = icmp slt i64 %load26, 0
  %mul28 = mul i64 %arg7, %arg15
  %mul29 = mul i64 %arg15, %mul28
  %icmp30 = icmp slt i64 %load23, 0
  %icmp31 = icmp eq i64 0, %arg5
  %select32 = select i1 %icmp30, i1 false, i1 %icmp31
  %mul33 = mul i64 %load23, %mul29
  %load34 = load i64, ptr %arg1, align 8
  %icmp35 = icmp slt i64 %load34, 0
  %icmp36 = icmp eq i64 0, %mul33
  %select37 = select i1 %icmp35, i1 false, i1 %icmp36
  %load38 = load i64, ptr null, align 8
  %icmp39 = icmp slt i64 %load38, 0
  %mul40 = mul i64 %load34, %mul33
  %icmp41 = icmp eq i64 %arg16, %mul40
  %select42 = select i1 %icmp39, i1 false, i1 %icmp41
  %icmp43 = icmp slt i64 %arg14, 0
  %mul44 = mul i64 %load38, %mul40
  %icmp45 = icmp eq i64 %load20, %mul44
  %select46 = select i1 %icmp43, i1 true, i1 %icmp45
  %select47 = select i1 %select46, i1 %select42, i1 false
  %select48 = select i1 %select47, i1 %select37, i1 false
  %select49 = select i1 %select48, i1 %select32, i1 false
  %select50 = select i1 %select49, i1 %icmp27, i1 false
  %select51 = select i1 %select50, i1 %select, i1 false
  %select52 = select i1 %select51, i1 %icmp, i1 false
  %zext = zext i1 %select52 to i8
  store ptr %load, ptr null, align 8
  call void @llvm.memcpy.p0.p0.i64(ptr null, ptr null, i64 64, i1 false)
  store i64 %mul22, ptr poison, align 8
  store i64 %mul19, ptr null, align 8
  store i64 0, ptr poison, align 8
  store i64 %mul17, ptr null, align 8
  store i64 %arg5, ptr %arg, align 8
  store i64 %mul, ptr null, align 8
  store i64 %arg5, ptr %arg, align 8
  store i64 0, ptr null, align 8
  store i8 %zext, ptr null, align 8
  br i1 %arg13, label %bbl54, label %bbl53

bbl53:                                            ; preds = %bbl
  ret void

bbl54:                                            ; preds = %bbl
  ret void
}

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #1 = { "frame-pointer"="non-leaf-no-reserve" "target-features"="+avx" "tune-cpu"="haswell" }
```

Produces
```
error: <unknown>:0:0: ran out of registers during register allocation in function 'snork'
```
DeanSturtevant1 pushed a commit that referenced this pull request Nov 11, 2026
BPFASpaceCastSimplifyPass rewrites
`addrspacecast M->N (getelementptr (addrspacecast N->M p))` to
`getelementptr p`. When the inner cast has no other uses, the rewrite
erases it. That cast can also be the outer cast of another chain that is
still in the worklist. The pass then reads the erased cast. Clang
crashes on this code:

```c
#define __arena __attribute__((address_space(1)))

struct hdr { int len; int flags; };
int use(int *p);

int f(void __arena *buf, long off)
{
	struct hdr __arena *h = (struct hdr __arena *)((char *)buf + off);
	return use((int *)&h->flags);
}
```

```console
$ clang --target=bpfel -O2 -c bpf.c
devtools (dce2167): crash, SIGSEGV, Running pass "bpf-aspace-simplify" on function "test"
...
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace and dumped files.
Stack dump:
0.      Program arguments: clang --target=bpfel -O2 -c bpf.c -o bpf.o
1.      <eof> parser at end of file
2.      Optimizer
3.      Running pass "function<eager-inv>(mem2reg,instcombine<max-iterations=1;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;no-switch-ra
4.      Running pass "bpf-aspace-simplify" on function "test"
 #0 0x0000000001f89b00 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/data/users/yatsenko/devtools/llvm/20261014/bin/clang-24+0x1f89b00)
 #1 0x0000000001f8786c llvm::sys::CleanupOnSignal(unsigned long) (/data/users/yatsenko/devtools/llvm/20261014/bin/clang-24+0x1f8786c)
 #2 0x0000000001ecc4f0 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 llvm#3 0x00007f268bc3fb30 __restore_rt (/lib64/libc.so.6+0x3fb30)
...
llvm#33 0x0000000000c390a5 _start (/data/users/yatsenko/devtools/llvm/20261014/bin/clang-24+0xc390a5)
clang: error: clang frontend command failed due to signal (use -v to see invocation)
clang version 24.0.0git (https://github.com/llvm/llvm-project.git dce2167)
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant