[mlir][sparse] Fix crash on linalg ops with buffer semantics (#216458)
Fixes #216215
## The problem
`mlir-opt --sparse-gpu-codegen` crashes on valid input:
```
Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
```
The pass looks for `linalg.generic` ops shaped like a matmul so it can
turn them into GPU library calls. Its checks only look at the *shape* of
the operation (loop count, iterator types, indexing maps, the
multiply-add body) — none of them check whether the operands are tensors
or memrefs.
Sparsity only exists on tensors, so when the pass then asks "is this
operand a dense tensor?", it casts the operand type to
`RankedTensorType`. If the op has buffer semantics, that operand is a
`memref`, and the cast asserts.
## The fix
Reject ops with buffer semantics before any of that happens:
```cpp
if (!op.hasPureTensorSemantics())
return failure();
```
`return failure()` just means "this pattern doesn't apply here", so the
op is left alone — the correct outcome for memrefs.
This is the same guard the linalg patterns in `SparseReinterpretMap.cpp`
and `SparseTensorRewriting.cpp` already use. Putting it at the entry
point covers every rewrite reached through this pattern (SpMV, SpMM,
SpGEMM, SDDMM, 2:4-SpMM), since they all share it.
## Testing
Added `mlir/test/Dialect/SparseTensor/GPU/gpu_buffer_semantics.mlir`
with the matmul case from the issue plus a matvec case, checking the ops
are left untouched.
Verified with an assertions-enabled build:
- the reproducer aborts before the fix and exits cleanly after
- the new test fails without the fix and passes with it
- `mlir/test/Dialect/SparseTensor` is 114/114, no regressions