LLVM/project f60fdbf — llvm/lib/Transforms/Vectorize VPlanTransforms.cpp, llvm/test/Transforms/LoopVectorize early-exit-tail-folding.ll

[VPlan] Remove header masks whose tail lanes aren't used

Replace a use of header-mask && x with x if the user, transitively
through freeze, logical-and, not and mask.beforefirst(freeze ...), only
reaches masks that are and'ed with the header mask again. The header
mask is a prefix and lane i of mask.beforefirst only depends on lanes
0..i, so the lanes outside of the header mask are never used.

This avoids the i1 vp.merge that EVL tail folding needs for the inner
header mask, e.g. in the early exit mask.beforefirst(freeze(header-mask
&& c)) and in switch default edges.
DeltaFile
+39-0llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+2-4llvm/test/Transforms/LoopVectorize/early-exit-tail-folding.ll
+2-4llvm/test/Transforms/LoopVectorize/RISCV/early_exit_with_stores.ll
+2-4llvm/test/Transforms/LoopVectorize/RISCV/early-exit.ll
+1-2llvm/test/Transforms/LoopVectorize/RISCV/zvl1024b-crash.ll
+46-145 files

LLVM/project 517ed7f — llvm/test/Transforms/LoopVectorize early-exit-tail-folding.ll

Precommit tests
DeltaFile
+214-153llvm/test/Transforms/LoopVectorize/early-exit-tail-folding.ll
+214-1531 files

LLVM/project 3357b41 — llvm/lib/Transforms/Vectorize VPlanConstruction.cpp, llvm/test/Transforms/LoopVectorize multiple-early-exits.ll early-exit-tail-folding.ll

[VPlan] Support tail folding uncountable early exits

Enables the first step towards #179595. After #237254, the MaskedHandleExitInVectorLoop early exit style uses the CFG to handle masking for early exit loops. This allows it to compose with tail folding which is also handled via the CFG in #176143.

This allows us to tail fold the following loop:

```c
extern char x[256];
int f(char * restrict y) {
  for (int i = 0; i < 256; i++) {
    if (x[i] == 0)
      return i;
  }
  return -1;
}
```

Into this on RISC-V:


    [18 lines not shown]
DeltaFile
+91-164llvm/test/Transforms/LoopVectorize/RISCV/early-exit-live-out.ll
+77-149llvm/test/Transforms/LoopVectorize/RISCV/early-exit.ll
+54-105llvm/test/Transforms/LoopVectorize/early-exit-tail-folding.ll
+108-16llvm/test/Transforms/LoopVectorize/multiple-early-exits.ll
+20-37llvm/test/Transforms/LoopVectorize/RISCV/sink-to-early-exit.ll
+32-18llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp
+382-4894 files not shown
+414-49710 files

LLVM/project e220882 — llvm/test/Transforms/LoopVectorize early-exit-tail-folding-active-lane-mask.ll early-exit-tail-folding.ll, llvm/test/Transforms/LoopVectorize/RISCV early-exit.ll

Precommit tests
DeltaFile
+552-0llvm/test/Transforms/LoopVectorize/RISCV/early-exit.ll
+524-0llvm/test/Transforms/LoopVectorize/early-exit-tail-folding.ll
+65-0llvm/test/Transforms/LoopVectorize/early-exit-tail-folding-active-lane-mask.ll
+1,141-03 files

LLVM/project 8bf2876 — llvm/lib/Transforms/Vectorize LoopVectorizationLegality.cpp LoopVectorize.cpp, llvm/test/Transforms/LoopVectorize early_exit_store_legality.ll early-exit-tail-folding.ll

[VPlan] Allow tail folding early exits with side effects

Continues the work in #179595.

This allows us to tail fold e.g. the following loop:

```c
extern char a[1024], b[1024], c[1024], y[1024];
void two_guards(void) {
  for (int i = 0; i < 1000; i++) {
    if (a[i] == 0)
      break;
    if (b[i] > 3) {
      if (c[i] < 9)
        y[i] = 1;
    }
  }
}
```

    [30 lines not shown]
