tests: run both with and without --spirt.

This commit is contained in:
Eduard-Mihai Burtescu 2022-12-12 15:02:52 +02:00 committed by Eduard-Mihai Burtescu
parent 8535bb3bf1
commit 3fca36ecb2
76 changed files with 514 additions and 251 deletions

View File

@ -1,4 +1,4 @@
use super::{link, LinkResult, Options};
use super::{link, LinkResult};
use pipe::pipe;
use rspirv::dr::{Loader, Module};
use rustc_errors::registry::Registry;
@ -53,7 +53,55 @@ fn load(bytes: &[u8]) -> Module {
loader.module()
}
fn assemble_and_link(binaries: &[&[u8]]) -> Result<Module, PrettyString> {
struct TestLinkOutputs {
// Old output, equivalent to not passing `--spirt` in codegen args.
without_spirt: Module,
// New output, equivalent to passing `--spirt` in codegen args.
with_spirt: Module,
}
// FIXME(eddyb) shouldn't this be named just `link`? (`assemble_spirv` is separate)
fn assemble_and_link(binaries: &[&[u8]]) -> Result<TestLinkOutputs, PrettyString> {
let link_with_spirt = |spirt: bool| {
link_with_linker_opts(
binaries,
&crate::linker::Options {
compact_ids: true,
dce: true,
keep_link_exports: true,
spirt,
..Default::default()
},
)
};
match [link_with_spirt(false), link_with_spirt(true)] {
[Ok(without_spirt), Ok(with_spirt)] => Ok(TestLinkOutputs {
without_spirt,
with_spirt,
}),
[Err(without_spirt), Err(with_spirt)] if without_spirt == with_spirt => Err(without_spirt),
// Different error, or only one side errored.
[without_spirt, with_spirt] => {
let pretty = |result: Result<Module, _>| {
result.map(|m| {
use rspirv::binary::Disassemble;
PrettyString(m.disassemble())
})
};
// HACK(eddyb) using `assert_eq!` to dump the different `Result`s.
assert_eq!(pretty(without_spirt), pretty(with_spirt));
unreachable!();
}
}
}
fn link_with_linker_opts(
binaries: &[&[u8]],
opts: &crate::linker::Options,
) -> Result<Module, PrettyString> {
let modules = binaries.iter().cloned().map(load).collect::<Vec<_>>();
// FIXME(eddyb) this seems ridiculous, we should be able to write to
@ -118,16 +166,7 @@ fn assemble_and_link(binaries: &[&[u8]]) -> Result<Module, PrettyString> {
)
};
let res = link(
&sess,
modules,
&Options {
compact_ids: true,
dce: true,
keep_link_exports: true,
..Default::default()
},
);
let res = link(&sess, modules, opts);
assert_eq!(sess.has_errors(), res.as_ref().err().copied());
res.map(|res| match res {
LinkResult::SingleModule(m) => *m,
@ -141,14 +180,33 @@ fn assemble_and_link(binaries: &[&[u8]]) -> Result<Module, PrettyString> {
}
#[track_caller]
fn without_header_eq(mut result: Module, expected: &str) {
use rspirv::binary::Disassemble;
//use rspirv::binary::Assemble;
fn without_header_eq(outputs: TestLinkOutputs, expected: &str) {
let result = {
let disasm = |mut result: Module| {
use rspirv::binary::Disassemble;
//use rspirv::binary::Assemble;
// validate(&result.assemble());
// validate(&result.assemble());
result.header = None;
let result = result.disassemble();
result.header = None;
result.disassemble()
};
let [without_spirt, with_spirt] =
[disasm(outputs.without_spirt), disasm(outputs.with_spirt)];
// HACK(eddyb) merge the two outputs into a single "dump".
if without_spirt == with_spirt {
without_spirt
} else {
format!(
"=== without SPIR-T ===\n\
{without_spirt}\n\
\n\
=== with SPIR-T ===\n\
{with_spirt}"
)
}
};
let expected = expected
.split('\n')
@ -471,7 +529,8 @@ fn use_exported_func_param_attr() {
let result = assemble_and_link(&[&a, &b]).unwrap();
let expect = r#"OpCapability Kernel
let expect = r#"=== without SPIR-T ===
OpCapability Kernel
OpCapability Linkage
OpMemoryModel Logical OpenCL
OpDecorate %1 FuncParamAttr Zext
@ -492,6 +551,30 @@ fn use_exported_func_param_attr() {
%10 = OpLabel
%11 = OpLoad %6 %4
OpReturn
OpFunctionEnd
=== with SPIR-T ===
OpCapability Linkage
OpCapability Kernel
OpMemoryModel Logical OpenCL
OpDecorate %1 FuncParamAttr Zext
OpDecorate %2 FuncParamAttr Sext
OpDecorate %3 LinkageAttributes "HACK(eddyb) keep function alive" Export
OpDecorate %4 LinkageAttributes "foo" Export
%5 = OpTypeVoid
%6 = OpTypeInt 32 0
%7 = OpTypeFunction %5 %6
%3 = OpFunction %5 None %7
%1 = OpFunctionParameter %6
%8 = OpLabel
%9 = OpLoad %6 %1
OpReturn
OpFunctionEnd
%4 = OpFunction %5 None %7
%2 = OpFunctionParameter %6
%10 = OpLabel
%11 = OpLoad %6 %2
OpReturn
OpFunctionEnd"#;
without_header_eq(result, expect);
@ -550,7 +633,8 @@ fn names_and_decorations() {
let result = assemble_and_link(&[&a, &b]).unwrap();
let expect = r#"OpCapability Kernel
let expect = r#"=== without SPIR-T ===
OpCapability Kernel
OpCapability Linkage
OpMemoryModel Logical OpenCL
OpName %1 "foo"
@ -575,6 +659,34 @@ fn names_and_decorations() {
%11 = OpLabel
%12 = OpLoad %6 %2
OpReturn
OpFunctionEnd
=== with SPIR-T ===
OpCapability Linkage
OpCapability Kernel
OpMemoryModel Logical OpenCL
OpName %1 "foo"
OpName %2 "param"
OpDecorate %3 Restrict
OpDecorate %3 NonWritable
OpDecorate %2 Restrict
OpDecorate %4 LinkageAttributes "HACK(eddyb) keep function alive" Export
OpDecorate %1 LinkageAttributes "foo" Export
%5 = OpTypeVoid
%6 = OpTypeInt 32 0
%7 = OpTypePointer Function %6
%8 = OpTypeFunction %5 %7
%4 = OpFunction %5 None %8
%3 = OpFunctionParameter %7
%9 = OpLabel
%10 = OpLoad %6 %3
OpReturn
OpFunctionEnd
%1 = OpFunction %5 None %8
%2 = OpFunctionParameter %7
%11 = OpLabel
%12 = OpLoad %6 %2
OpReturn
OpFunctionEnd"#;
without_header_eq(result, expect);

View File

@ -27,8 +27,8 @@ struct Opt {
}
impl Opt {
pub fn environments(&self) -> Vec<String> {
self.target_env.split(',').map(String::from).collect()
pub fn environments(&self) -> impl Iterator<Item = &str> {
self.target_env.split(',')
}
}
@ -125,12 +125,20 @@ impl Runner {
.join(" ")
}
for env in self.opt.environments() {
let target = format!("{}{}", TARGET_PREFIX, env);
let mut config = compiletest::Config::default();
let libs = build_deps(&self.deps_target_dir, &self.codegen_backend_path, &target);
for (env, spirt) in self
.opt
.environments()
.flat_map(|env| [(env, false), (env, true)])
{
// HACK(eddyb) in order to allow *some* tests to have separate output
// with the SPIR-T support enabled (via `--spirt`), while keeping
// *most* of the tests unchanged, we take advantage of "stage IDs",
// which offer `// only-S` and `// ignore-S` for any stage ID `S`.
let stage_id = if spirt { "spirt" } else { "not_spirt" };
let flags = test_rustc_flags(
let target = format!("{}{}", TARGET_PREFIX, env);
let libs = build_deps(&self.deps_target_dir, &self.codegen_backend_path, &target);
let mut flags = test_rustc_flags(
&self.codegen_backend_path,
&libs,
&[
@ -142,14 +150,22 @@ impl Runner {
.join(DepKind::ProcMacro.target_dir_suffix(&target)),
],
);
if spirt {
flags += " -Cllvm-args=--spirt";
}
config.target_rustcflags = Some(flags);
config.mode = mode.parse().expect("Invalid mode");
config.target = target;
config.src_base = self.tests_dir.join(mode);
config.build_base = self.compiletest_build_dir.clone();
config.bless = self.opt.bless;
config.filters = self.opt.filters.clone();
let config = compiletest::Config {
stage_id: stage_id.to_string(),
target_rustcflags: Some(flags),
mode: mode.parse().expect("Invalid mode"),
target,
src_base: self.tests_dir.join(mode),
build_base: self.compiletest_build_dir.clone(),
bless: self.opt.bless,
filters: self.opt.filters.clone(),
..compiletest::Config::default()
};
// FIXME(eddyb) do we need this? shouldn't `compiletest` be independent?
config.clean_rmeta();
compiletest::run_tests(&config);

View File

@ -1,3 +1,5 @@
// normalize-stderr-not_spirt "OpLine %8 11 1" -> "OpNoLine"
// build-pass
// compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model
// compile-flags: -C llvm-args=--disassemble-fn=all_memory_barrier::all_memory_barrier

View File

@ -2,6 +2,6 @@
%4 = OpLabel
OpLine %5 75 4
OpMemoryBarrier %6 %7
OpLine %8 9 1
OpNoLine
OpReturn
OpFunctionEnd

View File

@ -1,3 +1,5 @@
// normalize-stderr-not_spirt "OpLine %9 11 1" -> "OpNoLine"
// build-pass
// compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model
// compile-flags: -C llvm-args=--disassemble-fn=all_memory_barrier_with_group_sync::all_memory_barrier_with_group_sync

View File

@ -2,6 +2,6 @@
%4 = OpLabel
OpLine %5 41 4
OpControlBarrier %6 %7 %8
OpLine %9 9 1
OpNoLine
OpReturn
OpFunctionEnd

View File

@ -1,3 +1,5 @@
// normalize-stderr-not_spirt "OpLine %8 11 1" -> "OpNoLine"
// build-pass
// compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model
// compile-flags: -C llvm-args=--disassemble-fn=device_memory_barrier::device_memory_barrier

View File

@ -2,6 +2,6 @@
%4 = OpLabel
OpLine %5 75 4
OpMemoryBarrier %6 %7
OpLine %8 9 1
OpNoLine
OpReturn
OpFunctionEnd

View File

@ -1,3 +1,5 @@
// normalize-stderr-not_spirt "OpLine %9 11 1" -> "OpNoLine"
// build-pass
// compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model
// compile-flags: -C llvm-args=--disassemble-fn=device_memory_barrier_with_group_sync::device_memory_barrier_with_group_sync

View File

@ -2,6 +2,6 @@
%4 = OpLabel
OpLine %5 41 4
OpControlBarrier %6 %7 %8
OpLine %9 9 1
OpNoLine
OpReturn
OpFunctionEnd

View File

@ -1,3 +1,5 @@
// normalize-stderr-not_spirt "OpLine %8 10 1" -> "OpNoLine"
// build-pass
// compile-flags: -C llvm-args=--disassemble-fn=workgroup_memory_barrier::workgroup_memory_barrier

View File

@ -2,6 +2,6 @@
%4 = OpLabel
OpLine %5 75 4
OpMemoryBarrier %6 %7
OpLine %8 8 1
OpNoLine
OpReturn
OpFunctionEnd

View File

@ -1,3 +1,5 @@
// normalize-stderr-not_spirt "OpLine %8 10 1" -> "OpNoLine"
// build-pass
// compile-flags: -C llvm-args=--disassemble-fn=workgroup_memory_barrier_with_group_sync::workgroup_memory_barrier_with_group_sync

View File

@ -2,6 +2,6 @@
%4 = OpLabel
OpLine %5 41 4
OpControlBarrier %6 %6 %7
OpLine %8 8 1
OpNoLine
OpReturn
OpFunctionEnd

View File

@ -1,3 +1,5 @@
// normalize-stderr-not_spirt "OpLine %7 10 1" -> "OpNoLine"
// build-pass
// compile-flags: -C llvm-args=--disassemble-fn=add_two_ints::add_two_ints

View File

@ -2,8 +2,8 @@
%4 = OpFunctionParameter %2
%5 = OpFunctionParameter %2
%6 = OpLabel
OpLine %7 7 4
OpLine %7 9 4
%8 = OpIAdd %2 %4 %5
OpLine %7 8 1
OpNoLine
OpReturnValue %8
OpFunctionEnd

View File

@ -1,3 +1,5 @@
// normalize-stderr-not_spirt "OpLine %5 18 1" -> "OpNoLine"
// build-pass
// compile-flags: -C llvm-args=--disassemble-fn=asm::asm

View File

@ -1,7 +1,7 @@
%1 = OpFunction %2 None %3
%4 = OpLabel
OpLine %5 9 8
OpLine %5 11 8
OpMemoryBarrier %6 %7
OpLine %5 16 1
OpNoLine
OpReturn
OpFunctionEnd

View File

@ -1,3 +1,5 @@
// normalize-stderr-not_spirt "OpLine %7 20 1" -> "OpNoLine"
// build-pass
// compile-flags: -C llvm-args=--disassemble-fn=asm_add_two_ints::add_two_ints

View File

@ -2,8 +2,8 @@
%4 = OpFunctionParameter %2
%5 = OpFunctionParameter %2
%6 = OpLabel
OpLine %7 10 8
OpLine %7 12 8
%8 = OpIAdd %2 %4 %5
OpLine %7 18 1
OpNoLine
OpReturnValue %8
OpFunctionEnd

View File

@ -1,3 +1,6 @@
// HACK(eddyb) duplicate of asm_op_decorate.spirt.rs because only-/ignore- do not work with revisions.
// only-not_spirt
// build-pass
// compile-flags: -C target-feature=+RuntimeDescriptorArray,+ext:SPV_EXT_descriptor_indexing
// compile-flags: -C llvm-args=--disassemble-globals

View File

@ -0,0 +1,4 @@
error: invalid character `'.'` in crate name: `asm_op_decorate.not_spirt`
error: aborting due to previous error

View File

@ -0,0 +1,48 @@
// HACK(eddyb) duplicate of asm_op_decorate.not_spirt.rs because only-/ignore- do not work with revisions.
// only-spirt
// build-pass
// compile-flags: -C target-feature=+RuntimeDescriptorArray,+ext:SPV_EXT_descriptor_indexing
// compile-flags: -C llvm-args=--disassemble-globals
// normalize-stderr-test "OpCapability VulkanMemoryModel\n" -> ""
// normalize-stderr-test "OpExtension .SPV_KHR_vulkan_memory_model.\n" -> ""
// normalize-stderr-test "OpMemoryModel Logical Vulkan" -> "OpMemoryModel Logical Simple"
// FIXME(eddyb) this should use revisions to track both the `vulkan1.2` output
// and the pre-`vulkan1.2` output, but per-revisions `{only,ignore}-*` directives
// are not supported in `compiletest-rs`.
// ignore-vulkan1.2
use core::arch::asm;
use spirv_std::spirv;
fn add_decorate() {
unsafe {
let offset = 1u32;
asm!(
"OpDecorate %image_2d_var DescriptorSet 0",
"OpDecorate %image_2d_var Binding 0",
"%uint = OpTypeInt 32 0",
"%float = OpTypeFloat 32",
"%uint_0 = OpConstant %uint 0",
"%image_2d = OpTypeImage %float Dim2D 0 0 0 1 Unknown",
"%sampled_image_2d = OpTypeSampledImage %image_2d",
"%image_array = OpTypeRuntimeArray %sampled_image_2d",
// NOTE(eddyb) `Generic` is used here because it's the placeholder
// for storage class inference - both of the two `OpTypePointer`
// types below should end up inferring to `UniformConstant`.
"%ptr_image_array = OpTypePointer Generic %image_array",
"%image_2d_var = OpVariable %ptr_image_array UniformConstant",
"%ptr_sampled_image_2d = OpTypePointer Generic %sampled_image_2d",
"", // ^^ type preamble
"%offset = OpLoad _ {0}",
"%24 = OpAccessChain %ptr_sampled_image_2d %image_2d_var %offset",
"%25 = OpLoad %sampled_image_2d %24",
in(reg) &offset,
);
}
}
#[spirv(fragment)]
pub fn main() {
add_decorate();
}

View File

@ -0,0 +1,4 @@
error: invalid character `'.'` in crate name: `asm_op_decorate.spirt`
error: aborting due to previous error

View File

@ -1,29 +0,0 @@
OpCapability Float64
OpCapability Int16
OpCapability Int64
OpCapability Int8
OpCapability RuntimeDescriptorArray
OpCapability ShaderClockKHR
OpCapability Shader
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_KHR_shader_clock"
OpMemoryModel Logical Simple
OpEntryPoint Fragment %1 "main"
OpExecutionMode %1 OriginUpperLeft
%2 = OpString "$OPSTRING_FILENAME/asm_op_decorate.rs"
OpName %3 "asm_op_decorate::add_decorate"
OpName %4 "asm_op_decorate::main"
OpDecorate %5 ArrayStride 4
OpDecorate %6 DescriptorSet 0
OpDecorate %6 Binding 0
%7 = OpTypeVoid
%8 = OpTypeFunction %7
%9 = OpTypeInt 32 0
%10 = OpConstant %9 1
%11 = OpTypeFloat 32
%12 = OpTypeImage %11 2D 0 0 0 1 Unknown
%13 = OpTypeSampledImage %12
%5 = OpTypeRuntimeArray %13
%14 = OpTypePointer UniformConstant %5
%6 = OpVariable %14 UniformConstant
%15 = OpTypePointer UniformConstant %13

View File

@ -1,3 +1,5 @@
// normalize-stderr-not_spirt "OpLine %12 60 1" -> "OpNoLine"
// build-pass
// compile-flags: -Ctarget-feature=+RuntimeDescriptorArray,+ext:SPV_EXT_descriptor_indexing
// compile-flags: -C llvm-args=--disassemble-fn=complex_image_sample_inst::sample_proj_lod

View File

@ -5,10 +5,10 @@
%8 = OpFunctionParameter %9
%10 = OpFunctionParameter %9
%11 = OpLabel
OpLine %12 18 8
OpLine %12 20 8
%13 = OpAccessChain %14 %15 %16
%17 = OpLoad %18 %13
%19 = OpImageSampleProjExplicitLod %2 %17 %4 Grad|ConstOffset %5 %7 %20
OpLine %12 58 1
OpNoLine
OpReturnValue %19
OpFunctionEnd

View File

@ -1,3 +1,6 @@
// HACK(eddyb) duplicate of custom_entry_point.spirt.rs because only-/ignore- do not work with revisions.
// only-not_spirt
// build-pass
// compile-flags: -C llvm-args=--disassemble-globals
// normalize-stderr-test "OpCapability VulkanMemoryModel\n" -> ""

View File

@ -0,0 +1,4 @@
error: invalid character `'.'` in crate name: `custom_entry_point.not_spirt`
error: aborting due to previous error

View File

@ -0,0 +1,13 @@
// HACK(eddyb) duplicate of custom_entry_point.not_spirt.rs because only-/ignore- do not work with revisions.
// only-spirt
// build-pass
// compile-flags: -C llvm-args=--disassemble-globals
// normalize-stderr-test "OpCapability VulkanMemoryModel\n" -> ""
// normalize-stderr-test "OpExtension .SPV_KHR_vulkan_memory_model.\n" -> ""
// normalize-stderr-test "OpMemoryModel Logical Vulkan" -> "OpMemoryModel Logical Simple"
use spirv_std::spirv;
#[spirv(fragment(entry_point_name = "hello_world"))]
pub fn main() {}

View File

@ -0,0 +1,4 @@
error: invalid character `'.'` in crate name: `custom_entry_point.spirt`
error: aborting due to previous error

View File

@ -1,14 +0,0 @@
OpCapability Float64
OpCapability Int16
OpCapability Int64
OpCapability Int8
OpCapability ShaderClockKHR
OpCapability Shader
OpExtension "SPV_KHR_shader_clock"
OpMemoryModel Logical Simple
OpEntryPoint Fragment %1 "hello_world"
OpExecutionMode %1 OriginUpperLeft
%2 = OpString "$OPSTRING_FILENAME/custom_entry_point.rs"
OpName %3 "custom_entry_point::main"
%4 = OpTypeVoid
%5 = OpTypeFunction %4

View File

@ -1,3 +1,5 @@
// normalize-stderr-not_spirt "OpLine %5 18 1" -> "OpNoLine"
// This is a similar setup to the `issue-731` test, but instead of "just" the
// missing copy out of the global (`Input`) `OpVariable`, small enough types
// would fail much earlier (by generating unsupported pointer casts).

View File

@ -1,13 +1,13 @@
%1 = OpFunction %2 None %3
%4 = OpLabel
OpLine %5 13 12
OpLine %5 15 12
%6 = OpLoad %7 %8
OpLine %5 14 4
OpLine %5 16 4
%9 = OpCompositeExtract %10 %6 0
%11 = OpFAdd %10 %9 %12
%13 = OpCompositeInsert %7 %11 %6 0
OpLine %5 15 4
OpLine %5 17 4
OpStore %14 %13
OpLine %5 16 1
OpNoLine
OpReturn
OpFunctionEnd

View File

@ -1,3 +1,6 @@
// HACK(eddyb) duplicate of generic-fn-op-name.spirt.rs because only-/ignore- do not work with revisions.
// only-not_spirt
// Test that generic functions' `OpName` correctly include generic arguments.
// build-pass

View File

@ -0,0 +1,4 @@
error: invalid character `'.'` in crate name: `generic_fn_op_name.not_spirt`
error: aborting due to previous error

View File

@ -0,0 +1,23 @@
// HACK(eddyb) duplicate of generic-fn-op-name.not_spirt.rs because only-/ignore- do not work with revisions.
// only-spirt
// Test that generic functions' `OpName` correctly include generic arguments.
// build-pass
// compile-flags: -C llvm-args=--disassemble-globals
// normalize-stderr-test "OpCapability VulkanMemoryModel\n" -> ""
// normalize-stderr-test "OpExtension .SPV_KHR_vulkan_memory_model.\n" -> ""
// normalize-stderr-test "OpMemoryModel Logical Vulkan" -> "OpMemoryModel Logical Simple"
#![feature(adt_const_params)]
#![allow(incomplete_features)]
use spirv_std::image::Dimensionality;
use spirv_std::spirv;
fn generic<T, const DIM: Dimensionality>() {}
#[spirv(fragment)]
pub fn main() {
generic::<f32, { Dimensionality::TwoD }>();
}

View File

@ -0,0 +1,4 @@
error: invalid character `'.'` in crate name: `generic_fn_op_name.spirt`
error: aborting due to previous error

View File

@ -1,15 +0,0 @@
OpCapability Float64
OpCapability Int16
OpCapability Int64
OpCapability Int8
OpCapability ShaderClockKHR
OpCapability Shader
OpExtension "SPV_KHR_shader_clock"
OpMemoryModel Logical Simple
OpEntryPoint Fragment %1 "main"
OpExecutionMode %1 OriginUpperLeft
%2 = OpString "$OPSTRING_FILENAME/generic-fn-op-name.rs"
OpName %3 "generic_fn_op_name::generic::<f32, {spirv_std_types::image_params::Dimensionality::TwoD}>"
OpName %4 "generic_fn_op_name::main"
%5 = OpTypeVoid
%6 = OpTypeFunction %5

View File

@ -1,3 +1,6 @@
// HACK(eddyb) duplicate of index_user_dst.spirt.rs because only-/ignore- do not work with revisions.
// only-not_spirt
// build-pass
// compile-flags: -C llvm-args=--disassemble-entry=main

View File

@ -0,0 +1,4 @@
error: invalid character `'.'` in crate name: `index_user_dst.not_spirt`
error: aborting due to previous error

View File

@ -0,0 +1,13 @@
// HACK(eddyb) duplicate of index_user_dst.not_spirt.rs because only-/ignore- do not work with revisions.
// only-spirt
// build-pass
// compile-flags: -C llvm-args=--disassemble-entry=main
use spirv_std::spirv;
#[spirv(fragment)]
pub fn main(#[spirv(storage_buffer, descriptor_set = 0, binding = 0)] slice: &mut [f32]) {
let float: f32 = slice[0];
let _ = float;
}

View File

@ -0,0 +1,4 @@
error: invalid character `'.'` in crate name: `index_user_dst.spirt`
error: aborting due to previous error

View File

@ -1,34 +0,0 @@
%1 = OpFunction %2 None %3
%4 = OpLabel
OpLine %5 7 12
%6 = OpAccessChain %7 %8 %9
%10 = OpArrayLength %11 %8 0
OpLine %5 8 21
%12 = OpULessThan %13 %9 %10
OpLine %5 8 21
OpSelectionMerge %14 None
OpBranchConditional %12 %15 %16
%15 = OpLabel
OpLine %5 8 21
%17 = OpInBoundsAccessChain %18 %6 %9
%19 = OpLoad %20 %17
OpLine %5 10 1
OpReturn
%16 = OpLabel
OpLine %5 8 21
OpBranch %21
%21 = OpLabel
OpBranch %22
%22 = OpLabel
%23 = OpPhi %13 %24 %21 %24 %25
OpLoopMerge %26 %25 None
OpBranchConditional %23 %27 %26
%27 = OpLabel
OpBranch %25
%25 = OpLabel
OpBranch %22
%26 = OpLabel
OpUnreachable
%14 = OpLabel
OpUnreachable
OpFunctionEnd

View File

@ -1,3 +1,6 @@
// HACK(eddyb) duplicate of issue-373.spirt.rs because only-/ignore- do not work with revisions.
// only-not_spirt
// Test that returning a single-scalar-field `#[repr(C)] struct` doesn't generate
// unsupported pointer casts (the problem was the use of `PassMode::Cast`, through
// the default Rust ABI adjustments, that we now override through query hooks).

View File

@ -0,0 +1,4 @@
error: invalid character `'.'` in crate name: `issue_373.not_spirt`
error: aborting due to previous error

View File

@ -0,0 +1,26 @@
// HACK(eddyb) duplicate of issue-373.not_spirt.rs because only-/ignore- do not work with revisions.
// only-spirt
// Test that returning a single-scalar-field `#[repr(C)] struct` doesn't generate
// unsupported pointer casts (the problem was the use of `PassMode::Cast`, through
// the default Rust ABI adjustments, that we now override through query hooks).
// build-pass
// compile-flags: -C llvm-args=--disassemble-entry=main
use spirv_std::spirv;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct S {
x: f32,
}
fn f() -> S {
S { x: 2.0 }
}
#[spirv(fragment)]
pub fn main(out: &mut f32) {
*out = f().x;
}

View File

@ -0,0 +1,4 @@
error: invalid character `'.'` in crate name: `issue_373.spirt`
error: aborting due to previous error

View File

@ -1,11 +0,0 @@
%1 = OpFunction %2 None %3
%4 = OpLabel
OpLine %5 22 11
%6 = OpFunctionCall %7 %8
OpLine %5 22 11
%9 = OpCompositeExtract %10 %6 0
OpLine %5 22 4
OpStore %11 %9
OpLine %5 23 1
OpReturn
OpFunctionEnd

View File

@ -1,3 +1,6 @@
// HACK(eddyb) duplicate of issue-723-output.spirt.rs because only-/ignore- do not work with revisions.
// only-not_spirt
// Test that interface (global) `OpVariable`s mentioned by `OpEntryPoint` don't
// have to be used by the shader, for storage class inference to succeed.

View File

@ -0,0 +1,4 @@
error: invalid character `'.'` in crate name: `issue_723_output.not_spirt`
error: aborting due to previous error

View File

@ -0,0 +1,25 @@
// HACK(eddyb) duplicate of issue-723-output.not_spirt.rs because only-/ignore- do not work with revisions.
// only-spirt
// Test that interface (global) `OpVariable`s mentioned by `OpEntryPoint` don't
// have to be used by the shader, for storage class inference to succeed.
// NOTE(eddyb) this relies on two subtleties (in order to fail without the fix):
// * disabling debuginfo (to prevent `%x.dbg.spill` stack slot generation)
// * this could be alleviated in the future if we clean up how debuginfo
// is handled in `rustc_codegen_ssa`, to not assume LLVM limitations
// * it probably needs to stay like this, to ensure the parameter is unused
// * `Output`s being handled with `&mut`, instead of by-value returns
// * if this changes, this test will likely need >=1.4 SPIR-V, which supports
// all interface `OpVariables` in `OpEntryPoint`, not just `Input`/`Output`
// build-pass
// compile-flags: -C debuginfo=0 -C llvm-args=--disassemble-globals
// normalize-stderr-test "OpCapability VulkanMemoryModel\n" -> ""
// normalize-stderr-test "OpExtension .SPV_KHR_vulkan_memory_model.\n" -> ""
// normalize-stderr-test "OpMemoryModel Logical Vulkan" -> "OpMemoryModel Logical Simple"
use spirv_std::spirv;
#[spirv(fragment)]
pub fn main(/* unused Output */ _: &mut glam::Vec4) {}

View File

@ -0,0 +1,4 @@
error: invalid character `'.'` in crate name: `issue_723_output.spirt`
error: aborting due to previous error

View File

@ -1,19 +0,0 @@
OpCapability Float64
OpCapability Int16
OpCapability Int64
OpCapability Int8
OpCapability ShaderClockKHR
OpCapability Shader
OpExtension "SPV_KHR_shader_clock"
OpMemoryModel Logical Simple
OpEntryPoint Fragment %1 "main" %2
OpExecutionMode %1 OriginUpperLeft
%3 = OpString "$OPSTRING_FILENAME/issue-723-output.rs"
OpName %4 "issue_723_output::main"
OpDecorate %2 Location 0
%5 = OpTypeVoid
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpTypeFunction %5
%2 = OpVariable %8 Output

View File

@ -1,3 +1,5 @@
// normalize-stderr-not_spirt "OpLine %5 16 1" -> "OpNoLine"
// Test that non-immediate (i.e. not one of scalar/scalar-pair/vector) inputs
// get properly copied out of the global (`Input`) `OpVariable` and mutation is
// only ever done on `fn`-local `OpVariable`s, not on the original global.

View File

@ -1,13 +1,13 @@
%1 = OpFunction %2 None %3
%4 = OpLabel
OpLine %5 11 12
OpLine %5 13 12
%6 = OpLoad %7 %8
OpLine %5 12 4
OpLine %5 14 4
%9 = OpCompositeExtract %10 %6 0
%11 = OpFAdd %10 %9 %12
%13 = OpCompositeInsert %7 %11 %6 0
OpLine %5 13 4
OpLine %5 15 4
OpStore %14 %13
OpLine %5 14 1
OpNoLine
OpReturn
OpFunctionEnd

View File

@ -1,3 +1,6 @@
// HACK(eddyb) duplicate of pass-mode-cast-struct.spirt.rs because only-/ignore- do not work with revisions.
// only-not_spirt
// Test that a small enough `struct` doesn't generate unsupported pointer casts.
// (Just like `issue-373`, the problem was the use of `PassMode::Cast`, through
// the default Rust ABI adjustments, that we now override through query hooks)

View File

@ -0,0 +1,4 @@
error: invalid character `'.'` in crate name: `pass_mode_cast_struct.not_spirt`
error: aborting due to previous error

View File

@ -0,0 +1,33 @@
// HACK(eddyb) duplicate of pass-mode-cast-struct.not_spirt.rs because only-/ignore- do not work with revisions.
// only-spirt
// Test that a small enough `struct` doesn't generate unsupported pointer casts.
// (Just like `issue-373`, the problem was the use of `PassMode::Cast`, through
// the default Rust ABI adjustments, that we now override through query hooks)
// build-pass
// compile-flags: -C llvm-args=--disassemble-entry=main
use spirv_std::spirv;
struct Foo {
a: u32,
b: u8,
c: u8,
}
impl Foo {
fn unpack(data: u64) -> Self {
Self {
a: (data >> 16 & 0xffffff) as u32,
b: (data & 0xff >> 8) as u8,
c: (data & 0xff) as u8,
}
}
}
#[spirv(fragment)]
pub fn main(#[spirv(flat)] in_packed: u64, out_sum: &mut u32) {
let foo = Foo::unpack(in_packed);
*out_sum = foo.a + (foo.b + foo.c) as u32;
}

View File

@ -0,0 +1,4 @@
error: invalid character `'.'` in crate name: `pass_mode_cast_struct.spirt`
error: aborting due to previous error

View File

@ -1,22 +0,0 @@
%1 = OpFunction %2 None %3
%4 = OpLabel
OpLine %5 27 12
%6 = OpLoad %7 %8
OpLine %5 28 14
%9 = OpFunctionCall %10 %11 %6
OpLine %5 29 15
%12 = OpCompositeExtract %13 %9 0
OpLine %5 29 24
%14 = OpCompositeExtract %15 %9 1
OpLine %5 29 32
%16 = OpCompositeExtract %15 %9 2
OpLine %5 29 23
%17 = OpIAdd %15 %14 %16
OpLine %5 29 23
%18 = OpUConvert %13 %17
OpLine %5 29 4
%19 = OpIAdd %13 %12 %18
OpStore %20 %19
OpLine %5 30 1
OpReturn
OpFunctionEnd

View File

@ -1,7 +1,9 @@
// normalize-stderr-not_spirt "OpLine %8 32 1" -> "OpNoLine"
// revisions: normal via_intrinsic
// [normal] build-fail
//[normal] build-fail
// normalize-stderr-test "\S*/library/core/src/" -> "$$CORE_SRC/"
// [via_intrinsic] build-pass
//[via_intrinsic] build-pass
// compile-flags: -C llvm-args=--disassemble-fn=ptr_copy::copy_via_raw_ptr
#![cfg_attr(via_intrinsic, feature(intrinsics))]

View File

@ -2,8 +2,8 @@
%4 = OpFunctionParameter %5
%6 = OpFunctionParameter %5
%7 = OpLabel
OpLine %8 17 17
OpLine %8 19 17
OpCopyMemory %6 %4
OpLine %8 30 1
OpNoLine
OpReturn
OpFunctionEnd

View File

@ -1,3 +1,5 @@
// normalize-stderr-not_spirt "OpLine %11 10 1" -> "OpNoLine"
// build-pass
// compile-flags: -C llvm-args=--disassemble-fn=ptr_read::copy_via_raw_ptr

View File

@ -4,8 +4,8 @@
%7 = OpLabel
OpLine %8 1139 8
%9 = OpLoad %10 %4
OpLine %11 7 13
OpLine %11 9 13
OpStore %6 %9
OpLine %11 8 1
OpNoLine
OpReturn
OpFunctionEnd

View File

@ -1,3 +1,5 @@
// normalize-stderr-not_spirt "OpLine %11 10 1" -> "OpNoLine"
// build-pass
// compile-flags: -C llvm-args=--disassemble-fn=ptr_read_method::copy_via_raw_ptr

View File

@ -4,8 +4,8 @@
%7 = OpLabel
OpLine %8 1139 8
%9 = OpLoad %10 %4
OpLine %11 7 13
OpLine %11 9 13
OpStore %6 %9
OpLine %11 8 1
OpNoLine
OpReturn
OpFunctionEnd

View File

@ -1,3 +1,5 @@
// normalize-stderr-not_spirt "OpLine %8 10 1" -> "OpNoLine"
// build-pass
// compile-flags: -C llvm-args=--disassemble-fn=ptr_write::copy_via_raw_ptr

View File

@ -2,10 +2,10 @@
%4 = OpFunctionParameter %5
%6 = OpFunctionParameter %5
%7 = OpLabel
OpLine %8 7 35
OpLine %8 9 35
%9 = OpLoad %10 %4
OpLine %11 1336 8
OpStore %6 %9
OpLine %8 8 1
OpNoLine
OpReturn
OpFunctionEnd

View File

@ -1,3 +1,5 @@
// normalize-stderr-not_spirt "OpLine %8 10 1" -> "OpNoLine"
// build-pass
// compile-flags: -C llvm-args=--disassemble-fn=ptr_write_method::copy_via_raw_ptr

View File

@ -2,10 +2,10 @@
%4 = OpFunctionParameter %5
%6 = OpFunctionParameter %5
%7 = OpLabel
OpLine %8 7 37
OpLine %8 9 37
%9 = OpLoad %10 %4
OpLine %11 1336 8
OpStore %6 %9
OpLine %8 8 1
OpNoLine
OpReturn
OpFunctionEnd

View File

@ -1,3 +1,6 @@
// HACK(eddyb) duplicate of unwrap_or.spirt.rs because only-/ignore- do not work with revisions.
// only-not_spirt
// unwrap_or generates some memory-bools (as u8). Test to make sure they're fused away.
// OpINotEqual, as well as %bool, should not appear in the output.

View File

@ -0,0 +1,4 @@
error: invalid character `'.'` in crate name: `unwrap_or.not_spirt`
error: aborting due to previous error

View File

@ -0,0 +1,15 @@
// HACK(eddyb) duplicate of unwrap_or.not_spirt.rs because only-/ignore- do not work with revisions.
// only-spirt
// unwrap_or generates some memory-bools (as u8). Test to make sure they're fused away.
// OpINotEqual, as well as %bool, should not appear in the output.
// build-pass
// compile-flags: -C llvm-args=--disassemble-entry=main
use spirv_std::spirv;
#[spirv(fragment)]
pub fn main(out: &mut u32) {
*out = None.unwrap_or(15);
}

View File

@ -0,0 +1,4 @@
error: invalid character `'.'` in crate name: `unwrap_or.spirt`
error: aborting due to previous error

View File

@ -1,39 +0,0 @@
%1 = OpFunction %2 None %3
%4 = OpLabel
OpLine %5 11 11
%6 = OpCompositeInsert %7 %8 %9 0
OpLine %5 11 11
%10 = OpCompositeExtract %11 %6 1
OpLine %12 803 14
%13 = OpBitcast %14 %8
OpLine %12 803 8
OpSelectionMerge %15 None
OpSwitch %13 %16 0 %17 1 %18
%16 = OpLabel
OpLine %12 803 14
OpUnreachable
%17 = OpLabel
OpLine %12 805 20
OpBranch %15
%18 = OpLabel
OpLine %12 804 23
OpBranch %15
%15 = OpLabel
%19 = OpPhi %20 %21 %17 %22 %18
%23 = OpPhi %11 %24 %17 %10 %18
OpBranch %25
%25 = OpLabel
OpLine %12 807 4
OpSelectionMerge %26 None
OpBranchConditional %19 %27 %28
%27 = OpLabel
OpLine %12 807 4
OpBranch %26
%28 = OpLabel
OpBranch %26
%26 = OpLabel
OpLine %5 11 4
OpStore %29 %23
OpLine %5 12 1
OpReturn
OpFunctionEnd