blob: a3a55da001a1e2ef5050bf95db3149a4a5b9be60 [file] [log] [blame]
// RUN: mlir-opt -split-input-file -verify-diagnostics %s | FileCheck %s
//===----------------------------------------------------------------------===//
// spv.FMul
//===----------------------------------------------------------------------===//
func @fmul_scalar(%arg: f32) -> f32 {
// CHECK: spv.FMul
%0 = spv.FMul %arg, %arg : f32
return %0 : f32
}
func @fmul_vector(%arg: vector<4xf32>) -> vector<4xf32> {
// CHECK: spv.FMul
%0 = spv.FMul %arg, %arg : vector<4xf32>
return %0 : vector<4xf32>
}
// -----
func @fmul_i32(%arg: i32) -> i32 {
// expected-error @+1 {{must be scalar/vector of 16/32/64-bit float}}
%0 = spv.FMul %arg, %arg : i32
return %0 : i32
}
// -----
func @fmul_bf16(%arg: bf16) -> bf16 {
// expected-error @+1 {{must be scalar/vector of 16/32/64-bit float}}
%0 = spv.FMul %arg, %arg : bf16
return %0 : bf16
}
// -----
func @fmul_tensor(%arg: tensor<4xf32>) -> tensor<4xf32> {
// expected-error @+1 {{must be scalar/vector of 16/32/64-bit float}}
%0 = spv.FMul %arg, %arg : tensor<4xf32>
return %0 : tensor<4xf32>
}
// -----
//===----------------------------------------------------------------------===//
// spv.LoadOp
//===----------------------------------------------------------------------===//
// CHECK_LABEL: @simple_load
func @simple_load() -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// CHECK: spv.Load "Function" %0 : f32
%1 = spv.Load "Function" %0 : f32
return
}
// CHECK_LABEL: @volatile_load
func @volatile_load() -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// CHECK: spv.Load "Function" %0 ["Volatile"] : f32
%1 = spv.Load "Function" %0 ["Volatile"] : f32
return
}
// CHECK_LABEL: @aligned_load
func @aligned_load() -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// CHECK: spv.Load "Function" %0 ["Aligned", 4] : f32
%1 = spv.Load "Function" %0 ["Aligned", 4] : f32
return
}
// -----
func @simple_load_missing_storageclass() -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// expected-error @+1 {{expected non-function type}}
%1 = spv.Load %0 : f32
return
}
// -----
func @simple_load_missing_operand() -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// expected-error @+1 {{expected SSA operand}}
%1 = spv.Load "Function" : f32
return
}
// -----
func @simple_load_missing_rettype() -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// expected-error @+2 {{expected ':'}}
%1 = spv.Load "Function" %0
return
}
// -----
func @volatile_load_missing_lbrace() -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// expected-error @+1 {{expected ':'}}
%1 = spv.Load "Function" %0 "Volatile"] : f32
return
}
// -----
func @volatile_load_missing_rbrace() -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// expected-error @+1 {{expected ']'}}
%1 = spv.Load "Function" %0 ["Volatile"} : f32
return
}
// -----
func @aligned_load_missing_alignment() -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// expected-error @+1 {{expected ','}}
%1 = spv.Load "Function" %0 ["Aligned"] : f32
return
}
// -----
func @aligned_load_missing_comma() -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// expected-error @+1 {{expected ','}}
%1 = spv.Load "Function" %0 ["Aligned" 4] : f32
return
}
// -----
func @load_incorrect_attributes() -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// expected-error @+1 {{expected ']'}}
%1 = spv.Load "Function" %0 ["Volatile", 4] : f32
return
}
// -----
func @load_unknown_memory_access() -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// expected-error @+1 {{invalid memory access specifier: "Something"}}
%1 = spv.Load "Function" %0 ["Something"] : f32
return
}
// -----
func @aligned_load_incorrect_attributes() -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// expected-error @+1 {{expected ']'}}
%1 = spv.Load "Function" %0 ["Aligned", 4, 23] : f32
return
}
// -----
//===----------------------------------------------------------------------===//
// spv.Return
//===----------------------------------------------------------------------===//
func @return_not_in_func() -> () {
// expected-error @+1 {{must appear in a 'func' op}}
spv.Return
}
// -----
func @return_mismatch_func_signature() -> () {
spv.module "Logical" "VulkanKHR" {
func @work() -> (i32) {
// expected-error @+1 {{cannot be used in functions returning value}}
spv.Return
}
}
return
}
// -----
//===----------------------------------------------------------------------===//
// spv.StoreOp
//===----------------------------------------------------------------------===//
func @simple_store(%arg0 : f32) -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// CHECK: spv.Store "Function" %0, %arg0 : f32
spv.Store "Function" %0, %arg0 : f32
return
}
// CHECK_LABEL: @volatile_store
func @volatile_store(%arg0 : f32) -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// CHECK: spv.Store "Function" %0, %arg0 ["Volatile"] : f32
spv.Store "Function" %0, %arg0 ["Volatile"] : f32
return
}
// CHECK_LABEL: @aligned_store
func @aligned_store(%arg0 : f32) -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// CHECK: spv.Store "Function" %0, %arg0 ["Aligned", 4] : f32
spv.Store "Function" %0, %arg0 ["Aligned", 4] : f32
return
}
// -----
func @simple_store_missing_ptr_type(%arg0 : f32) -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// expected-error @+1 {{expected non-function type}}
spv.Store %0, %arg0 : f32
return
}
// -----
func @simple_store_missing_operand(%arg0 : f32) -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// expected-error @+1 {{custom op 'spv.Store' invalid operand}} : f32
spv.Store "Function" , %arg0 : f32
return
}
// -----
func @simple_store_missing_operand(%arg0 : f32) -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// expected-error @+1 {{custom op 'spv.Store' expected 2 operands}} : f32
spv.Store "Function" %0 : f32
return
}
// -----
func @volatile_store_missing_lbrace(%arg0 : f32) -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// expected-error @+1 {{expected ':'}}
spv.Store "Function" %0, %arg0 "Volatile"] : f32
return
}
// -----
func @volatile_store_missing_rbrace(%arg0 : f32) -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// expected-error @+1 {{expected ']'}}
spv.Store "Function" %0, %arg0 ["Volatile"} : f32
return
}
// -----
func @aligned_store_missing_alignment(%arg0 : f32) -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// expected-error @+1 {{expected ','}}
spv.Store "Function" %0, %arg0 ["Aligned"] : f32
return
}
// -----
func @aligned_store_missing_comma(%arg0 : f32) -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// expected-error @+1 {{expected ','}}
spv.Store "Function" %0, %arg0 ["Aligned" 4] : f32
return
}
// -----
func @load_incorrect_attributes(%arg0 : f32) -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// expected-error @+1 {{expected ']'}}
spv.Store "Function" %0, %arg0 ["Volatile", 4] : f32
return
}
// -----
func @aligned_store_incorrect_attributes(%arg0 : f32) -> () {
%0 = spv.Variable : !spv.ptr<f32, Function>
// expected-error @+1 {{expected ']'}}
spv.Store "Function" %0, %arg0 ["Aligned", 4, 23] : f32
return
}
// -----
//===----------------------------------------------------------------------===//
// spv.Variable
//===----------------------------------------------------------------------===//
func @variable_no_init(%arg0: f32) -> () {
// CHECK: spv.Variable : !spv.ptr<f32, Function>
%0 = spv.Variable : !spv.ptr<f32, Function>
return
}
func @variable_init() -> () {
%0 = spv.constant 4.0 : f32
// CHECK: spv.Variable init(%0) : !spv.ptr<f32, Private>
%1 = spv.Variable init(%0) : !spv.ptr<f32, Private>
return
}
func @variable_bind() -> () {
// CHECK: spv.Variable bind(1, 2) : !spv.ptr<f32, Uniform>
%0 = spv.Variable bind(1, 2) : !spv.ptr<f32, Uniform>
return
}
func @variable_init_bind() -> () {
%0 = spv.constant 4.0 : f32
// CHECK: spv.Variable init(%0) {binding = 5 : i32} : !spv.ptr<f32, Private>
%1 = spv.Variable init(%0) {binding = 5 : i32} : !spv.ptr<f32, Private>
return
}
// -----
func @expect_ptr_result_type(%arg0: f32) -> () {
// expected-error @+1 {{expected spv.ptr type}}
%0 = spv.Variable : f32
return
}
// -----
func @variable_init(%arg0: f32) -> () {
// expected-error @+1 {{op initializer must be the result of a spv.Constant or module-level spv.Variable op}}
%0 = spv.Variable init(%arg0) : !spv.ptr<f32, Private>
return
}
// -----
func @storage_class_mismatch() -> () {
%0 = spv.constant 5.0 : f32
// expected-error @+1 {{storage class must match result pointer's storage class}}
%1 = "spv.Variable"(%0) {storage_class = 2: i32} : (f32) -> !spv.ptr<f32, Function>
return
}
// -----
func @cannot_be_generic_storage_class(%arg0: f32) -> () {
// expected-error @+1 {{storage class cannot be 'Generic'}}
%0 = spv.Variable : !spv.ptr<f32, Generic>
return
}