DeltaFile
+40-70llvm/test/Transforms/LoopVectorize/early-exit-tail-folding.ll
+24-41llvm/test/Transforms/LoopVectorize/RISCV/early_exit_with_stores.ll
+18-35llvm/test/Transforms/LoopVectorize/RISCV/early-exit.ll
+24-0llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+0-7llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
+2-2llvm/test/Transforms/LoopVectorize/early_exit_store_legality.ll
+108-1552 files not shown
+111-1578 files

LLVM/project 7b44787 — llvm/test/Transforms/LoopVectorize early_exit_with_stores.ll

Precommit tests
DeltaFile
+221-0llvm/test/Transforms/LoopVectorize/early_exit_with_stores.ll
+221-01 files

LLVM/project b456685 — llvm/unittests/Transforms/Vectorize VPlanVerifierTest.cpp

Remove old dominance unit test
DeltaFile
+0-18llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp
+0-181 files

LLVM/project 13564dd — llvm/lib/Transforms/Vectorize VPlanVerifier.cpp VPlanTransforms.cpp, llvm/test/Transforms/LoopVectorize predicated-single-exit.ll predicated-early-exits-interleave.ll

[VPlan] Preserve SSA in early exit loops

MaskedCond is used to logically-and the condition to early exit with the current block in-mask. However because we use it in the latch block where the condition isn't defined on all paths, we have to workaround it not being in SSA in the verifier.

This fixes this by using reconstructSSA added in #212209 to preserve SSA in both the exit conditions and live outs in the exit blocks. It also means we get the right exit condition without MaskedCond and allows us to remove the MaskedCond exceptions in the verifier. MaskedCond is still kept since a followup PR will still use it.

One subtle point is that we need to freeze any branch conditions. Any lanes after and including the early exiting lane might contain poison and we can have branches on those poison lanes that didn't we didn't previously branch on in the scalar loop.

There's no miscompile on main today because we coincidentally don't keep SSA so exit conditions are read directly without being polluted by poison stemming from a branch past the early exit. But in this PR the exit conditions are polluted and we can end up with poison in the condition operand of a select, which causes an undefined result for AnyOf even if it freezes its operand. The poison in the branch will also cause problems in future if we decide to preserve uniform control flow and emit branches instead of blends. The exit_cond_merged_after_poison_branch test illustrates this.
DeltaFile
+156-36llvm/test/Transforms/LoopVectorize/predicated-multiple-exits.ll
+24-16llvm/test/Transforms/LoopVectorize/predicated-early-exits-interleave.ll
+26-9llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+1-18llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
+12-6llvm/test/Transforms/LoopVectorize/predicated-single-exit.ll
+219-855 files

LLVM/project 558bc4c — llvm/lib/Transforms/Vectorize VPlan.h VPlanTransforms.cpp, llvm/test/Transforms/LoopVectorize early_exit_with_stores.ll

[VPlan] Allow early exit loops with side effects by masking in the vector loop.

When all blocks with side effects are dominated by every early exit, we can vectorize the loop if we mask off any lanes past the exit. We can do this with control flow:

```mermaid
flowchart TD
  header --> exiting
  exiting -->| exit mask | sideeffects --> latch --> latch.split
  exiting -->| !exit mask | latch.split
```

For every early exiting block we add a branch to the latch on `!mask.beforefirst(exitcond)`. This is implemented in UncountableExitStyle::ReadOnly which is now renamed to MaskedHandleExitInVectorLoop.

This is a complementary exit style to MaskedHandleExitInScalarLoop. If any of the side effects aren't dominated by the early exit it still falls back to the scalar loop style, which is why none of the existing early exit side effect tests changed. Masking in loop is profitable for RISC-V and I'm assuming it's also profitable for AArch64 too, but if not then we can add a TTI hook for a preferred exit style.
DeltaFile
+59-76llvm/test/Transforms/LoopVectorize/early_exit_with_stores.ll
+86-33llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+10-8llvm/test/Transforms/LoopVectorize/X86/early_exit_with_stores.ll
+8-7llvm/test/Transforms/LoopVectorize/RISCV/early_exit_with_stores.ll
+5-4llvm/lib/Transforms/Vectorize/VPlan.h
+3-2llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp
+171-1302 files not shown
+176-1328 files

