vce-deduction.mlir 6.42 KB
// RUN: mlir-opt -spirv-update-vce %s | FileCheck %s

//===----------------------------------------------------------------------===//
// Version
//===----------------------------------------------------------------------===//

// Test deducing minimal version.
// spv.IAdd is available from v1.0.

// CHECK: requires #spv.vce<v1.0, [Shader], []>
spv.module Logical GLSL450 attributes {
  spv.target_env = #spv.target_env<
    #spv.vce<v1.5, [Shader], []>, {}>
} {
  spv.func @iadd(%val : i32) -> i32 "None" {
    %0 = spv.IAdd %val, %val: i32
    spv.ReturnValue %0: i32
  }
}

// Test deducing minimal version.
// spv.GroupNonUniformBallot is available since v1.3.

// CHECK: requires #spv.vce<v1.3, [GroupNonUniformBallot, Shader], []>
spv.module Logical GLSL450 attributes {
  spv.target_env = #spv.target_env<
    #spv.vce<v1.5, [Shader, GroupNonUniformBallot], []>, {}>
} {
  spv.func @group_non_uniform_ballot(%predicate : i1) -> vector<4xi32> "None" {
    %0 = spv.GroupNonUniformBallot "Workgroup" %predicate : vector<4xi32>
    spv.ReturnValue %0: vector<4xi32>
  }
}

//===----------------------------------------------------------------------===//
// Capability
//===----------------------------------------------------------------------===//

// Test minimal capabilities.

// CHECK: requires #spv.vce<v1.0, [Shader], []>
spv.module Logical GLSL450 attributes {
  spv.target_env = #spv.target_env<
    #spv.vce<v1.0, [Shader, Float16, Float64, Int16, Int64, VariablePointers], []>, {}>
} {
  spv.func @iadd(%val : i32) -> i32 "None" {
    %0 = spv.IAdd %val, %val: i32
    spv.ReturnValue %0: i32
  }
}

// Test deducing implied capability.
// AtomicStorage implies Shader.

// CHECK: requires #spv.vce<v1.0, [Shader], []>
spv.module Logical GLSL450 attributes {
  spv.target_env = #spv.target_env<
    #spv.vce<v1.0, [AtomicStorage], []>, {}>
} {
  spv.func @iadd(%val : i32) -> i32 "None" {
    %0 = spv.IAdd %val, %val: i32
    spv.ReturnValue %0: i32
  }
}

// Test selecting the capability available in the target environment.
// spv.GroupNonUniform op itself can be enabled via any of
// * GroupNonUniformArithmetic
// * GroupNonUniformClustered
// * GroupNonUniformPartitionedNV
// Its 'Reduce' group operation can be enabled via any of
// * Kernel
// * GroupNonUniformArithmetic
// * GroupNonUniformBallot

// CHECK: requires #spv.vce<v1.3, [GroupNonUniformArithmetic, Shader], []>
spv.module Logical GLSL450 attributes {
  spv.target_env = #spv.target_env<
    #spv.vce<v1.3, [Shader, GroupNonUniformArithmetic], []>, {}>
} {
  spv.func @group_non_uniform_iadd(%val : i32) -> i32 "None" {
    %0 = spv.GroupNonUniformIAdd "Subgroup" "Reduce" %val : i32
    spv.ReturnValue %0: i32
  }
}

// CHECK: requires #spv.vce<v1.3, [GroupNonUniformClustered, GroupNonUniformBallot, Shader], []>
spv.module Logical GLSL450 attributes {
  spv.target_env = #spv.target_env<
    #spv.vce<v1.3, [Shader, GroupNonUniformClustered, GroupNonUniformBallot], []>, {}>
} {
  spv.func @group_non_uniform_iadd(%val : i32) -> i32 "None" {
    %0 = spv.GroupNonUniformIAdd "Subgroup" "Reduce" %val : i32
    spv.ReturnValue %0: i32
  }
}

// Test type required capabilities

// Using 8-bit integers in non-interface storage class requires Int8.
// CHECK: requires #spv.vce<v1.0, [Int8, Shader], []>
spv.module Logical GLSL450 attributes {
  spv.target_env = #spv.target_env<
    #spv.vce<v1.3, [Shader, Int8], []>, {}>
} {
  spv.func @iadd_function(%val : i8) -> i8 "None" {
    %0 = spv.IAdd %val, %val : i8
    spv.ReturnValue %0: i8
  }
}

