Make tests properly exercise Some("") global names. (#1503)

The GLSL empty-global-name.frag test doesn't suffice because the GLSL front end
doesn't produce the same IR as the SPIR-V included in the bug report. As far as
I know, only a genuine SPIR-V input test can produce a global whose name is
`Some("")`.

Include the SPIR-V assembly source.
This commit is contained in:
Jim Blandy 2021-11-01 11:07:11 -07:00 committed by GitHub
parent 323999fcb9
commit c1b378842e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 115 additions and 28 deletions

View File

@ -1,7 +0,0 @@
layout(set = 1, binding = 1) uniform TextureData {
vec4 material;
};
void main() {
vec2 coords = vec2(material.xy);
}

Binary file not shown.

View File

@ -0,0 +1,44 @@
;; Make sure we handle globals whose assigned name is "".
;;
;; In MSL, the anonymous global sometimes ends up looking like
;;
;; struct Blah { int member; } ;
;;
;; where the null name just becomes an empty string before that last semicolon.
;; This is, unfortunately, valid MSL, simply declaring the type Blah, so it will
;; pass validation. However, an attempt to *use* the global will generate a
;; garbage expression like ".member", so we include a function that returns the
;; member's value.
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main" %global
OpExecutionMode %main LocalSize 64 1 1
OpName %global ""
OpDecorate %block Block
OpMemberDecorate %block 0 Offset 0
OpDecorate %global DescriptorSet 0
OpDecorate %global Binding 0
%void = OpTypeVoid
%int = OpTypeInt 32 1
%block = OpTypeStruct %int
%ptr_int = OpTypePointer StorageBuffer %int
%ptr_block = OpTypePointer StorageBuffer %block
%fn_void = OpTypeFunction %void
%fn_int = OpTypeFunction %int
%zero = OpConstant %int 0
%one = OpConstant %int 1
;; This global is said to have a name of "".
%global = OpVariable %ptr_block StorageBuffer
%main = OpFunction %void None %fn_void
%main_prelude = OpLabel
%member_ptr = OpAccessChain %ptr_int %global %zero
%member_val = OpLoad %int %member_ptr
%plus_one = OpIAdd %int %member_val %one
OpStore %member_ptr %plus_one
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,19 @@
struct type1 {
int member;
};
RWByteAddressBuffer global : register(u0);
void function()
{
int _expr8 = asint(global.Load(0));
global.Store(0, asuint((_expr8 + 1)));
return;
}
[numthreads(64, 1, 1)]
void main()
{
function();
}

View File

@ -0,0 +1,3 @@
vertex=()
fragment=()
compute=(main:cs_5_1 )

View File

@ -0,0 +1,21 @@
// language: metal1.1
#include <metal_stdlib>
#include <simd/simd.h>
struct type1 {
int member;
};
void function(
device type1& global
) {
int _e8 = global.member;
global.member = _e8 + 1;
return;
}
kernel void main1(
device type1& global [[user(fake0)]]
) {
function(global);
}

View File

@ -1,21 +0,0 @@
[[block]]
struct TextureData {
material: vec4<f32>;
};
[[group(1), binding(1)]]
var<uniform> global: TextureData;
fn main1() {
var coords: vec2<f32>;
let e2: vec4<f32> = global.material;
coords = vec2<f32>(e2.xy);
return;
}
[[stage(fragment)]]
fn main() {
main1();
return;
}

View File

@ -0,0 +1,18 @@
[[block]]
struct type2 {
member: i32;
};
[[group(0), binding(0)]]
var<storage, read_write> global: type2;
fn function1() {
let e8: i32 = global.member;
global.member = (e8 + 1);
return;
}
[[stage(compute), workgroup_size(64, 1, 1)]]
fn main() {
function1();
}

View File

@ -598,6 +598,16 @@ fn convert_spv_inverse_hyperbolic_trig_functions() {
);
}
#[cfg(feature = "spv-in")]
#[test]
fn convert_spv_empty_global_name() {
convert_spv(
"empty-global-name",
true,
Targets::HLSL | Targets::WGSL | Targets::METAL,
);
}
#[cfg(feature = "glsl-in")]
#[allow(unused_variables)]
#[test]