Skip to content

LLVM21: ARM64 sve2 vector reduce recursion fix - #9396

Closed
mcourteaux wants to merge 2 commits into
mcourteaux/llvm21-load-elim-workaroundfrom
mcourteaux/sve2-vector-reduce-recursion-fix
Closed

LLVM21: ARM64 sve2 vector reduce recursion fix#9396
mcourteaux wants to merge 2 commits into
mcourteaux/llvm21-load-elim-workaroundfrom
mcourteaux/sve2-vector-reduce-recursion-fix

Conversation

@mcourteaux

@mcourteaux mcourteaux commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Claude Sonnet:

Before LLVM 22, LLVM's llvm.vector.reduce.mul intrinsic lowering isn't
available for scalable (SVE) vectors, so CodeGen_LLVM::codegen_vector_reduce
always falls back to decomposing VectorReduce::Mul into halving stages for
this case (see the mul_ok check there). CodeGen_ARM::codegen_across_vector_reduce
doesn't know about this: whenever it's re-entered on one of those halving
stages, it sees a lane count that isn't a multiple of the native vector
width (because the "width" is really an intermediate reduce result, not
raw data) and pads it up to a native-width multiply-reduce, which routes
back into the same halving decomposition. Padding and halving alternate
forever without ever reaching a terminating case, hanging the compiler.

See commit message for more info.

Fixes the hang rediscovered in #9374

Breaking changes

Un-breaking: LLVM 21 works now more?

Checklist

  • Tests added or updated (not required for docs, CI config, or typo fixes)
  • Documentation updated (if public API changed)
  • Python bindings updated (if public API changed)
  • Benchmarks are included here if the change is intended to affect performance.
  • Commits include AI attribution where applicable (see Code of Conduct)

mcourteaux and others added 2 commits August 26, 2026 09:01
… 22.

Before LLVM 22, LLVM's llvm.vector.reduce.mul intrinsic lowering isn't
available for scalable (SVE) vectors, so CodeGen_LLVM::codegen_vector_reduce
always falls back to decomposing VectorReduce::Mul into halving stages for
this case (see the `mul_ok` check there). CodeGen_ARM::codegen_across_vector_reduce
doesn't know about this: whenever it's re-entered on one of those halving
stages, it sees a lane count that isn't a multiple of the native vector
width (because the "width" is really an intermediate reduce result, not
raw data) and pads it up to a native-width multiply-reduce, which routes
back into the same halving decomposition. Padding and halving alternate
forever without ever reaching a terminating case, hanging the compiler.

Confirmed against a real LLVM 21.1.8 build: the compiler hangs
deterministically compiling a VectorReduce::Mul reduction on an SVE2
target before this change, and converges immediately after it. A full
sweep of the type/lane/op combinations exercised by
test/correctness/vector_reductions.cpp also compiles cleanly with the
fix applied.

Since the native intrinsic can't be used for this op/target/LLVM-version
combination regardless, defer entirely to the base class's decomposition,
which does not have this problem.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The previous commit fixes the infinite recursion in
CodeGen_ARM::codegen_across_vector_reduce that this skip was working
around, so the test no longer needs to be skipped under LLVM < 22.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@mcourteaux mcourteaux changed the title Mcourteaux/sve2 vector reduce recursion fix LLVM21: ARM64 sve2 vector reduce recursion fix Aug 26, 2026
@codecov

codecov Bot commented Aug 26, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.09%. Comparing base (a68de1f) to head (36d27cd).

Files with missing lines Patch % Lines
src/CodeGen_ARM.cpp 0.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@                           Coverage Diff                           @@
##           mcourteaux/llvm21-load-elim-workaround    #9396   +/-   ##
=======================================================================
  Coverage                                   70.08%   70.09%           
=======================================================================
  Files                                         261      261           
  Lines                                       79370    79372    +2     
  Branches                                    19350    19351    +1     
=======================================================================
+ Hits                                        55629    55633    +4     
- Misses                                      17906    17911    +5     
+ Partials                                     5835     5828    -7     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@alexreinking

Copy link
Copy Markdown
Member

I think the original approach of disabling SVE2 on LLVM 21 was the right one. There's no reason to believe this is exhaustive.

@mcourteaux mcourteaux closed this Aug 27, 2026
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.

2 participants