// Using 16-bit floats in non-interface storage class requires Float16.
// CHECK: requires #spv.vce<v1.0, [Float16, Shader], []>
spv.module Logical GLSL450 attributes {
  spv.target_env = #spv.target_env<
    #spv.vce<v1.3, [Shader, Float16], []>, {}>
} {
  spv.func @fadd_function(%val : f16) -> f16 "None" {
    %0 = spv.FAdd %val, %val : f16
    spv.ReturnValue %0: f16
  }
}

//===----------------------------------------------------------------------===//
// Extension
//===----------------------------------------------------------------------===//

// Test deducing minimal extensions.
// spv.SubgroupBallotKHR requires the SPV_KHR_shader_ballot extension.

// CHECK: requires #spv.vce<v1.0, [SubgroupBallotKHR, Shader], [SPV_KHR_shader_ballot]>
spv.module Logical GLSL450 attributes {
  spv.target_env = #spv.target_env<
    #spv.vce<v1.0, [Shader, SubgroupBallotKHR],
             [SPV_KHR_shader_ballot, SPV_KHR_shader_clock, SPV_KHR_variable_pointers]>, {}>
} {
  spv.func @subgroup_ballot(%predicate : i1) -> vector<4xi32> "None" {
    %0 = spv.SubgroupBallotKHR %predicate: vector<4xi32>
    spv.ReturnValue %0: vector<4xi32>
  }
}

// Test deducing implied extension.
// Vulkan memory model requires SPV_KHR_vulkan_memory_model, which is enabled
// implicitly by v1.5.

// CHECK: requires #spv.vce<v1.0, [VulkanMemoryModel], [SPV_KHR_vulkan_memory_model]>
spv.module Logical Vulkan attributes {
  spv.target_env = #spv.target_env<
    #spv.vce<v1.5, [Shader, VulkanMemoryModel], []>, {}>
} {
  spv.func @iadd(%val : i32) -> i32 "None" {
    %0 = spv.IAdd %val, %val: i32
    spv.ReturnValue %0: i32
  }
}

// Test type required extensions

// Using 8-bit integers in interface storage class requires additional
// extensions and capabilities.
// CHECK: requires #spv.vce<v1.0, [StorageBuffer16BitAccess, Shader, Int16], [SPV_KHR_16bit_storage, SPV_KHR_storage_buffer_storage_class]>
spv.module Logical GLSL450 attributes {
  spv.target_env = #spv.target_env<
    #spv.vce<v1.3, [Shader, StorageBuffer16BitAccess, Int16], []>, {}>
} {
  spv.func @iadd_storage_buffer(%ptr : !spv.ptr<i16, StorageBuffer>) -> i16 "None" {
    %0 = spv.Load "StorageBuffer" %ptr : i16
    %1 = spv.IAdd %0, %0 : i16
    spv.ReturnValue %1: i16
  }
}

// Complicated nested types
// * Buffer requires ImageBuffer or SampledBuffer.
// * Rg32f requires StorageImageExtendedFormats.
// CHECK: requires #spv.vce<v1.0, [UniformAndStorageBuffer8BitAccess, StorageUniform16, Shader, ImageBuffer, StorageImageExtendedFormats], [SPV_KHR_8bit_storage, SPV_KHR_16bit_storage]>
spv.module Logical GLSL450 attributes {
  spv.target_env = #spv.target_env<
    #spv.vce<v1.5, [Shader, UniformAndStorageBuffer8BitAccess, StorageBuffer16BitAccess, StorageUniform16, Int16, ImageBuffer, StorageImageExtendedFormats], []>,
    {}>
} {
  spv.globalVariable @data : !spv.ptr<!spv.struct<i8 [0], f16 [2], i64 [4]>, Uniform>
  spv.globalVariable @img  : !spv.ptr<!spv.image<f32, Buffer, NoDepth, NonArrayed, SingleSampled, SamplerUnknown, Rg32f>, UniformConstant>
}