mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-05 22:23:29 +00:00
tint/transform: Fix ICE in HLSL backend
When referencing a pointer parameter with a 'let', but not using that let. Also fix a bunch of places where we used the old names for the pointer transforms. Bug: chromium:1433499 Change-Id: I8decefeacd6150bd6f7637f80e62b9cb62936235 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/127540 Kokoro: Kokoro <noreply+kokoro@google.com> Auto-Submit: Ben Clayton <bclayton@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
63aa15467e
commit
559e5a2cde
@ -132,6 +132,13 @@ struct SimplifyPointers::State {
|
|||||||
utils::Hashmap<const ast::Expression*, Symbol, 8> saved_vars;
|
utils::Hashmap<const ast::Expression*, Symbol, 8> saved_vars;
|
||||||
|
|
||||||
bool needs_transform = false;
|
bool needs_transform = false;
|
||||||
|
for (auto* ty : ctx.src->Types()) {
|
||||||
|
if (ty->Is<type::Pointer>()) {
|
||||||
|
// Program contains pointers which need removing.
|
||||||
|
needs_transform = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Find all the pointer-typed `let` declarations.
|
// Find all the pointer-typed `let` declarations.
|
||||||
// Note that these must be function-scoped, as module-scoped `let`s are not
|
// Note that these must be function-scoped, as module-scoped `let`s are not
|
||||||
|
@ -28,16 +28,6 @@ TEST_F(SimplifyPointersTest, EmptyModule) {
|
|||||||
EXPECT_FALSE(ShouldRun<SimplifyPointers>(src));
|
EXPECT_FALSE(ShouldRun<SimplifyPointers>(src));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SimplifyPointersTest, NoAddressOf) {
|
|
||||||
auto* src = R"(
|
|
||||||
fn f(p : ptr<function, i32>) {
|
|
||||||
var v : i32;
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
EXPECT_FALSE(ShouldRun<SimplifyPointers>(src));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SimplifyPointersTest, FoldPointer) {
|
TEST_F(SimplifyPointersTest, FoldPointer) {
|
||||||
auto* src = R"(
|
auto* src = R"(
|
||||||
fn f() {
|
fn f() {
|
||||||
@ -59,6 +49,36 @@ fn f() {
|
|||||||
EXPECT_EQ(expect, str(got));
|
EXPECT_EQ(expect, str(got));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SimplifyPointersTest, UnusedPointerParam) {
|
||||||
|
auto* src = R"(
|
||||||
|
fn f(p : ptr<function, i32>) {
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
auto* expect = src;
|
||||||
|
|
||||||
|
auto got = Run<Unshadow, SimplifyPointers>(src);
|
||||||
|
|
||||||
|
EXPECT_EQ(expect, str(got));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SimplifyPointersTest, ReferencedPointerParam) {
|
||||||
|
auto* src = R"(
|
||||||
|
fn f(p : ptr<function, i32>) {
|
||||||
|
let x = p;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
auto* expect = R"(
|
||||||
|
fn f(p : ptr<function, i32>) {
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
auto got = Run<Unshadow, SimplifyPointers>(src);
|
||||||
|
|
||||||
|
EXPECT_EQ(expect, str(got));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SimplifyPointersTest, AddressOfDeref) {
|
TEST_F(SimplifyPointersTest, AddressOfDeref) {
|
||||||
auto* src = R"(
|
auto* src = R"(
|
||||||
fn f() {
|
fn f() {
|
||||||
|
@ -2982,9 +2982,8 @@ bool GeneratorImpl::EmitType(utils::StringStream& out,
|
|||||||
out << "x" << mat->rows();
|
out << "x" << mat->rows();
|
||||||
}
|
}
|
||||||
} else if (TINT_UNLIKELY(type->Is<type::Pointer>())) {
|
} else if (TINT_UNLIKELY(type->Is<type::Pointer>())) {
|
||||||
TINT_ICE(Writer, diagnostics_)
|
TINT_ICE(Writer, diagnostics_) << "Attempting to emit pointer type. These should have been "
|
||||||
<< "Attempting to emit pointer type. These should have been removed "
|
"removed with the SimplifyPointers transform";
|
||||||
"with the InlinePointerLets transform";
|
|
||||||
return false;
|
return false;
|
||||||
} else if (type->Is<type::Sampler>()) {
|
} else if (type->Is<type::Sampler>()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -228,7 +228,7 @@ void main() {
|
|||||||
EXPECT_EQ(expect, got);
|
EXPECT_EQ(expect, got);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GlslSanitizerTest, InlinePtrLetsBasic) {
|
TEST_F(GlslSanitizerTest, SimplifyPointersBasic) {
|
||||||
// var v : i32;
|
// var v : i32;
|
||||||
// let p : ptr<function, i32> = &v;
|
// let p : ptr<function, i32> = &v;
|
||||||
// let x : i32 = *p;
|
// let x : i32 = *p;
|
||||||
@ -267,7 +267,7 @@ void main() {
|
|||||||
EXPECT_EQ(expect, got);
|
EXPECT_EQ(expect, got);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GlslSanitizerTest, InlinePtrLetsComplexChain) {
|
TEST_F(GlslSanitizerTest, SimplifyPointersComplexChain) {
|
||||||
// var a : array<mat4x4<f32>, 4u>;
|
// var a : array<mat4x4<f32>, 4u>;
|
||||||
// let ap : ptr<function, array<mat4x4<f32>, 4u>> = &a;
|
// let ap : ptr<function, array<mat4x4<f32>, 4u>> = &a;
|
||||||
// let mp : ptr<function, mat4x4<f32>> = &(*ap)[3i];
|
// let mp : ptr<function, mat4x4<f32>> = &(*ap)[3i];
|
||||||
|
@ -281,15 +281,14 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
|
|||||||
// TODO(crbug.com/tint/1752): This is only necessary when FXC is being used.
|
// TODO(crbug.com/tint/1752): This is only necessary when FXC is being used.
|
||||||
manager.Add<transform::DemoteToHelper>();
|
manager.Add<transform::DemoteToHelper>();
|
||||||
|
|
||||||
// ArrayLengthFromUniform must come after InlinePointerLets and Simplify, as
|
// ArrayLengthFromUniform must come after SimplifyPointers as it assumes that the form of the
|
||||||
// it assumes that the form of the array length argument is &var.array.
|
// array length argument is &var.array.
|
||||||
manager.Add<transform::ArrayLengthFromUniform>();
|
manager.Add<transform::ArrayLengthFromUniform>();
|
||||||
data.Add<transform::ArrayLengthFromUniform::Config>(std::move(array_length_from_uniform_cfg));
|
data.Add<transform::ArrayLengthFromUniform::Config>(std::move(array_length_from_uniform_cfg));
|
||||||
// DecomposeMemoryAccess must come after:
|
// DecomposeMemoryAccess must come after:
|
||||||
// * InlinePointerLets, as we cannot take the address of calls to
|
// * SimplifyPointers, as we cannot take the address of calls to
|
||||||
// DecomposeMemoryAccess::Intrinsic.
|
// DecomposeMemoryAccess::Intrinsic and we need to fold away the address-of and dereferences
|
||||||
// * Simplify, as we need to fold away the address-of and dereferences of
|
// of `*(&(intrinsic_load()))` expressions.
|
||||||
// `*(&(intrinsic_load()))` expressions.
|
|
||||||
// * RemovePhonies, as phonies can be assigned a pointer to a
|
// * RemovePhonies, as phonies can be assigned a pointer to a
|
||||||
// non-constructible buffer, or dynamic array, which DMA cannot cope with.
|
// non-constructible buffer, or dynamic array, which DMA cannot cope with.
|
||||||
manager.Add<transform::DecomposeMemoryAccess>();
|
manager.Add<transform::DecomposeMemoryAccess>();
|
||||||
@ -4070,9 +4069,8 @@ bool GeneratorImpl::EmitType(utils::StringStream& out,
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[&](const type::Pointer*) {
|
[&](const type::Pointer*) {
|
||||||
TINT_ICE(Writer, diagnostics_)
|
TINT_ICE(Writer, diagnostics_) << "Attempting to emit pointer type. These should have "
|
||||||
<< "Attempting to emit pointer type. These should have been "
|
"been removed with the SimplifyPointers transform";
|
||||||
"removed with the InlinePointerLets transform";
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
[&](const type::Sampler* sampler) {
|
[&](const type::Sampler* sampler) {
|
||||||
|
@ -237,7 +237,7 @@ void main() {
|
|||||||
EXPECT_EQ(expect, got);
|
EXPECT_EQ(expect, got);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(HlslSanitizerTest, InlinePtrLetsBasic) {
|
TEST_F(HlslSanitizerTest, SimplifyPointersBasic) {
|
||||||
// var v : i32;
|
// var v : i32;
|
||||||
// let p : ptr<function, i32> = &v;
|
// let p : ptr<function, i32> = &v;
|
||||||
// let x : i32 = *p;
|
// let x : i32 = *p;
|
||||||
@ -269,7 +269,7 @@ TEST_F(HlslSanitizerTest, InlinePtrLetsBasic) {
|
|||||||
EXPECT_EQ(expect, got);
|
EXPECT_EQ(expect, got);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(HlslSanitizerTest, InlinePtrLetsComplexChain) {
|
TEST_F(HlslSanitizerTest, SimplifyPointersComplexChain) {
|
||||||
// var a : array<mat4x4<f32>, 4u>;
|
// var a : array<mat4x4<f32>, 4u>;
|
||||||
// let ap : ptr<function, array<mat4x4<f32>, 4u>> = &a;
|
// let ap : ptr<function, array<mat4x4<f32>, 4u>> = &a;
|
||||||
// let mp : ptr<function, mat4x4<f32>> = &(*ap)[3i];
|
// let mp : ptr<function, mat4x4<f32>> = &(*ap)[3i];
|
||||||
|
3
test/tint/bug/chromium/1433499.wgsl
Normal file
3
test/tint/bug/chromium/1433499.wgsl
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fn f(p : ptr<function, f32>) {
|
||||||
|
let x = p;
|
||||||
|
}
|
7
test/tint/bug/chromium/1433499.wgsl.expected.dxc.hlsl
Normal file
7
test/tint/bug/chromium/1433499.wgsl.expected.dxc.hlsl
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[numthreads(1, 1, 1)]
|
||||||
|
void unused_entry_point() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void f(inout float p) {
|
||||||
|
}
|
7
test/tint/bug/chromium/1433499.wgsl.expected.fxc.hlsl
Normal file
7
test/tint/bug/chromium/1433499.wgsl.expected.fxc.hlsl
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[numthreads(1, 1, 1)]
|
||||||
|
void unused_entry_point() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void f(inout float p) {
|
||||||
|
}
|
9
test/tint/bug/chromium/1433499.wgsl.expected.glsl
Normal file
9
test/tint/bug/chromium/1433499.wgsl.expected.glsl
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#version 310 es
|
||||||
|
|
||||||
|
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||||
|
void unused_entry_point() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void f(inout float p) {
|
||||||
|
}
|
||||||
|
|
6
test/tint/bug/chromium/1433499.wgsl.expected.msl
Normal file
6
test/tint/bug/chromium/1433499.wgsl.expected.msl
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include <metal_stdlib>
|
||||||
|
|
||||||
|
using namespace metal;
|
||||||
|
void f(thread float* const p) {
|
||||||
|
}
|
||||||
|
|
26
test/tint/bug/chromium/1433499.wgsl.expected.spvasm
Normal file
26
test/tint/bug/chromium/1433499.wgsl.expected.spvasm
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
; SPIR-V
|
||||||
|
; Version: 1.3
|
||||||
|
; Generator: Google Tint Compiler; 0
|
||||||
|
; Bound: 11
|
||||||
|
; Schema: 0
|
||||||
|
OpCapability Shader
|
||||||
|
OpMemoryModel Logical GLSL450
|
||||||
|
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||||
|
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||||
|
OpName %unused_entry_point "unused_entry_point"
|
||||||
|
OpName %f "f"
|
||||||
|
OpName %p "p"
|
||||||
|
%void = OpTypeVoid
|
||||||
|
%1 = OpTypeFunction %void
|
||||||
|
%float = OpTypeFloat 32
|
||||||
|
%_ptr_Function_float = OpTypePointer Function %float
|
||||||
|
%5 = OpTypeFunction %void %_ptr_Function_float
|
||||||
|
%unused_entry_point = OpFunction %void None %1
|
||||||
|
%4 = OpLabel
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
%f = OpFunction %void None %5
|
||||||
|
%p = OpFunctionParameter %_ptr_Function_float
|
||||||
|
%10 = OpLabel
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
3
test/tint/bug/chromium/1433499.wgsl.expected.wgsl
Normal file
3
test/tint/bug/chromium/1433499.wgsl.expected.wgsl
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fn f(p : ptr<function, f32>) {
|
||||||
|
let x = p;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user