GLSL, MSL: Handle OpUndef
as part of a constant composite.
Fixes the CTS test `dEQP-VK.spirv_assembly.instruction.compute.opundef.undefined_constant_composite` and helps with another, `dEQP-VK.spirv_assembly.instruction.compute.opundef.undefined_spec_constant_composite`. Unfortunately, fixing the latter requires another change.
This commit is contained in:
parent
51d2dfe02a
commit
06ef3de002
@ -0,0 +1,28 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct _20
|
||||
{
|
||||
int _m0;
|
||||
int _m1;
|
||||
};
|
||||
|
||||
struct _5
|
||||
{
|
||||
int _m0[10];
|
||||
};
|
||||
|
||||
struct _7
|
||||
{
|
||||
int _m0[10];
|
||||
};
|
||||
|
||||
constant int _28 = {};
|
||||
|
||||
kernel void main0(device _5& _6 [[buffer(0)]], device _7& _8 [[buffer(1)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]])
|
||||
{
|
||||
_6._m0[gl_GlobalInvocationID.x] = _8._m0[gl_GlobalInvocationID.x] + (_20{ _28, 200 })._m1;
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
#version 450
|
||||
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||
|
||||
struct _20
|
||||
{
|
||||
int _m0;
|
||||
int _m1;
|
||||
};
|
||||
|
||||
layout(binding = 1, std430) buffer _5_6
|
||||
{
|
||||
int _m0[10];
|
||||
} _6;
|
||||
|
||||
layout(binding = 0, std430) buffer _7_8
|
||||
{
|
||||
int _m0[10];
|
||||
} _8;
|
||||
|
||||
int _28;
|
||||
|
||||
void main()
|
||||
{
|
||||
_6._m0[gl_GlobalInvocationID.x] = _8._m0[gl_GlobalInvocationID.x] + _20(_28, 200)._m1;
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct _20
|
||||
{
|
||||
int _m0;
|
||||
int _m1;
|
||||
};
|
||||
|
||||
struct _5
|
||||
{
|
||||
int _m0[10];
|
||||
};
|
||||
|
||||
struct _7
|
||||
{
|
||||
int _m0[10];
|
||||
};
|
||||
|
||||
constant int _28 = {};
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
int _39(thread const int& _41, thread const _20& _42)
|
||||
{
|
||||
return _41 + _42._m1;
|
||||
}
|
||||
|
||||
kernel void main0(device _5& _6 [[buffer(0)]], device _7& _8 [[buffer(1)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]])
|
||||
{
|
||||
int _32 = _8._m0[gl_GlobalInvocationID.x];
|
||||
_20 _33 = _20{ _28, 200 };
|
||||
_6._m0[gl_GlobalInvocationID.x] = _39(_32, _33);
|
||||
}
|
||||
|
@ -0,0 +1,33 @@
|
||||
#version 450
|
||||
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||
|
||||
struct _20
|
||||
{
|
||||
int _m0;
|
||||
int _m1;
|
||||
};
|
||||
|
||||
layout(binding = 1, std430) buffer _5_6
|
||||
{
|
||||
int _m0[10];
|
||||
} _6;
|
||||
|
||||
layout(binding = 0, std430) buffer _7_8
|
||||
{
|
||||
int _m0[10];
|
||||
} _8;
|
||||
|
||||
int _28;
|
||||
|
||||
int _39(int _41, _20 _42)
|
||||
{
|
||||
return _41 + _42._m1;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
int _32 = _8._m0[gl_GlobalInvocationID.x];
|
||||
_20 _33 = _20(_28, 200);
|
||||
_6._m0[gl_GlobalInvocationID.x] = _39(_32, _33);
|
||||
}
|
||||
|
102
shaders-msl/asm/comp/undefined-constant-composite.asm.comp
Normal file
102
shaders-msl/asm/comp/undefined-constant-composite.asm.comp
Normal file
@ -0,0 +1,102 @@
|
||||
;
|
||||
; The shader below is based on the following GLSL shader:
|
||||
;
|
||||
; #version 450
|
||||
;
|
||||
; struct Pair {
|
||||
; int first;
|
||||
; int second;
|
||||
; };
|
||||
;
|
||||
; const Pair constant_pair = { 100, 200 };
|
||||
;
|
||||
; layout(set=0, binding=0, std430) buffer InputBlock {
|
||||
; int array[10];
|
||||
; } inputValues;
|
||||
;
|
||||
; layout(set=0, binding=1, std430) buffer OutputBlock {
|
||||
; int array[10];
|
||||
; } outputValues;
|
||||
;
|
||||
; int add_second (int value, Pair pair) {
|
||||
; return value + pair.second;
|
||||
; }
|
||||
;
|
||||
; void main() {
|
||||
; uint idx = gl_GlobalInvocationID.x;
|
||||
; outputValues.array[idx] = add_second(inputValues.array[idx], constant_pair);
|
||||
; }
|
||||
;
|
||||
; However, the first element of constant_pair has been modified to be undefined.
|
||||
;
|
||||
OpCapability Shader
|
||||
%std450 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
|
||||
OpExecutionMode %main LocalSize 1 1 1
|
||||
OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
|
||||
OpDecorate %_arr_int_uint_10 ArrayStride 4
|
||||
OpMemberDecorate %OutputBlock 0 Offset 0
|
||||
OpDecorate %OutputBlock BufferBlock
|
||||
OpDecorate %outputValues DescriptorSet 0
|
||||
OpDecorate %outputValues Binding 1
|
||||
OpMemberDecorate %InputBlock 0 Offset 0
|
||||
OpDecorate %InputBlock BufferBlock
|
||||
OpDecorate %inputValues DescriptorSet 0
|
||||
OpDecorate %inputValues Binding 0
|
||||
%void = OpTypeVoid
|
||||
%void_func = OpTypeFunction %void
|
||||
%int = OpTypeInt 32 1
|
||||
%uint = OpTypeInt 32 0
|
||||
%v3uint = OpTypeVector %uint 3
|
||||
%int_0 = OpConstant %int 0
|
||||
%int_1 = OpConstant %int 1
|
||||
%int_200 = OpConstant %int 200
|
||||
%uint_0 = OpConstant %uint 0
|
||||
%uint_10 = OpConstant %uint 10
|
||||
%_ptr_Function_int = OpTypePointer Function %int
|
||||
%Pair = OpTypeStruct %int %int
|
||||
%_ptr_Function_Pair = OpTypePointer Function %Pair
|
||||
%add_second_func_type = OpTypeFunction %int %_ptr_Function_int %_ptr_Function_Pair
|
||||
%_ptr_Function_uint = OpTypePointer Function %uint
|
||||
%_ptr_Input_v3uint = OpTypePointer Input %v3uint
|
||||
%_ptr_Input_uint = OpTypePointer Input %uint
|
||||
%_arr_int_uint_10 = OpTypeArray %int %uint_10
|
||||
%OutputBlock = OpTypeStruct %_arr_int_uint_10
|
||||
%_ptr_Uniform_OutputBlock = OpTypePointer Uniform %OutputBlock
|
||||
%outputValues = OpVariable %_ptr_Uniform_OutputBlock Uniform
|
||||
%InputBlock = OpTypeStruct %_arr_int_uint_10
|
||||
%_ptr_Uniform_InputBlock = OpTypePointer Uniform %InputBlock
|
||||
%inputValues = OpVariable %_ptr_Uniform_InputBlock Uniform
|
||||
; Replaced %int_100 with an undefined int.
|
||||
%undef_int = OpUndef %int
|
||||
; Composed a constant Pair with the undefined int in the first member.
|
||||
%const_Pair = OpConstantComposite %Pair %undef_int %int_200
|
||||
%_ptr_Uniform_int = OpTypePointer Uniform %int
|
||||
%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
|
||||
%main = OpFunction %void None %void_func
|
||||
%main_label = OpLabel
|
||||
%param_1 = OpVariable %_ptr_Function_int Function
|
||||
%param_2 = OpVariable %_ptr_Function_Pair Function
|
||||
%gidx_ptr = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0
|
||||
%gidx = OpLoad %uint %gidx_ptr
|
||||
%input_value_ptr = OpAccessChain %_ptr_Uniform_int %inputValues %int_0 %gidx
|
||||
%input_value = OpLoad %int %input_value_ptr
|
||||
OpStore %param_1 %input_value
|
||||
OpStore %param_2 %const_Pair
|
||||
%retval = OpFunctionCall %int %add_second %param_1 %param_2
|
||||
%output_value_ptr = OpAccessChain %_ptr_Uniform_int %outputValues %int_0 %gidx
|
||||
OpStore %output_value_ptr %retval
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%add_second = OpFunction %int None %add_second_func_type
|
||||
%value_ptr = OpFunctionParameter %_ptr_Function_int
|
||||
%pair = OpFunctionParameter %_ptr_Function_Pair
|
||||
%add_second_label = OpLabel
|
||||
%value = OpLoad %int %value_ptr
|
||||
; Access the second struct member, which is defined.
|
||||
%pair_second_ptr = OpAccessChain %_ptr_Function_int %pair %int_1
|
||||
%pair_second = OpLoad %int %pair_second_ptr
|
||||
%add_result = OpIAdd %int %value %pair_second
|
||||
OpReturnValue %add_result
|
||||
OpFunctionEnd
|
102
shaders/asm/comp/undefined-constant-composite.asm.comp
Normal file
102
shaders/asm/comp/undefined-constant-composite.asm.comp
Normal file
@ -0,0 +1,102 @@
|
||||
;
|
||||
; The shader below is based on the following GLSL shader:
|
||||
;
|
||||
; #version 450
|
||||
;
|
||||
; struct Pair {
|
||||
; int first;
|
||||
; int second;
|
||||
; };
|
||||
;
|
||||
; const Pair constant_pair = { 100, 200 };
|
||||
;
|
||||
; layout(set=0, binding=0, std430) buffer InputBlock {
|
||||
; int array[10];
|
||||
; } inputValues;
|
||||
;
|
||||
; layout(set=0, binding=1, std430) buffer OutputBlock {
|
||||
; int array[10];
|
||||
; } outputValues;
|
||||
;
|
||||
; int add_second (int value, Pair pair) {
|
||||
; return value + pair.second;
|
||||
; }
|
||||
;
|
||||
; void main() {
|
||||
; uint idx = gl_GlobalInvocationID.x;
|
||||
; outputValues.array[idx] = add_second(inputValues.array[idx], constant_pair);
|
||||
; }
|
||||
;
|
||||
; However, the first element of constant_pair has been modified to be undefined.
|
||||
;
|
||||
OpCapability Shader
|
||||
%std450 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
|
||||
OpExecutionMode %main LocalSize 1 1 1
|
||||
OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
|
||||
OpDecorate %_arr_int_uint_10 ArrayStride 4
|
||||
OpMemberDecorate %OutputBlock 0 Offset 0
|
||||
OpDecorate %OutputBlock BufferBlock
|
||||
OpDecorate %outputValues DescriptorSet 0
|
||||
OpDecorate %outputValues Binding 1
|
||||
OpMemberDecorate %InputBlock 0 Offset 0
|
||||
OpDecorate %InputBlock BufferBlock
|
||||
OpDecorate %inputValues DescriptorSet 0
|
||||
OpDecorate %inputValues Binding 0
|
||||
%void = OpTypeVoid
|
||||
%void_func = OpTypeFunction %void
|
||||
%int = OpTypeInt 32 1
|
||||
%uint = OpTypeInt 32 0
|
||||
%v3uint = OpTypeVector %uint 3
|
||||
%int_0 = OpConstant %int 0
|
||||
%int_1 = OpConstant %int 1
|
||||
%int_200 = OpConstant %int 200
|
||||
%uint_0 = OpConstant %uint 0
|
||||
%uint_10 = OpConstant %uint 10
|
||||
%_ptr_Function_int = OpTypePointer Function %int
|
||||
%Pair = OpTypeStruct %int %int
|
||||
%_ptr_Function_Pair = OpTypePointer Function %Pair
|
||||
%add_second_func_type = OpTypeFunction %int %_ptr_Function_int %_ptr_Function_Pair
|
||||
%_ptr_Function_uint = OpTypePointer Function %uint
|
||||
%_ptr_Input_v3uint = OpTypePointer Input %v3uint
|
||||
%_ptr_Input_uint = OpTypePointer Input %uint
|
||||
%_arr_int_uint_10 = OpTypeArray %int %uint_10
|
||||
%OutputBlock = OpTypeStruct %_arr_int_uint_10
|
||||
%_ptr_Uniform_OutputBlock = OpTypePointer Uniform %OutputBlock
|
||||
%outputValues = OpVariable %_ptr_Uniform_OutputBlock Uniform
|
||||
%InputBlock = OpTypeStruct %_arr_int_uint_10
|
||||
%_ptr_Uniform_InputBlock = OpTypePointer Uniform %InputBlock
|
||||
%inputValues = OpVariable %_ptr_Uniform_InputBlock Uniform
|
||||
; Replaced %int_100 with an undefined int.
|
||||
%undef_int = OpUndef %int
|
||||
; Composed a constant Pair with the undefined int in the first member.
|
||||
%const_Pair = OpConstantComposite %Pair %undef_int %int_200
|
||||
%_ptr_Uniform_int = OpTypePointer Uniform %int
|
||||
%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
|
||||
%main = OpFunction %void None %void_func
|
||||
%main_label = OpLabel
|
||||
%param_1 = OpVariable %_ptr_Function_int Function
|
||||
%param_2 = OpVariable %_ptr_Function_Pair Function
|
||||
%gidx_ptr = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0
|
||||
%gidx = OpLoad %uint %gidx_ptr
|
||||
%input_value_ptr = OpAccessChain %_ptr_Uniform_int %inputValues %int_0 %gidx
|
||||
%input_value = OpLoad %int %input_value_ptr
|
||||
OpStore %param_1 %input_value
|
||||
OpStore %param_2 %const_Pair
|
||||
%retval = OpFunctionCall %int %add_second %param_1 %param_2
|
||||
%output_value_ptr = OpAccessChain %_ptr_Uniform_int %outputValues %int_0 %gidx
|
||||
OpStore %output_value_ptr %retval
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%add_second = OpFunction %int None %add_second_func_type
|
||||
%value_ptr = OpFunctionParameter %_ptr_Function_int
|
||||
%pair = OpFunctionParameter %_ptr_Function_Pair
|
||||
%add_second_label = OpLabel
|
||||
%value = OpLoad %int %value_ptr
|
||||
; Access the second struct member, which is defined.
|
||||
%pair_second_ptr = OpAccessChain %_ptr_Function_int %pair %int_1
|
||||
%pair_second = OpLoad %int %pair_second_ptr
|
||||
%add_result = OpIAdd %int %value %pair_second
|
||||
OpReturnValue %add_result
|
||||
OpFunctionEnd
|
@ -5342,6 +5342,10 @@ string CompilerGLSL::constant_expression(const SPIRConstant &c, bool inside_bloc
|
||||
{
|
||||
res += constant_op_expression(*op);
|
||||
}
|
||||
else if (maybe_get<SPIRUndef>(elem) != nullptr)
|
||||
{
|
||||
res += to_name(elem);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto &subc = get<SPIRConstant>(elem);
|
||||
|
Loading…
Reference in New Issue
Block a user