LLVM/project bbfbc89 — llvm/lib/Transforms/Vectorize VPlanConstruction.cpp LoopVectorize.cpp

[VPlan] Use vputils::findCanonicalIVIncrement in more places. NFC

In a future patch we want to enable more scenarios with early exits and tail folding. In these scenarios the terminator will no longer be a BranchOnCount/BranchOnCond but a BranchOnTwoConds, so a bunch of canonical IV matchers break. Use vputils::findCanonicalIVIncrement instead since it searches the users of the canonical IV instead of looking at the terminator.
DeltaFile
+7-13llvm/lib/Transforms/Vectorize/VPlanEVLTailFolding.cpp
+2-9llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+2-8llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp
+11-303 files

LLVM/project 139d27f — llvm/lib/Transforms/Vectorize VPlanPredicator.cpp, llvm/test/Transforms/LoopVectorize uniform-blend.ll select-cmp-blend-chain.ll

[VPlan] Peek through nested phi incoming values in computeBlendMasks
DeltaFile
+495-0llvm/test/Transforms/LoopVectorize/predicator.ll
+389-6llvm/test/Transforms/LoopVectorize/VPlan/predicator.ll
+80-11llvm/lib/Transforms/Vectorize/VPlanPredicator.cpp
+81-0llvm/test/Transforms/LoopVectorize/find-last.ll
+13-3llvm/test/Transforms/LoopVectorize/select-cmp-blend-chain.ll
+3-12llvm/test/Transforms/LoopVectorize/uniform-blend.ll
+1,061-326 files

LLVM/project d7f7e75 — llvm/lib/Transforms/Vectorize VPlanTransforms.cpp, llvm/test/Transforms/LoopVectorize blend-i1.ll

[VPlan] Simplify BLEND X/M, false, ..., false -> M && X

If an i1 blend has false for all but one incoming value, then we can simplify this to the one non-false value. Blends by construction never have any overlapping mask values, so we don't need to worry about the order as the masks can't "shortcut" each other.
DeltaFile
+13-0llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+3-8llvm/test/Transforms/LoopVectorize/blend-i1.ll
+16-82 files

LLVM/project 2236f38 — llvm/lib/Transforms/Vectorize LoopVectorize.cpp VPlanUnroll.cpp, llvm/test/Transforms/LoopVectorize interleave_uncountable_exits.ll

[VPlan] Support interleaving early exit loops with side effects

We couldn't do this on main previously because the exit mask `active-lane-mask(0, FirstActiveLane(Cond))` doesn't get unrolled properly across parts. Now that we use mask.beforefirst we can unroll it properly in a chain. The unrolled form is:

    unroll(mask.beforefirst, P) = mask.beforefirst(cond[P] | broadcast(anyof(not(unroll(mask.beforefirst, P-1)))))

On AArch64 this can be combined to brkpb in another patch.
DeltaFile
+216-15llvm/test/Transforms/LoopVectorize/AArch64/early_exit_with_stores.ll
+106-7llvm/test/Transforms/LoopVectorize/interleave_uncountable_exits.ll
+35-4llvm/test/Transforms/PhaseOrdering/AArch64/countable-and-uncountable-exits-combined.ll
+10-0llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp
+10-0llvm/lib/Transforms/Vectorize/VPlanLowering.cpp
+0-9llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+377-356 files

LLVM/project f6aa241 — llvm/test/Transforms/LoopVectorize blend-i1.ll

Precommit tests
DeltaFile
+69-0llvm/test/Transforms/LoopVectorize/blend-i1.ll
+69-01 files

LLVM/project 2522d53 — llvm/lib/Transforms/Vectorize VPlanTransforms.cpp, llvm/test/Transforms/LoopVectorize interleave_uncountable_exits.ll

