Luke Lau c2a879ecaa
[VPlan] Fix VPTypeAnalysis cache clobbering in EVL transform (#120252)
When building SPEC CPU 2017 with RISC-V and EVL tail folding, this
assertion in VPTypeAnalysis would trigger during the transformation to
EVL recipes:


d8a0709b10/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp (L135-L142)

It was caused by this recipe:

```
WIDEN ir<%shr> = vp.or ir<%add33>, ir<0>, vp<%6>
```

Having its type inferred as i16, when ir<%add33> and ir<0> had inferred
types of i32 somehow.

The cause of this turned out to be because the VPTypeAnalysis cache was
getting clobbered: In this transform we were erasing recipes but keeping
around the same mapping from VPValue* to Type*. In the meantime, new
recipes would be created which would have the same address as the old
value. They would then incorrectly get the old erased VPValue*'s cached
type:

```
  --- before ---
  0x600001ec5030: WIDEN ir<%mul21.neg> = vp.mul vp<%11>, ir<0>, vp<%6>
  0x600001ec5450: <badref> <- some value that was erased
  --- after ---
  0x600001ec5030: WIDEN ir<%mul21.neg> = vp.mul vp<%11>, ir<0>, vp<%6>
  0x600001ec5450: WIDEN ir<%shr> = vp.or ir<%add33>, ir<0>, vp<%6>  <- a new value that happens to have the same address
```

This fixes this by deferring the erasing of recipes till after the
transformation.

The test case might be a bit flakey since it just happens to have the
right conditions to recreate this. I tried to add an assert in
inferScalarType that every VPValue in the cache was valid, but couldn't
find a way of telling if a VPValue had been erased.

---------

Co-authored-by: Florian Hahn <flo@fhahn.com>
2024-12-18 11:28:28 +08:00
..