[Mlir-commits] [mlir] [mlir][SPIRV] Handle vector stores when unifying aliased resources (PR #232185)
Anutosh Bhat
llvmlistbot at llvm.org
Wed Oct 28 21:50:02 PDT 2026
https://github.com/anutosh491 updated https://github.com/llvm/llvm-project/pull/232185
>From 06733a8ffc8442aab7555c74587e3a9c9d8fc677 Mon Sep 17 00:00:00 2001
From: anutosh491 <andersonbhat491 at gmail.com>
Date: Thu, 15 Oct 2026 11:28:47 +0530
Subject: [PATCH 1/2] [mlir][SPIRV] Handle vector stores when unifying aliased
resources
Signed-off-by: anutosh491 <andersonbhat491 at gmail.com>
---
.../Transforms/UnifyAliasedResourcePass.cpp | 67 +++++++++-
.../Transforms/unify-aliased-resource.mlir | 120 ++++++++++++++++++
2 files changed, 181 insertions(+), 6 deletions(-)
diff --git a/mlir/lib/Dialect/SPIRV/Transforms/UnifyAliasedResourcePass.cpp b/mlir/lib/Dialect/SPIRV/Transforms/UnifyAliasedResourcePass.cpp
index 99eaa3f0b16654..2cc1f0a4a821a8 100644
--- a/mlir/lib/Dialect/SPIRV/Transforms/UnifyAliasedResourcePass.cpp
+++ b/mlir/lib/Dialect/SPIRV/Transforms/UnifyAliasedResourcePass.cpp
@@ -24,6 +24,7 @@
#include "mlir/Transforms/DialectConversion.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Alignment.h"
#include <iterator>
namespace mlir {
@@ -550,15 +551,69 @@ struct ConvertStore : public ConvertAliasResource<spirv::StoreOp> {
cast<spirv::PointerType>(storeOp.getPtr().getType()).getPointeeType();
auto dstElemType =
cast<spirv::PointerType>(adaptor.getPtr().getType()).getPointeeType();
- if (!srcElemType.isIntOrFloat() || !dstElemType.isIntOrFloat())
- return rewriter.notifyMatchFailure(storeOp, "not scalar type");
- if (!areSameBitwidthScalarType(srcElemType, dstElemType))
- return rewriter.notifyMatchFailure(storeOp, "different bitwidth");
-
Location loc = storeOp.getLoc();
Value value = adaptor.getValue();
- if (srcElemType != dstElemType)
+ auto srcVector = dyn_cast<VectorType>(srcElemType);
+ auto dstVector = dyn_cast<VectorType>(dstElemType);
+ if (srcVector && dstVector && srcVector != dstVector) {
+ if (srcVector.getElementTypeBitWidth() !=
+ dstVector.getElementTypeBitWidth() ||
+ srcVector.getNumElements() % dstVector.getNumElements() != 0)
+ return rewriter.notifyMatchFailure(storeOp,
+ "incompatible vector types");
+ auto acOp = adaptor.getPtr().getDefiningOp<spirv::AccessChainOp>();
+ if (!acOp)
+ return rewriter.notifyMatchFailure(storeOp,
+ "ptr not spirv.AccessChain");
+ if (srcVector.getElementType() != dstVector.getElementType())
+ value = spirv::BitcastOp::create(
+ rewriter, loc,
+ VectorType::get(srcVector.getShape(), dstVector.getElementType()),
+ value);
+ unsigned count = dstVector.getNumElements();
+ unsigned ratio = srcVector.getNumElements() / count;
+ unsigned bytes = count * dstVector.getElementTypeBitWidth() / 8;
+ for (unsigned i = 0; i < ratio; ++i) {
+ Value part = value;
+ if (ratio > 1) {
+ SmallVector<int32_t> components;
+ for (unsigned j = 0; j < count; ++j)
+ components.push_back(i * count + j);
+ part = spirv::VectorShuffleOp::create(
+ rewriter, loc, dstVector, value, value,
+ rewriter.getI32ArrayAttr(components));
+ }
+ Value ptr = adaptor.getPtr();
+ auto alignment = storeOp.getAlignmentAttr();
+ if (i) {
+ auto indices = llvm::to_vector(acOp.getIndices());
+ Type indexType = indices.back().getType();
+ auto offset = spirv::ConstantOp::create(
+ rewriter, loc, indexType, rewriter.getIntegerAttr(indexType, i));
+ indices.back() = spirv::IAddOp::create(rewriter, loc, indexType,
+ indices.back(), offset);
+ ptr = spirv::AccessChainOp::create(rewriter, loc, acOp.getBasePtr(),
+ indices);
+ if (alignment)
+ alignment = rewriter.getI32IntegerAttr(
+ llvm::commonAlignment(llvm::Align(alignment.getInt()),
+ i * bytes)
+ .value());
+ }
+ auto store = spirv::StoreOp::create(
+ rewriter, loc, ptr, part, storeOp.getMemoryAccessAttr(), alignment);
+ store->setDiscardableAttrs(storeOp->getDiscardableAttrDictionary());
+ }
+ rewriter.eraseOp(storeOp);
+ return success();
+ }
+ if (srcElemType != dstElemType) {
+ if (!srcElemType.isIntOrFloat() || !dstElemType.isIntOrFloat())
+ return rewriter.notifyMatchFailure(storeOp, "not scalar type");
+ if (!areSameBitwidthScalarType(srcElemType, dstElemType))
+ return rewriter.notifyMatchFailure(storeOp, "different bitwidth");
value = spirv::BitcastOp::create(rewriter, loc, dstElemType, value);
+ }
auto newStore = rewriter.replaceOpWithNewOp<spirv::StoreOp>(
storeOp, adaptor.getPtr(), value, storeOp.getMemoryAccessAttr(),
storeOp.getAlignmentAttr());
diff --git a/mlir/test/Dialect/SPIRV/Transforms/unify-aliased-resource.mlir b/mlir/test/Dialect/SPIRV/Transforms/unify-aliased-resource.mlir
index d7cc1d0cc1f849..e0567272e57de1 100644
--- a/mlir/test/Dialect/SPIRV/Transforms/unify-aliased-resource.mlir
+++ b/mlir/test/Dialect/SPIRV/Transforms/unify-aliased-resource.mlir
@@ -581,3 +581,123 @@ spirv.module Logical GLSL450 {
// CHECK-LABEL: spirv.func @main
// CHECK-SAME: (%{{.+}}: !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer>) "None"
// CHECK: spirv.Return
+
+// -----
+
+spirv.module Logical GLSL450 {
+ spirv.GlobalVariable @canonical bind(0, 0) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<2xf32>, stride=8> [0])>, StorageBuffer>
+ spirv.GlobalVariable @wide bind(0, 0) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>
+ spirv.func @store_wide_vector(%value: vector<4xf32>) "None" {
+ %c0 = spirv.Constant 0 : i32
+ %c3 = spirv.Constant 3 : i32
+ %base = spirv.mlir.addressof @wide : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>
+ %ptr = spirv.AccessChain %base[%c0, %c3] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<vector<4xf32>, StorageBuffer>
+ spirv.Store "StorageBuffer" %ptr, %value : vector<4xf32>
+ spirv.Return
+ }
+}
+// CHECK-LABEL: spirv.module
+// CHECK: spirv.GlobalVariable @canonical bind(0, 0)
+// CHECK-NOT: spirv.GlobalVariable @wide
+// CHECK: spirv.func @store_wide_vector(%[[VALUE:.+]]: vector<4xf32>)
+// CHECK-DAG: %[[ZERO:.+]] = spirv.Constant 0 : i32
+// CHECK-DAG: %[[THREE:.+]] = spirv.Constant 3 : i32
+// CHECK-DAG: %[[BASE:.+]] = spirv.mlir.addressof @canonical
+// CHECK-DAG: %[[TWO:.+]] = spirv.Constant 2 : i32
+// CHECK: %[[INDEX:.+]] = spirv.IMul %[[THREE]], %[[TWO]] : i32
+// CHECK: %[[PTR0:.+]] = spirv.AccessChain %[[BASE]][%[[ZERO]], %[[INDEX]]]
+// CHECK: %[[LOW:.+]] = spirv.VectorShuffle [0 : i32, 1 : i32] %[[VALUE]], %[[VALUE]]
+// CHECK: spirv.Store "StorageBuffer" %[[PTR0]], %[[LOW]] : vector<2xf32>
+// CHECK: %[[HIGH:.+]] = spirv.VectorShuffle [2 : i32, 3 : i32] %[[VALUE]], %[[VALUE]]
+// CHECK: %[[ONE:.+]] = spirv.Constant 1 : i32
+// CHECK: %[[NEXT:.+]] = spirv.IAdd %[[INDEX]], %[[ONE]] : i32
+// CHECK: %[[PTR1:.+]] = spirv.AccessChain %[[BASE]][%[[ZERO]], %[[NEXT]]]
+// CHECK: spirv.Store "StorageBuffer" %[[PTR1]], %[[HIGH]] : vector<2xf32>
+
+// -----
+
+spirv.module Logical GLSL450 {
+ spirv.GlobalVariable @canonical bind(0, 0) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<2xf32>, stride=8> [0])>, StorageBuffer>
+ spirv.GlobalVariable @wide bind(0, 0) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xi32>, stride=16> [0])>, StorageBuffer>
+ spirv.func @store_wide_bitcast(%value: vector<4xi32>) "None" {
+ %c0 = spirv.Constant 0 : i32
+ %c3 = spirv.Constant 3 : i32
+ %base = spirv.mlir.addressof @wide : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xi32>, stride=16> [0])>, StorageBuffer>
+ %ptr = spirv.AccessChain %base[%c0, %c3] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xi32>, stride=16> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<vector<4xi32>, StorageBuffer>
+ spirv.Store "StorageBuffer" %ptr, %value : vector<4xi32>
+ spirv.Return
+ }
+}
+// CHECK-LABEL: spirv.module
+// CHECK: spirv.GlobalVariable @canonical bind(0, 0)
+// CHECK-NOT: spirv.GlobalVariable @wide
+// CHECK: spirv.func @store_wide_bitcast
+// CHECK: spirv.Bitcast
+// CHECK: spirv.VectorShuffle
+// CHECK: spirv.Store "StorageBuffer" {{.+}} : vector<2xf32>
+// CHECK: spirv.VectorShuffle
+// CHECK: spirv.Store "StorageBuffer" {{.+}} : vector<2xf32>
+
+// -----
+
+spirv.module Logical GLSL450 {
+ spirv.GlobalVariable @canonical bind(0, 0) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<2xf32>, stride=8> [0])>, StorageBuffer>
+ spirv.GlobalVariable @wide bind(0, 0) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>
+ spirv.func @store_wide_aligned(%value: vector<4xf32>) "None" {
+ %c0 = spirv.Constant 0 : i32
+ %c3 = spirv.Constant 3 : i32
+ %base = spirv.mlir.addressof @wide : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>
+ %ptr = spirv.AccessChain %base[%c0, %c3] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<vector<4xf32>, StorageBuffer>
+ spirv.Store "StorageBuffer" %ptr, %value ["Volatile|Aligned", 16] : vector<4xf32>
+ spirv.Return
+ }
+}
+// CHECK-LABEL: spirv.module
+// CHECK: spirv.GlobalVariable @canonical bind(0, 0)
+// CHECK-NOT: spirv.GlobalVariable @wide
+// CHECK: spirv.func @store_wide_aligned
+// CHECK: spirv.VectorShuffle
+// CHECK: spirv.Store "StorageBuffer" {{.+}}["Volatile|Aligned", 16] : vector<2xf32>
+// CHECK: spirv.VectorShuffle
+// CHECK: spirv.Store "StorageBuffer" {{.+}}["Volatile|Aligned", 8] : vector<2xf32>
+
+// -----
+
+spirv.module Logical GLSL450 {
+ spirv.GlobalVariable @canonical bind(0, 0) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>
+ spirv.GlobalVariable @wide bind(0, 0) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xi32>, stride=16> [0])>, StorageBuffer>
+ spirv.func @store_equal_vector_bitcast(%value: vector<4xi32>) "None" {
+ %c0 = spirv.Constant 0 : i32
+ %c3 = spirv.Constant 3 : i32
+ %base = spirv.mlir.addressof @wide : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xi32>, stride=16> [0])>, StorageBuffer>
+ %ptr = spirv.AccessChain %base[%c0, %c3] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xi32>, stride=16> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<vector<4xi32>, StorageBuffer>
+ spirv.Store "StorageBuffer" %ptr, %value : vector<4xi32>
+ spirv.Return
+ }
+}
+// CHECK-LABEL: spirv.module
+// CHECK: spirv.GlobalVariable @canonical bind(0, 0)
+// CHECK-NOT: spirv.GlobalVariable @wide
+// CHECK: spirv.func @store_equal_vector_bitcast
+// CHECK: spirv.Bitcast
+// CHECK: spirv.Store "StorageBuffer" {{.+}} : vector<4xf32>
+
+// -----
+
+spirv.module Logical GLSL450 {
+ spirv.GlobalVariable @canonical bind(0, 0) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>
+ spirv.GlobalVariable @alias bind(0, 0) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>
+ spirv.func @store_equal_vector(%value: vector<4xf32>) "None" {
+ %c0 = spirv.Constant 0 : i32
+ %base = spirv.mlir.addressof @alias : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>
+ %ptr = spirv.AccessChain %base[%c0, %c0] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<vector<4xf32>, StorageBuffer>
+ spirv.Store "StorageBuffer" %ptr, %value : vector<4xf32>
+ spirv.Return
+ }
+}
+// CHECK-LABEL: spirv.module
+// CHECK: spirv.GlobalVariable @canonical bind(0, 0)
+// CHECK-NOT: spirv.GlobalVariable @alias
+// CHECK: spirv.func @store_equal_vector(%[[VALUE:.+]]: vector<4xf32>)
+// CHECK: %[[PTR:.+]] = spirv.AccessChain
+// CHECK: spirv.Store "StorageBuffer" %[[PTR]], %[[VALUE]] : vector<4xf32>
>From adafb93651f09571c92d2b089b1db2bb148b3886 Mon Sep 17 00:00:00 2001
From: anutosh491 <andersonbhat491 at gmail.com>
Date: Thu, 29 Oct 2026 10:19:45 +0530
Subject: [PATCH 2/2] [mlir][SPIRV] Address vector store review feedback
Signed-off-by: anutosh491 <andersonbhat491 at gmail.com>
---
.../Transforms/UnifyAliasedResourcePass.cpp | 56 ++++++++++---------
.../Transforms/unify-aliased-resource.mlir | 49 ++++++++++++++++
2 files changed, 79 insertions(+), 26 deletions(-)
diff --git a/mlir/lib/Dialect/SPIRV/Transforms/UnifyAliasedResourcePass.cpp b/mlir/lib/Dialect/SPIRV/Transforms/UnifyAliasedResourcePass.cpp
index 2cc1f0a4a821a8..3ee1e2a6ba641d 100644
--- a/mlir/lib/Dialect/SPIRV/Transforms/UnifyAliasedResourcePass.cpp
+++ b/mlir/lib/Dialect/SPIRV/Transforms/UnifyAliasedResourcePass.cpp
@@ -573,33 +573,37 @@ struct ConvertStore : public ConvertAliasResource<spirv::StoreOp> {
unsigned count = dstVector.getNumElements();
unsigned ratio = srcVector.getNumElements() / count;
unsigned bytes = count * dstVector.getElementTypeBitWidth() / 8;
- for (unsigned i = 0; i < ratio; ++i) {
- Value part = value;
- if (ratio > 1) {
- SmallVector<int32_t> components;
- for (unsigned j = 0; j < count; ++j)
- components.push_back(i * count + j);
- part = spirv::VectorShuffleOp::create(
- rewriter, loc, dstVector, value, value,
- rewriter.getI32ArrayAttr(components));
- }
- Value ptr = adaptor.getPtr();
+
+ // Split the value into stores of the canonical resource's vector type.
+ auto getPart = [&](unsigned i) -> Value {
+ if (ratio == 1)
+ return value;
+ SmallVector<int32_t> components;
+ for (unsigned j = 0; j < count; ++j)
+ components.push_back(i * count + j);
+ return spirv::VectorShuffleOp::create(
+ rewriter, loc, dstVector, value, value,
+ rewriter.getI32ArrayAttr(components));
+ };
+ auto firstStore = spirv::StoreOp::create(
+ rewriter, loc, adaptor.getPtr(), getPart(0),
+ storeOp.getMemoryAccessAttr(), storeOp.getAlignmentAttr());
+ firstStore->setDiscardableAttrs(storeOp->getDiscardableAttrDictionary());
+ for (unsigned i = 1; i < ratio; ++i) {
+ Value part = getPart(i);
+ auto indices = llvm::to_vector(acOp.getIndices());
+ Type indexType = indices.back().getType();
+ auto offset = spirv::ConstantOp::create(
+ rewriter, loc, indexType, rewriter.getIntegerAttr(indexType, i));
+ indices.back() = spirv::IAddOp::create(rewriter, loc, indexType,
+ indices.back(), offset);
+ Value ptr = spirv::AccessChainOp::create(rewriter, loc,
+ acOp.getBasePtr(), indices);
auto alignment = storeOp.getAlignmentAttr();
- if (i) {
- auto indices = llvm::to_vector(acOp.getIndices());
- Type indexType = indices.back().getType();
- auto offset = spirv::ConstantOp::create(
- rewriter, loc, indexType, rewriter.getIntegerAttr(indexType, i));
- indices.back() = spirv::IAddOp::create(rewriter, loc, indexType,
- indices.back(), offset);
- ptr = spirv::AccessChainOp::create(rewriter, loc, acOp.getBasePtr(),
- indices);
- if (alignment)
- alignment = rewriter.getI32IntegerAttr(
- llvm::commonAlignment(llvm::Align(alignment.getInt()),
- i * bytes)
- .value());
- }
+ if (alignment)
+ alignment = rewriter.getI32IntegerAttr(
+ llvm::commonAlignment(llvm::Align(alignment.getInt()), i * bytes)
+ .value());
auto store = spirv::StoreOp::create(
rewriter, loc, ptr, part, storeOp.getMemoryAccessAttr(), alignment);
store->setDiscardableAttrs(storeOp->getDiscardableAttrDictionary());
diff --git a/mlir/test/Dialect/SPIRV/Transforms/unify-aliased-resource.mlir b/mlir/test/Dialect/SPIRV/Transforms/unify-aliased-resource.mlir
index e0567272e57de1..982a35cebe69df 100644
--- a/mlir/test/Dialect/SPIRV/Transforms/unify-aliased-resource.mlir
+++ b/mlir/test/Dialect/SPIRV/Transforms/unify-aliased-resource.mlir
@@ -701,3 +701,52 @@ spirv.module Logical GLSL450 {
// CHECK: spirv.func @store_equal_vector(%[[VALUE:.+]]: vector<4xf32>)
// CHECK: %[[PTR:.+]] = spirv.AccessChain
// CHECK: spirv.Store "StorageBuffer" %[[PTR]], %[[VALUE]] : vector<4xf32>
+
+// -----
+
+spirv.module Logical GLSL450 {
+ spirv.GlobalVariable @canonical bind(0, 0) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<2xf16>, stride=4> [0])>, StorageBuffer>
+ spirv.GlobalVariable @wide bind(0, 0) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>
+ spirv.func @store_different_element_width(%value: vector<4xf32>) "None" {
+ %c0 = spirv.Constant 0 : i32
+ %base = spirv.mlir.addressof @wide : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>
+ %ptr = spirv.AccessChain %base[%c0, %c0] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<vector<4xf32>, StorageBuffer>
+ // expected-error at +1 {{failed to legalize operation 'spirv.Store'}}
+ spirv.Store "StorageBuffer" %ptr, %value : vector<4xf32>
+ spirv.Return
+ }
+}
+
+// -----
+
+spirv.module Logical GLSL450 {
+ spirv.GlobalVariable @canonical bind(0, 0) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<3xf32>, stride=16> [0])>, StorageBuffer>
+ spirv.GlobalVariable @wide bind(0, 0) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>
+ spirv.func @store_nondivisible_vectors(%value: vector<4xf32>) "None" {
+ %c0 = spirv.Constant 0 : i32
+ %base = spirv.mlir.addressof @wide : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>
+ %ptr = spirv.AccessChain %base[%c0, %c0] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<vector<4xf32>, StorageBuffer>
+ spirv.Store "StorageBuffer" %ptr, %value : vector<4xf32>
+ spirv.Return
+ }
+}
+
+// CHECK-LABEL: spirv.module
+// CHECK: spirv.GlobalVariable @canonical bind(0, 0) {aliased}
+// CHECK: spirv.GlobalVariable @wide bind(0, 0) {aliased}
+// CHECK-LABEL: spirv.func @store_nondivisible_vectors
+// CHECK-NOT: spirv.VectorShuffle
+// CHECK: spirv.Store "StorageBuffer" {{.+}} : vector<4xf32>
+
+// -----
+
+spirv.module Logical GLSL450 {
+ spirv.func @store_without_access_chain(%ptr: !spirv.ptr<vector<4xf32>, StorageBuffer>, %value: vector<4xf32>) "None" {
+ spirv.Store "StorageBuffer" %ptr, %value : vector<4xf32>
+ spirv.Return
+ }
+}
+// CHECK-LABEL: spirv.func @store_without_access_chain(
+// CHECK-SAME: %[[PTR:.+]]: !spirv.ptr<vector<4xf32>, StorageBuffer>, %[[VALUE:.+]]: vector<4xf32>)
+// CHECK-NOT: spirv.AccessChain
+// CHECK: spirv.Store "StorageBuffer" %[[PTR]], %[[VALUE]] : vector<4xf32>
More information about the Mlir-commits
mailing list