[VPlan] Move extract-lane(0, canWideIV) combine before unrolling

Some extract-lane combines can't be performed before unrolling, e.g. the one that combines it to Instruction::ExtractElement can end up extracting from a different part. But the extract-lane(0, canWideIV) can because at index 0 you're always extracting from the first part. Do this before unrolling, which improves codegen of unrolled code.
DeltaFile
+5-80llvm/test/Transforms/LoopVectorize/AArch64/early_exit_with_stores.ll
+16-24llvm/test/Transforms/LoopVectorize/VPlan/early_exit_with_stores_vplan.ll
+4-12llvm/test/Transforms/LoopVectorize/interleave_uncountable_exits.ll
+6-6llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+1-8llvm/test/Transforms/PhaseOrdering/AArch64/countable-and-uncountable-exits-combined.ll
+32-1305 files

LLVM/project f4e052a — llvm/lib/Transforms/Vectorize LoopVectorize.cpp VPlanTransforms.h, llvm/test/Transforms/LoopVectorize/X86 early_exit_with_stores.ll

Expand mask.beforefirst if not cheap
DeltaFile
+34-0llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+4-4llvm/test/Transforms/LoopVectorize/X86/early_exit_with_stores.ll
+6-0llvm/lib/Transforms/Vectorize/VPlanTransforms.h
+4-0llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+48-44 files

LLVM/project 7eadcc7 — llvm/lib/Transforms/Vectorize VPlanRecipes.cpp, llvm/test/Transforms/LoopVectorize early_exit_combined_exits.ll early_exit_with_stores.ll

[VPlan] Use llvm.mask.beforefirst for computing early exit mask

This makes the cost more accurate and improves codegen for RISC-V. The codegen for an early exit loop with side effects then goes from:

    .LBB0_3:                                # %vector.body
                                            # =>This Inner Loop Header: Depth=1
        vl1r.v  v16, (a3)
        vsetvli zero, zero, e8, m1, ta, ma
        vmseq.vi        v16, v16, 0
        vfirst.m        a7, v16
        srli    t0, a7, 63
        czero.nez       a7, a7, t0
        czero.eqz       t0, a1, t0
        or      a7, t0, a7
        vsetvli zero, zero, e64, m8, ta, ma
        vmsltu.vx       v0, v8, a7
        vle8.v  v17, (a5), v0.t
        vcpop.m t1, v16
        vsetvli zero, zero, e8, m1, ta, ma

    [22 lines not shown]
DeltaFile
+50-50llvm/test/Transforms/LoopVectorize/AArch64/early_exit_with_stores.ll
+40-40llvm/test/Transforms/LoopVectorize/VPlan/early_exit_with_stores_vplan.ll
+23-23llvm/test/Transforms/LoopVectorize/RISCV/early_exit_with_stores.ll
+18-18llvm/test/Transforms/LoopVectorize/early_exit_with_stores.ll
+21-0llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+8-8llvm/test/Transforms/LoopVectorize/early_exit_combined_exits.ll
+160-1398 files not shown
+183-16114 files

LLVM/project bfdc712 — llvm/lib/Transforms/Vectorize VPlan.h VPlanTransforms.cpp, llvm/test/Transforms/LoopVectorize/VPlan early_exit_with_stores_vplan.ll

Emit VPWidenIntrinsicRecipe
DeltaFile
+56-56llvm/test/Transforms/LoopVectorize/VPlan/early_exit_with_stores_vplan.ll
+0-21llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+9-0llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h
+2-2llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+0-3llvm/lib/Transforms/Vectorize/VPlan.h
+67-825 files

LLVM/project 3a331ee — llvm/lib/Transforms/Vectorize VPlanRecipes.cpp VPlanTransforms.cpp

