Clamp vector element access to vector size.
In cases where we know the size of the vector and the index at compile time, we can check if it's accessing in bounds and rely in undefined behavior otherwise. Signed-off-by: Sebastián Aedo <saedo@codeweavers.com>
This commit is contained in:
parent
e9cc640334
commit
905b8244e7
@ -0,0 +1,8 @@
|
||||
#version 320 es
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
void main()
|
||||
{
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
#version 320 es
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
void main()
|
||||
{
|
||||
}
|
||||
|
@ -0,0 +1,15 @@
|
||||
#version 320 es
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
const uint _15 = 3u;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 v = vec3(0.0);
|
||||
if (false)
|
||||
{
|
||||
v[0] = 99.0;
|
||||
}
|
||||
}
|
||||
|
14
reference/shaders/asm/frag/out-of-bounds-access.asm.frag
Normal file
14
reference/shaders/asm/frag/out-of-bounds-access.asm.frag
Normal file
@ -0,0 +1,14 @@
|
||||
#version 320 es
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 v = vec3(0.0);
|
||||
if (false)
|
||||
{
|
||||
v.x = 99.0;
|
||||
v.x = 88.0;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,42 @@
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Google Shaderc over Glslang; 10
|
||||
; Bound: 21
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main"
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpSource ESSL 320
|
||||
OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
|
||||
OpSourceExtension "GL_GOOGLE_include_directive"
|
||||
OpName %main "main"
|
||||
OpName %v "v"
|
||||
OpDecorate %v RelaxedPrecision
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%v3float = OpTypeVector %float 3
|
||||
%_ptr_Function_v3float = OpTypePointer Function %v3float
|
||||
%float_0 = OpConstant %float 0
|
||||
%11 = OpConstantComposite %v3float %float_0 %float_0 %float_0
|
||||
%bool = OpTypeBool
|
||||
%false = OpConstantFalse %bool
|
||||
%float_99 = OpConstant %float 99
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_spec_3 = OpSpecConstant %uint 3
|
||||
%_ptr_Function_float = OpTypePointer Function %float
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%v = OpVariable %_ptr_Function_v3float Function
|
||||
OpStore %v %11
|
||||
OpSelectionMerge %15 None
|
||||
OpBranchConditional %false %14 %15
|
||||
%14 = OpLabel
|
||||
%20 = OpAccessChain %_ptr_Function_float %v %uint_spec_3
|
||||
OpStore %20 %float_99
|
||||
OpBranch %15
|
||||
%15 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
47
shaders/asm/frag/out-of-bounds-access.asm.frag
Normal file
47
shaders/asm/frag/out-of-bounds-access.asm.frag
Normal file
@ -0,0 +1,47 @@
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Google Shaderc over Glslang; 10
|
||||
; Bound: 21
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main"
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpSource ESSL 320
|
||||
OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
|
||||
OpSourceExtension "GL_GOOGLE_include_directive"
|
||||
OpName %main "main"
|
||||
OpName %v "v"
|
||||
OpDecorate %v RelaxedPrecision
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%v3float = OpTypeVector %float 3
|
||||
%_ptr_Function_v3float = OpTypePointer Function %v3float
|
||||
%float_0 = OpConstant %float 0
|
||||
%11 = OpConstantComposite %v3float %float_0 %float_0 %float_0
|
||||
%bool = OpTypeBool
|
||||
%false = OpConstantFalse %bool
|
||||
%float_99 = OpConstant %float 99
|
||||
%float_88 = OpConstant %float 88
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_3 = OpConstant %uint 3
|
||||
%sint = OpTypeInt 32 1
|
||||
%sint_3 = OpConstant %sint -1
|
||||
%_ptr_Function_float = OpTypePointer Function %float
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%v = OpVariable %_ptr_Function_v3float Function
|
||||
OpStore %v %11
|
||||
OpSelectionMerge %15 None
|
||||
OpBranchConditional %false %14 %15
|
||||
%14 = OpLabel
|
||||
%20 = OpAccessChain %_ptr_Function_float %v %uint_3
|
||||
OpStore %20 %float_99
|
||||
%99 = OpAccessChain %_ptr_Function_float %v %sint_3
|
||||
OpStore %99 %float_88
|
||||
OpBranch %15
|
||||
%15 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
@ -8894,30 +8894,37 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
||||
is_packed);
|
||||
}
|
||||
|
||||
if (is_literal && !is_packed && !row_major_matrix_needs_conversion)
|
||||
if (is_literal)
|
||||
{
|
||||
bool out_of_bounds = (index >= type->vecsize);
|
||||
|
||||
if (!is_packed && !row_major_matrix_needs_conversion)
|
||||
{
|
||||
expr += ".";
|
||||
expr += index_to_swizzle(index);
|
||||
expr += index_to_swizzle(out_of_bounds ? 0 : index);
|
||||
}
|
||||
else
|
||||
{
|
||||
// For packed vectors, we can only access them as an array, not by swizzle.
|
||||
expr += join("[", out_of_bounds ? 0 : index, "]");
|
||||
}
|
||||
}
|
||||
else if (ir.ids[index].get_type() == TypeConstant && !is_packed && !row_major_matrix_needs_conversion)
|
||||
{
|
||||
auto &c = get<SPIRConstant>(index);
|
||||
bool out_of_bounds = (c.scalar() >= type->vecsize);
|
||||
|
||||
if (c.specialization)
|
||||
{
|
||||
// If the index is a spec constant, we cannot turn extract into a swizzle.
|
||||
expr += join("[", to_expression(index), "]");
|
||||
expr += join("[", out_of_bounds ? "0" : to_expression(index), "]");
|
||||
}
|
||||
else
|
||||
{
|
||||
expr += ".";
|
||||
expr += index_to_swizzle(c.scalar());
|
||||
expr += index_to_swizzle(out_of_bounds ? 0 : c.scalar());
|
||||
}
|
||||
}
|
||||
else if (is_literal)
|
||||
{
|
||||
// For packed vectors, we can only access them as an array, not by swizzle.
|
||||
expr += join("[", index, "]");
|
||||
}
|
||||
else
|
||||
{
|
||||
expr += "[";
|
||||
|
Loading…
Reference in New Issue
Block a user