[AArch64][SelectionDAG] scalar_to_vector(anyextload i8) not matched by ExtLoad8_16AllModes patterns — root gap behind the neon-dotreduce regression in #217185 (workaround in place)
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
Background
PR #217185 fixes ISD::SCALAR_TO_VECTOR upper-element poison semantics. During its development a codegen regression surfaced in llvm/test/CodeGen/AArch64/neon-dotreduce.ll: the lane-32 i8 load degraded from a direct ldr b (FPR) to ldrb w8 + fmov s1, w8 (GPR→FPR move). Per review feedback (@RKSimon), this is tracked separately rather than folded into #217383 (verified unrelated — no aext(freeze(load)) shape involved).
Root-cause chain (from instrumented-build analysis in #217185)
1. With corrected PoisonOnly queries, the build_vector → AND/OR-mask fold in DAGCombiner now (correctly) freezes its source vector: getFreeze(CurVec, InsertedEltMask, PoisonOnly) can no longer elide the freeze because masked-off lanes trace back to the SCALAR_TO_VECTOR poison lanes.
2. visitFREEZE pushes the freeze down through the zext/extract chain, RAUW'ing users of the stv to freeze(stv(extload i8)).
3. SimplifyDemandedVectorElts' freeze(stv(x)) → stv(freeze(x)) fold (DemandedElts == 1) sinks the freeze below SCALAR_TO_VECTOR → stv(freeze(extload)). freeze(load) can never be dropped (a load is only poison-free with !noundef), and AArch64 ExtLoad8_16AllModes patterns only cover zextload/extload — so ISel stops matching.
Workaround currently in #217185 (note per review request)
TargetLowering::SimplifyDemandedVectorElts skips the freeze-through-stv sink when the scalar operand is a load: freeze(stv(load)) is equivalent for demanded element 0 and keeps the load visible to ISel patterns. This restores ldr b and removed the test diff, but it is a targeted workaround, not a root fix.
Remaining gaps / follow-up directions
- Add anyextload variants to ExtLoad8_16AllModes (safe: LDRBui/LDURBi zero-extend, which satisfies anyext semantics), and/or
- Add a combine forming an ext/zextload for scalar_to_vector(load) when only element 0 is demanded.
Once either lands, the SimplifyDemandedVectorElts workaround can be revisited/removed.
Related: #217185 (context + workaround), #155270 (separate: bfloat.ll PR92471 ZERO_EXTEND_VECTOR_INREG handling), #217383 (confirmed unrelated).
Contributor guide
Research direction
Start with llvm/test/CodeGen/AArch64/neon-dotreduce.ll and trace the ExtLoad8_16AllModes patterns and SimplifyDemandedVectorElts entry point described in the issue. Determine whether adding anyextload coverage or forming an ext/zextload for scalar_to_vector(load) resolves the regression, then verify that the test selects direct ldr b codegen and that the existing workaround can be revisited.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100