[VPlan] Lower MaskedCond earlier in the predicator. NFC (#238023)

A MaskedCond is used to logically-and some condition with the current
block in mask.

It's currently lowered in convertToConcreteRecipes but we can just do it
earlier in VPlanPredicator, which removes the need for the separate fold
in simplifyRecipe. It also enables more logical-and simplifications
earlier on.
DeltaFile
+15-2llvm/lib/Transforms/Vectorize/VPlanPredicator.cpp
+0-11llvm/lib/Transforms/Vectorize/VPlanLowering.cpp
+4-2llvm/lib/Transforms/Vectorize/VPlan.h
+0-5llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+2-0llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+21-205 files

LLVM/project deb738d — llvm/lib/IR Verifier.cpp, llvm/test/Verifier range-metadata.ll noundef-metadata.ll

[IR] Accept various metadata on phi nodes (#202877)

This patch allows adding `!nonnull`, `!noundef`, `!range`, `!nofpclass`,
`!dereferenceable`, `!dereferenceable_or_null` and `!align` metadata to
phi nodes.
DeltaFile
+25-0llvm/test/Verifier/dereferenceable-md.ll
+12-10llvm/lib/IR/Verifier.cpp
+14-2llvm/test/Verifier/nonnull-metadata.ll
+13-1llvm/test/Verifier/noundef-metadata.ll
+14-0llvm/test/Verifier/align-md.ll
+11-2llvm/test/Verifier/range-metadata.ll
+89-152 files not shown
+106-228 files

LLVM/project bb36d77 — llvm/lib/Target/LoongArch LoongArchISelLowering.cpp, llvm/test/CodeGen/LoongArch/lasx bitclr.ll

[LoongArch] Select [x]vbitclr for and-not of bitcasted shl(splat(1), y) (#241179)

When the shift of splat(1) is performed in a narrower element type than
the and-not, e.g.

```llvm
  %s = shl <8 x i16> splat (i16 1), %y
  %m = bitcast <8 x i16> %s to <2 x i64>
  %n = xor <2 x i64> %m, splat (i64 -1)
  %r = and <2 x i64> %x, %n
```

the VANDN node is created in v2i64 with a bitcast operand, so the
existing [x]vbitclr.{b/h/w} patterns fail to match and we emit vrepli +
vsll + vandn.v.

Fold VANDN(bitcast(shl(splat(1), y)), x) into
bitcast(VANDN(shl(splat(1), y), bitcast(x))) so that the operation is
done in the shift's element type and selected as a single [x]vbitclr.

Assisted-By: LLM
DeltaFile
+6-18llvm/test/CodeGen/LoongArch/lsx/bitclr.ll
+6-18llvm/test/CodeGen/LoongArch/lasx/bitclr.ll
+19-0llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+31-363 files

LLVM/project d006050 — llvm/test/CodeGen/LoongArch/lasx bitclr.ll, llvm/test/CodeGen/LoongArch/lsx bitclr.ll

[LoongArch][NFC] Pre-commit tests for [x]vbitclr through bitcast (#241178)

Add tests where the shift of splat(1) is done in a narrower element type
and then bitcast to the type of the and-not operation.

Assisted-By: LLM
DeltaFile
+99-0llvm/test/CodeGen/LoongArch/lsx/bitclr.ll
+99-0llvm/test/CodeGen/LoongArch/lasx/bitclr.ll
+198-02 files

LLVM/project aabf3a3 — flang/include/flang/Optimizer/CodeGen FIROpPatterns.h, flang/lib/Optimizer/CodeGen FIROpPatterns.cpp CodeGen.cpp

[flang] Give hoisted descriptor allocas the location of their region (#240953)

`genAllocaAndAddrCastWithType` hoists the alloca it creates into the
alloca block of the enclosing OpenMP region or function, but gave it the
location of the operation that needed it. When the alloca generates
code, the line table then shows that operation's line at the start of
the region, before the code that reaches it.

That happens on x86 for a descriptor load in the loop of a task:

```
  !$omp task
  do i = 1, 4
    x(i) = 2.0 * x(i)        ! x is allocatable
  end do
  !$omp end task

```
The alloca block of a task is not the entry block of the outlined

    [12 lines not shown]
DeltaFile
+65-0flang/test/Fir/alloca-hoist-loc.fir
+6-6flang/lib/Optimizer/CodeGen/CodeGen.cpp
+1-2flang/include/flang/Optimizer/CodeGen/FIROpPatterns.h
+2-1flang/lib/Optimizer/CodeGen/FIROpPatterns.cpp
+74-94 files

LLVM/project 2f93648 — llvm/lib/Transforms/Vectorize SLPVectorizer.cpp, llvm/test/Transforms/SLPVectorizer/AArch64 and-bsl-ctx-mixed-lanes.ll

[SLP] Pass a lane as the vector cost context only if all lanes agree

getEntryCost prices a vector instruction with one scalar lane as the
context, while each scalar lane is priced in its own context. A target
that reads the context, like the users of an fmul that fuses into an fma
on AMDGPU or a sibling udiv of a urem on X86, gives the whole vector the
property of that one lane.

Pass the lane as the context only if the vector cost is the same with any
of the represented lanes as the context.

Assisted-by: Claude Opus
DeltaFile
+103-31llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+21-7llvm/test/Transforms/SLPVectorizer/AMDGPU/fmul-fusion-ctx-mixed-lanes.ll
+23-4llvm/test/Transforms/SLPVectorizer/X86/urem-div-ctx-mixed-lanes.ll
+14-11llvm/test/Transforms/SLPVectorizer/AArch64/and-bsl-ctx-mixed-lanes.ll
+14-7llvm/test/Transforms/SLPVectorizer/AMDGPU/fdiv-afn-ctx-lanes.ll
+1-1llvm/test/Transforms/SLPVectorizer/X86/remark-alt-cmp-ctx-lanes.ll
+176-616 files

LLVM/project 6390174 — llvm/test/Transforms/SLPVectorizer/AArch64 and-bsl-ctx-mixed-lanes.ll, llvm/test/Transforms/SLPVectorizer/AMDGPU fmul-fusion-ctx-mixed-lanes.ll fdiv-afn-ctx-lanes.ll

[SLP][NFC] Add tests for the vector cost context of mixed lanes

Assisted-by: Claude Opus
DeltaFile
+98-0llvm/test/Transforms/SLPVectorizer/AMDGPU/fdiv-afn-ctx-lanes.ll
+81-0llvm/test/Transforms/SLPVectorizer/AArch64/and-bsl-ctx-mixed-lanes.ll
+62-0llvm/test/Transforms/SLPVectorizer/X86/remark-alt-cmp-ctx-lanes.ll
+53-0llvm/test/Transforms/SLPVectorizer/AMDGPU/fmul-fusion-ctx-mixed-lanes.ll
+51-0llvm/test/Transforms/SLPVectorizer/X86/urem-div-ctx-mixed-lanes.ll
+345-05 files

LLVM/project 4e8f741 — llvm/docs AMDGPUUsage.md

[AMDGPU][docs] Minor clean-ups for the GFX12.5 memory model docs (#239156)

- Use `GFX12.5` everywhere instead of a mix of `gfx125x` and others.
- Remove "WIP" disclaimer. The model hasn't seen huge changes in a
while. The remaining items are documented separately in their own
documents.
DeltaFile
+65-73llvm/docs/AMDGPUUsage.md
+65-731 files

LLVM/project b688e2e — llvm/test/CodeGen/AMDGPU/GlobalISel llvm.amdgcn.raw.tbuffer.store.ll regbanklegalize-amdgcn.s.buffer.load.subdword.ll

[AMDGPU][GlobalISel] Use v_cmpx/s_andn2_wrexec form in RegBankLegalize waterfall loops

Port the UseNewExecInstructions path from SIInstrInfo's waterfall emission
to RegBankLegalizeHelper::executeInWaterfallLoop. On subtargets with
no-sdst v_cmpx and s_andn2_wrexec, the loop now narrows exec with deferred
V_CMPX_EQ_*_nosdst_e32_term compares and computes the remaining lanes with
S_ANDN2 from an exec PHI, written back by S_MOV_term. SIOptimizeExecMasking
then folds the pair into s_and_not1_wrexec, matching SelectionDAG.

Co-authored-by: Cursor <cursoragent at cursor.com>
DeltaFile
+552-290llvm/test/CodeGen/AMDGPU/GlobalISel/regbankselect-amdgcn.s.buffer.load.ll
+214-228llvm/test/CodeGen/AMDGPU/GlobalISel/regbanklegalize-amdgcn.s.buffer.load.ll
+169-183llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.intersect_ray.ll
+120-120llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.s.buffer.load.ll
+84-96llvm/test/CodeGen/AMDGPU/GlobalISel/regbanklegalize-amdgcn.s.buffer.load.subdword.ll
+81-87llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.raw.tbuffer.store.ll
+1,220-1,00440 files not shown
+2,110-2,15746 files

LLVM/project 23445b7 — llvm/lib/Target/X86 X86ISelLowering.cpp, llvm/test/CodeGen/X86 pmulh.ll

[X86] combineShiftToPMULH - fix lshr of sign-extended products on wider than i32 elements (#234420)

combineShiftToPMULH folds srl/sra(mul(ext a, ext b), 16) into
ext(mulh(a, b)), taking the outer extension from the shift kind. For i32
elements that works, but for wider elements the product's bits above 31
are copies of its sign bit (sext inputs) or zero (zext inputs). So srl
of a sign-extended i64 product was lowered to zext(pmulhw), which loses
bits 16..47 of negative products.

For elements wider than 32 bits I now extend the MULH result the same
way as the inputs. A logical shift of a sign-extended product also needs
its top 16 bits cleared, so that case becomes and(sext(mulhs),
0x0000FFFFFFFFFFFF) and still uses pmulhw. Simply bailing out also fixes
it, but on SSE2 the test then grows to a long pmuludq sequence, so I
kept the fold.

The first commit adds a zext/ashr i64 test. That case was already
correct, since the generic combine turns the ashr into lshr first. I
checked the new codegen natively for SSE2/SSE4.1/AVX2/AVX512F/AVX512BW

    [5 lines not shown]
DeltaFile
+86-18llvm/test/CodeGen/X86/pmulh.ll
+14-0llvm/lib/Target/X86/X86ISelLowering.cpp
+100-182 files

LLVM/project b29a459 — llvm/lib/DebugInfo/DWARF/LowLevel DWARFCFIProgram.cpp

[DebugInfo][DWARF] Make CFIProgram::getOperandTypes() table constexpr (#227684)

Previously getOperandTypes() lazily filled a static table, but set its
flag before filling it, so a thread calling it concurrently with the
first call could return a partially filled table.

The table is now constexpr, so there is no runtime initialization for
concurrent callers to race on.

Assisted-by: Claude Opus 5.5

Signed-off-by: Steffen Holst Larsen <sholstla at amd.com>
DeltaFile
+43-42llvm/lib/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.cpp
+43-421 files

LLVM/project 16da446 — clang/include/clang/StaticAnalyzer/Core/PathSensitive CheckerContext.h

[analyzer] Correct logic in 3-param addTransition (#241415)

The method `CheckerContext::addTransition` should create a new exploded
node when (1) there was a state change or (2) an explicit non-null `Tag`
is specified.

However, in the 3-parameter overload (which accepts an exploded node
`Pred` to allow chaining transitions) this logic compared the `State` to
`getState()` (the state at the construction of `CheckerContext`) and
returned early with `getPredecessor()` (the node that was passed to the
constructor of `CheckerContext`) instead of `Pred`.

This commit corrects this oversight by using `Pred` and its state -- but
preserves the corner case that a null `Pred` is accepted and handled as
if it was `getPredecessor()`. (Note that passing a null node to
`addTransitionImpl` is equivalent to passing `getPredecessor()`, some
checkers -- at least `FuchsiaHandleChecker` leak reporting -- rely on
that `addTransition` can gracefully handle a null node argument.)


    [4 lines not shown]
DeltaFile
+9-12clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+9-121 files