Implement discard semantics

Implement new transform UnwindDiscardFunctions that replaces discard
statements with setting a module-level bool, adds a check and return for
this bool after every function call that may discard, and finally
invokes a single function that executes a discard from top-level
functions.

Regenerated tests and remove HLSL ones that used to fail FXC because it
had difficulty with discard.

Bug: tint:1478
Bug: chromium:1118
Change-Id: I09d680f59e2d5d0cad907bfbbdd426aae76d4bf3
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/84221
Reviewed-by: James Price <jrprice@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
Antonio Maiorano 2022-03-28 20:51:32 +00:00 committed by Tint LUCI CQ
parent ade4e74ec4
commit 66d6668372
36 changed files with 2469 additions and 2991 deletions

View File

@ -487,6 +487,8 @@ libtint_source_set("libtint_core_all_src") {
"transform/transform.h",
"transform/unshadow.cc",
"transform/unshadow.h",
"transform/unwind_discard_functions.cc",
"transform/unwind_discard_functions.h",
"transform/utils/hoist_to_decl_before.cc",
"transform/utils/hoist_to_decl_before.h",
"transform/var_for_dynamic_index.cc",

View File

@ -365,6 +365,8 @@ set(TINT_LIB_SRCS
transform/transform.h
transform/unshadow.cc
transform/unshadow.h
transform/unwind_discard_functions.cc
transform/unwind_discard_functions.h
transform/vectorize_scalar_matrix_constructors.cc
transform/vectorize_scalar_matrix_constructors.h
transform/var_for_dynamic_index.cc
@ -1031,6 +1033,7 @@ if(TINT_BUILD_TESTS)
transform/single_entry_point_test.cc
transform/test_helper.h
transform/unshadow_test.cc
transform/unwind_discard_functions_test.cc
transform/var_for_dynamic_index_test.cc
transform/vectorize_scalar_matrix_constructors_test.cc
transform/vertex_pulling_test.cc

View File

@ -40,5 +40,9 @@ ElseStatement::ElseStatement(const ast::ElseStatement* declaration,
ElseStatement::~ElseStatement() = default;
const ast::ElseStatement* ElseStatement::Declaration() const {
return static_cast<const ast::ElseStatement*>(Base::Declaration());
}
} // namespace sem
} // namespace tint

View File

@ -73,6 +73,9 @@ class ElseStatement final : public Castable<ElseStatement, CompoundStatement> {
/// Destructor
~ElseStatement() override;
/// @returns the AST node
const ast::ElseStatement* Declaration() const;
/// @returns the else-statement condition expression
const Expression* Condition() const { return condition_; }

View File

@ -34,6 +34,7 @@
#include "src/tint/transform/simplify_pointers.h"
#include "src/tint/transform/single_entry_point.h"
#include "src/tint/transform/unshadow.h"
#include "src/tint/transform/unwind_discard_functions.h"
#include "src/tint/transform/zero_init_workgroup_memory.h"
TINT_INSTANTIATE_TYPEINFO(tint::transform::Glsl);
@ -84,6 +85,7 @@ Output Glsl::Run(const Program* in, const DataMap& inputs) const {
}
manager.Add<CanonicalizeEntryPointIO>();
manager.Add<PromoteSideEffectsToDecl>();
manager.Add<UnwindDiscardFunctions>();
manager.Add<SimplifyPointers>();
manager.Add<RemovePhonies>();

View File

@ -118,7 +118,8 @@ class TransformTestBase : public BASE {
template <typename TRANSFORM>
bool ShouldRun(Program&& program, const DataMap& data = {}) {
EXPECT_TRUE(program.IsValid()) << program.Diagnostics().str();
return TRANSFORM().ShouldRun(&program, data);
const Transform& t = TRANSFORM();
return t.ShouldRun(&program, data);
}
/// @param in the input WGSL source

View File

@ -0,0 +1,432 @@
// Copyright 2022 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/transform/unwind_discard_functions.h"
#include <memory>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>
#include "src/tint/ast/discard_statement.h"
#include "src/tint/ast/return_statement.h"
#include "src/tint/ast/traverse_expressions.h"
#include "src/tint/sem/block_statement.h"
#include "src/tint/sem/call.h"
#include "src/tint/sem/for_loop_statement.h"
#include "src/tint/sem/function.h"
#include "src/tint/sem/if_statement.h"
TINT_INSTANTIATE_TYPEINFO(tint::transform::UnwindDiscardFunctions);
namespace tint::transform {
namespace {
class State {
private:
CloneContext& ctx;
ProgramBuilder& b;
const sem::Info& sem;
Symbol module_discard_var_name; // Use ModuleDiscardVarName() to read
Symbol module_discard_func_name; // Use ModuleDiscardFuncName() to read
// For the input statement, returns the block and statement within that
// block to insert before/after.
std::pair<const sem::BlockStatement*, const ast::Statement*>
GetInsertionPoint(const ast::Statement* stmt) {
using RetType =
std::pair<const sem::BlockStatement*, const ast::Statement*>;
if (auto* sem_stmt = sem.Get(stmt)) {
auto* parent = sem_stmt->Parent();
return Switch(
parent,
[&](const sem::BlockStatement* block) -> RetType {
// Common case, just insert in the current block above the input
// statement.
return {block, stmt};
},
[&](const sem::ForLoopStatement* fl) -> RetType {
// `stmt` is either the for loop initializer or the continuing
// statement of a for-loop.
if (fl->Declaration()->initializer == stmt) {
// For loop init, insert above the for loop itself.
return {fl->Block(), fl->Declaration()};
}
TINT_ICE(Transform, b.Diagnostics())
<< "cannot insert before or after continuing statement of a "
"for-loop";
return {};
},
[&](Default) -> RetType {
TINT_ICE(Transform, b.Diagnostics())
<< "expected parent of statement to be either a block or for "
"loop";
return {};
});
}
return {};
}
// If `block`'s parent is of type TO, returns pointer to it.
template <typename TO>
const TO* ParentAs(const ast::BlockStatement* block) {
if (auto* sem_block = sem.Get(block)) {
return As<TO>(sem_block->Parent());
}
return nullptr;
}
// Returns true if `sem_expr` contains a call expression that may
// (transitively) execute a discard statement.
bool MayDiscard(const sem::Expression* sem_expr) {
return sem_expr && sem_expr->Behaviors().Contains(sem::Behavior::kDiscard);
}
// Lazily creates and returns the name of the module bool variable for whether
// to discard: "tint_discard".
Symbol ModuleDiscardVarName() {
if (!module_discard_var_name.IsValid()) {
module_discard_var_name = b.Symbols().New("tint_discard");
ctx.dst->Global(module_discard_var_name, b.ty.bool_(), b.Expr(false),
ast::StorageClass::kPrivate);
}
return module_discard_var_name;
}
// Lazily creates and returns the name of the function that contains a single
// discard statement: "tint_discard_func".
// We do this to avoid having multiple discard statements in a single program,
// which causes problems in certain backends (see crbug.com/1118).
Symbol ModuleDiscardFuncName() {
if (!module_discard_func_name.IsValid()) {
module_discard_func_name = b.Symbols().New("tint_discard_func");
b.Func(module_discard_func_name, {}, b.ty.void_(), {b.Discard()});
}
return module_discard_func_name;
}
// Creates "return <default return value>;" based on the return type of
// `stmt`'s owning function.
const ast::ReturnStatement* Return(const ast::Statement* stmt) {
const ast::Expression* ret_val = nullptr;
auto* ret_type = sem.Get(stmt)->Function()->Declaration()->return_type;
if (!ret_type->Is<ast::Void>()) {
ret_val = b.Construct(ctx.Clone(ret_type));
}
return b.Return(ret_val);
}
// Returns true if the function `stmt` is in is an entry point
bool IsInEntryPointFunc(const ast::Statement* stmt) {
return sem.Get(stmt)->Function()->Declaration()->IsEntryPoint();
}
// Creates "tint_discard_func();"
const ast::CallStatement* CallDiscardFunc() {
auto func_name = ModuleDiscardFuncName();
return b.CallStmt(b.Call(func_name));
}
// Creates and returns a new if-statement of the form:
//
// if (tint_discard) {
// return <default value>;
// }
//
// or if `stmt` is in a entry point function:
//
// if (tint_discard) {
// tint_discard_func();
// return <default value>;
// }
//
const ast::IfStatement* IfDiscardReturn(const ast::Statement* stmt) {
ast::StatementList stmts;
// For entry point functions, also emit the discard statement
if (IsInEntryPointFunc(stmt)) {
stmts.emplace_back(CallDiscardFunc());
}
stmts.emplace_back(Return(stmt));
auto var_name = ModuleDiscardVarName();
return b.If(var_name, b.Block(stmts));
}
// Hoists `sem_expr` to a let followed by an `IfDiscardReturn` before `stmt`.
// For example, if `stmt` is:
//
// return f();
//
// This function will transform this to:
//
// let t1 = f();
// if (tint_discard) {
// return;
// }
// return t1;
//
const ast::Statement* HoistAndInsertBefore(const ast::Statement* stmt,
const sem::Expression* sem_expr) {
auto* expr = sem_expr->Declaration();
auto ip = GetInsertionPoint(stmt);
auto var_name = b.Sym();
auto* decl = b.Decl(b.Var(var_name, nullptr, ctx.Clone(expr)));
ctx.InsertBefore(ip.first->Declaration()->statements, ip.second, decl);
ctx.InsertBefore(ip.first->Declaration()->statements, ip.second,
IfDiscardReturn(stmt));
auto* var_expr = b.Expr(var_name);
// Special handling for CallStatement as we can only replace its expression
// with a CallExpression.
if (stmt->Is<ast::CallStatement>()) {
// We could replace the call statement with no statement, but we can't do
// that with transforms (yet), so just return a phony assignment.
return b.Assign(b.Phony(), var_expr);
}
ctx.Replace(expr, var_expr);
return ctx.CloneWithoutTransform(stmt);
}
// Returns true if `stmt` is a for-loop initializer statement.
bool IsForLoopInitStatement(const ast::Statement* stmt) {
if (auto* sem_stmt = sem.Get(stmt)) {
if (auto* sem_fl = As<sem::ForLoopStatement>(sem_stmt->Parent())) {
return sem_fl->Declaration()->initializer == stmt;
}
}
return false;
}
// Inserts an `IfDiscardReturn` after `stmt` if possible (i.e. `stmt` is not
// in a for-loop init), otherwise falls back to HoistAndInsertBefore, hoisting
// `sem_expr` to a let followed by an `IfDiscardReturn` before `stmt`.
//
// For example, if `stmt` is:
//
// let r = f();
//
// This function will transform this to:
//
// let r = f();
// if (tint_discard) {
// return;
// }
const ast::Statement* TryInsertAfter(const ast::Statement* stmt,
const sem::Expression* sem_expr) {
// If `stmt` is the init of a for-loop, hoist and insert before instead.
if (IsForLoopInitStatement(stmt)) {
return HoistAndInsertBefore(stmt, sem_expr);
}
auto ip = GetInsertionPoint(stmt);
ctx.InsertAfter(ip.first->Declaration()->statements, ip.second,
IfDiscardReturn(stmt));
return nullptr; // Don't replace current statement
}
// Replaces the input discard statement with either setting the module level
// discard bool ("tint_discard = true"), or calling the discard function
// ("tint_discard_func()"), followed by a default return statement.
//
// Replaces "discard;" with:
//
// tint_discard = true;
// return;
//
// Or if `stmt` is a entry point function, replaces with:
//
// tint_discard_func();
// return;
//
const ast::Statement* ReplaceDiscardStatement(
const ast::DiscardStatement* stmt) {
const ast::Statement* to_insert = nullptr;
if (IsInEntryPointFunc(stmt)) {
to_insert = CallDiscardFunc();
} else {
auto var_name = ModuleDiscardVarName();
to_insert = b.Assign(var_name, true);
}
auto ip = GetInsertionPoint(stmt);
ctx.InsertBefore(ip.first->Declaration()->statements, ip.second, to_insert);
return Return(stmt);
}
// Handle statement
const ast::Statement* Statement(const ast::Statement* stmt) {
return Switch(
stmt,
[&](const ast::DiscardStatement* s) -> const ast::Statement* {
return ReplaceDiscardStatement(s);
},
[&](const ast::AssignmentStatement* s) -> const ast::Statement* {
auto* sem_lhs = sem.Get(s->lhs);
auto* sem_rhs = sem.Get(s->rhs);
if (MayDiscard(sem_lhs)) {
if (MayDiscard(sem_rhs)) {
TINT_ICE(Transform, b.Diagnostics())
<< "Unexpected: both sides of assignment statement may "
"discard. Make sure transform::PromoteSideEffectsToDecl "
"was run first.";
}
return TryInsertAfter(s, sem_lhs);
} else if (MayDiscard(sem_rhs)) {
return TryInsertAfter(s, sem_rhs);
}
return nullptr;
},
[&](const ast::CallStatement* s) -> const ast::Statement* {
auto* sem_expr = sem.Get(s->expr);
if (!MayDiscard(sem_expr)) {
return nullptr;
}
return TryInsertAfter(s, sem_expr);
},
[&](const ast::ElseStatement* s) -> const ast::Statement* {
if (MayDiscard(sem.Get(s->condition))) {
TINT_ICE(Transform, b.Diagnostics())
<< "Unexpected ElseIf condition that may discard. Make sure "
"transform::PromoteSideEffectsToDecl was run first.";
}
return nullptr;
},
[&](const ast::ForLoopStatement* s) -> const ast::Statement* {
if (MayDiscard(sem.Get(s->condition))) {
TINT_ICE(Transform, b.Diagnostics())
<< "Unexpected ForLoopStatement condition that may discard. "
"Make sure transform::PromoteSideEffectsToDecl was run "
"first.";
}
return nullptr;
},
[&](const ast::IfStatement* s) -> const ast::Statement* {
auto* sem_expr = sem.Get(s->condition);
if (!MayDiscard(sem_expr)) {
return nullptr;
}
return HoistAndInsertBefore(s, sem_expr);
},
[&](const ast::ReturnStatement* s) -> const ast::Statement* {
auto* sem_expr = sem.Get(s->value);
if (!MayDiscard(sem_expr)) {
return nullptr;
}
return HoistAndInsertBefore(s, sem_expr);
},
[&](const ast::SwitchStatement* s) -> const ast::Statement* {
auto* sem_expr = sem.Get(s->condition);
if (!MayDiscard(sem_expr)) {
return nullptr;
}
return HoistAndInsertBefore(s, sem_expr);
},
[&](const ast::VariableDeclStatement* s) -> const ast::Statement* {
auto* var = s->variable;
if (!var->constructor) {
return nullptr;
}
auto* sem_expr = sem.Get(var->constructor);
if (!MayDiscard(sem_expr)) {
return nullptr;
}
return TryInsertAfter(s, sem_expr);
});
}
public:
/// Constructor
/// @param ctx_in the context
explicit State(CloneContext& ctx_in)
: ctx(ctx_in), b(*ctx_in.dst), sem(ctx_in.src->Sem()) {}
/// Runs the transform
void Run() {
ctx.ReplaceAll(
[&](const ast::BlockStatement* block) -> const ast::Statement* {
// If this block is for an else-if statement, process the else-if now
// before processing its block statements.
// NOTE: we can't replace else statements at this point - this would
// need to be done when replacing the parent if-statement. However, in
// this transform, we don't ever expect to need to do this as else-ifs
// are converted to else { if } by PromoteSideEffectsToDecl, so this
// is only for validation.
if (auto* sem_else = ParentAs<sem::ElseStatement>(block)) {
if (auto* new_stmt = Statement(sem_else->Declaration())) {
TINT_ASSERT(Transform, new_stmt == nullptr);
return nullptr;
}
}
// Iterate block statements and replace them as needed.
for (auto* stmt : block->statements) {
if (auto* new_stmt = Statement(stmt)) {
ctx.Replace(stmt, new_stmt);
}
// Handle for loops, as they are the only other AST node that
// contains statements outside of BlockStatements.
if (auto* fl = stmt->As<ast::ForLoopStatement>()) {
if (auto* new_stmt = Statement(fl->initializer)) {
ctx.Replace(fl->initializer, new_stmt);
}
if (auto* new_stmt = Statement(fl->continuing)) {
// NOTE: Should never reach here as we cannot discard in a
// continuing block.
ctx.Replace(fl->continuing, new_stmt);
}
}
}
return nullptr;
});
ctx.Clone();
}
};
} // namespace
UnwindDiscardFunctions::UnwindDiscardFunctions() = default;
UnwindDiscardFunctions::~UnwindDiscardFunctions() = default;
void UnwindDiscardFunctions::Run(CloneContext& ctx,
const DataMap&,
DataMap&) const {
State state(ctx);
state.Run();
}
bool UnwindDiscardFunctions::ShouldRun(const Program* program,
const DataMap& /*data*/) const {
auto& sem = program->Sem();
for (auto* f : program->AST().Functions()) {
if (sem.Get(f)->Behaviors().Contains(sem::Behavior::kDiscard)) {
return true;
}
}
return false;
}
} // namespace tint::transform

View File

@ -0,0 +1,68 @@
// Copyright 2022 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_TINT_TRANSFORM_UNWIND_DISCARD_FUNCTIONS_H_
#define SRC_TINT_TRANSFORM_UNWIND_DISCARD_FUNCTIONS_H_
#include "src/tint/transform/transform.h"
namespace tint::transform {
/// This transform is responsible for implementing discard semantics as per the
/// WGSL specification: https://gpuweb.github.io/gpuweb/wgsl/#discard-statement
///
/// Not all backend languages implement discard this way (e.g. HLSL), so this
/// transform does the following:
///
/// * Replaces discard statements with setting a module-level boolean
/// "tint_discard" to true and returning immediately.
/// * Wherever calls are made to discarding functions (directly or
/// transitively), it inserts a check afterwards for if "tint_discard" is true,
/// to return immediately.
/// * Finally, entry point functions that call discarding functions
/// emit a call to "tint_discard_func()" that contains the sole discard
/// statement.
///
/// @note Depends on the following transforms to have been run first:
/// * PromoteSideEffectsToDecl
class UnwindDiscardFunctions
: public Castable<UnwindDiscardFunctions, Transform> {
public:
/// Constructor
UnwindDiscardFunctions();
/// Destructor
~UnwindDiscardFunctions() override;
protected:
/// Runs the transform using the CloneContext built for transforming a
/// program. Run() is responsible for calling Clone() on the CloneContext.
/// @param ctx the CloneContext primed with the input program and
/// ProgramBuilder
/// @param inputs optional extra transform-specific input data
/// @param outputs optional extra transform-specific output data
void Run(CloneContext& ctx,
const DataMap& inputs,
DataMap& outputs) const override;
/// @param program the program to inspect
/// @param data optional extra transform-specific input data
/// @returns true if this transform should be run for the given program
bool ShouldRun(const Program* program,
const DataMap& data = {}) const override;
};
} // namespace tint::transform
#endif // SRC_TINT_TRANSFORM_UNWIND_DISCARD_FUNCTIONS_H_

File diff suppressed because it is too large Load Diff

View File

@ -62,6 +62,7 @@
#include "src/tint/transform/remove_phonies.h"
#include "src/tint/transform/simplify_pointers.h"
#include "src/tint/transform/unshadow.h"
#include "src/tint/transform/unwind_discard_functions.h"
#include "src/tint/transform/zero_init_workgroup_memory.h"
#include "src/tint/utils/defer.h"
#include "src/tint/utils/map.h"
@ -187,6 +188,7 @@ SanitizedResult Sanitize(
// only accessed directly via member accessors.
manager.Add<transform::NumWorkgroupsFromUniform>();
manager.Add<transform::PromoteSideEffectsToDecl>();
manager.Add<transform::UnwindDiscardFunctions>();
manager.Add<transform::SimplifyPointers>();
manager.Add<transform::RemovePhonies>();
// ArrayLengthFromUniform must come after InlinePointerLets and Simplify, as

View File

@ -68,6 +68,7 @@
#include "src/tint/transform/remove_phonies.h"
#include "src/tint/transform/simplify_pointers.h"
#include "src/tint/transform/unshadow.h"
#include "src/tint/transform/unwind_discard_functions.h"
#include "src/tint/transform/vectorize_scalar_matrix_constructors.h"
#include "src/tint/transform/wrap_arrays_in_structs.h"
#include "src/tint/transform/zero_init_workgroup_memory.h"
@ -174,6 +175,7 @@ SanitizedResult Sanitize(
}
manager.Add<transform::CanonicalizeEntryPointIO>();
manager.Add<transform::PromoteSideEffectsToDecl>();
manager.Add<transform::UnwindDiscardFunctions>();
manager.Add<transform::PromoteInitializersToConstVar>();
manager.Add<transform::VectorizeScalarMatrixConstructors>();

View File

@ -52,6 +52,7 @@
#include "src/tint/transform/remove_unreachable_statements.h"
#include "src/tint/transform/simplify_pointers.h"
#include "src/tint/transform/unshadow.h"
#include "src/tint/transform/unwind_discard_functions.h"
#include "src/tint/transform/var_for_dynamic_index.h"
#include "src/tint/transform/vectorize_scalar_matrix_constructors.h"
#include "src/tint/transform/zero_init_workgroup_memory.h"
@ -278,6 +279,7 @@ SanitizedResult Sanitize(const Program* in,
}
manager.Add<transform::RemoveUnreachableStatements>();
manager.Add<transform::PromoteSideEffectsToDecl>();
manager.Add<transform::UnwindDiscardFunctions>();
manager.Add<transform::SimplifyPointers>(); // Required for arrayLength()
manager.Add<transform::FoldConstants>();
manager.Add<transform::VectorizeScalarMatrixConstructors>();

View File

@ -338,6 +338,7 @@ tint_unittests_source_set("tint_unittests_transform_src") {
"../../src/tint/transform/test_helper.h",
"../../src/tint/transform/transform_test.cc",
"../../src/tint/transform/unshadow_test.cc",
"../../src/tint/transform/unwind_discard_functions_test.cc",
"../../src/tint/transform/utils/hoist_to_decl_before_test.cc",
"../../src/tint/transform/var_for_dynamic_index_test.cc",
"../../src/tint/transform/vectorize_scalar_matrix_constructors_test.cc",

View File

@ -52,19 +52,29 @@ struct VertexOutputs {
vec4 position;
};
bool tint_discard = false;
uniform highp sampler2D myTexture_mySampler;
vec4 fs_main(vec2 texcoord) {
vec2 clampedTexcoord = clamp(texcoord, vec2(0.0f, 0.0f), vec2(1.0f, 1.0f));
if (!(all(equal(clampedTexcoord, texcoord)))) {
discard;
tint_discard = true;
return vec4(0.0f, 0.0f, 0.0f, 0.0f);
}
vec4 srcColor = texture(myTexture_mySampler, texcoord);
return srcColor;
}
void tint_discard_func() {
discard;
}
void main() {
vec4 inner_result = fs_main(texcoord_1);
if (tint_discard) {
tint_discard_func();
return;
}
value = inner_result;
return;
}

View File

@ -45,21 +45,29 @@ struct tint_symbol_5 {
float4 value : SV_Target0;
};
static bool tint_discard = false;
float4 fs_main_inner(float2 texcoord) {
if (true) {
float2 clampedTexcoord = clamp(texcoord, float2(0.0f, 0.0f), float2(1.0f, 1.0f));
if (!(all((clampedTexcoord == texcoord)))) {
discard;
}
float4 srcColor = myTexture.Sample(mySampler, texcoord);
return srcColor;
float2 clampedTexcoord = clamp(texcoord, float2(0.0f, 0.0f), float2(1.0f, 1.0f));
if (!(all((clampedTexcoord == texcoord)))) {
tint_discard = true;
return float4(0.0f, 0.0f, 0.0f, 0.0f);
}
float4 unused;
return unused;
float4 srcColor = myTexture.Sample(mySampler, texcoord);
return srcColor;
}
void tint_discard_func() {
discard;
}
tint_symbol_5 fs_main(tint_symbol_4 tint_symbol_3) {
const float4 inner_result_1 = fs_main_inner(tint_symbol_3.texcoord);
if (tint_discard) {
tint_discard_func();
const tint_symbol_5 tint_symbol_8 = (tint_symbol_5)0;
return tint_symbol_8;
}
tint_symbol_5 wrapper_result_1 = (tint_symbol_5)0;
wrapper_result_1.value = inner_result_1;
return wrapper_result_1;

View File

@ -20,21 +20,21 @@ struct tint_array_wrapper {
float2 arr[3];
};
VertexOutputs vs_main_inner(uint VertexIndex, const constant Uniforms* const tint_symbol_4) {
VertexOutputs vs_main_inner(uint VertexIndex, const constant Uniforms* const tint_symbol_5) {
tint_array_wrapper texcoord = {.arr={float2(-0.5f, 0.0f), float2(1.5f, 0.0f), float2(0.5f, 2.0f)}};
VertexOutputs output = {};
output.position = float4(((texcoord.arr[VertexIndex] * 2.0f) - float2(1.0f, 1.0f)), 0.0f, 1.0f);
bool flipY = ((*(tint_symbol_4)).u_scale[1] < 0.0f);
bool flipY = ((*(tint_symbol_5)).u_scale[1] < 0.0f);
if (flipY) {
output.texcoords = ((((texcoord.arr[VertexIndex] * (*(tint_symbol_4)).u_scale) + (*(tint_symbol_4)).u_offset) * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f));
output.texcoords = ((((texcoord.arr[VertexIndex] * (*(tint_symbol_5)).u_scale) + (*(tint_symbol_5)).u_offset) * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f));
} else {
output.texcoords = ((((texcoord.arr[VertexIndex] * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)) * (*(tint_symbol_4)).u_scale) + (*(tint_symbol_4)).u_offset);
output.texcoords = ((((texcoord.arr[VertexIndex] * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)) * (*(tint_symbol_5)).u_scale) + (*(tint_symbol_5)).u_offset);
}
return output;
}
vertex tint_symbol vs_main(const constant Uniforms* tint_symbol_5 [[buffer(0)]], uint VertexIndex [[vertex_id]]) {
VertexOutputs const inner_result = vs_main_inner(VertexIndex, tint_symbol_5);
vertex tint_symbol vs_main(const constant Uniforms* tint_symbol_6 [[buffer(0)]], uint VertexIndex [[vertex_id]]) {
VertexOutputs const inner_result = vs_main_inner(VertexIndex, tint_symbol_6);
tint_symbol wrapper_result = {};
wrapper_result.texcoords = inner_result.texcoords;
wrapper_result.position = inner_result.position;
@ -49,17 +49,28 @@ struct tint_symbol_3 {
float4 value [[color(0)]];
};
float4 fs_main_inner(float2 texcoord, texture2d<float, access::sample> tint_symbol_6, sampler tint_symbol_7) {
float4 fs_main_inner(float2 texcoord, thread bool* const tint_symbol_7, texture2d<float, access::sample> tint_symbol_8, sampler tint_symbol_9) {
float2 clampedTexcoord = clamp(texcoord, float2(0.0f, 0.0f), float2(1.0f, 1.0f));
if (!(all((clampedTexcoord == texcoord)))) {
discard_fragment();
*(tint_symbol_7) = true;
return float4();
}
float4 srcColor = tint_symbol_6.sample(tint_symbol_7, texcoord);
float4 srcColor = tint_symbol_8.sample(tint_symbol_9, texcoord);
return srcColor;
}
fragment tint_symbol_3 fs_main(texture2d<float, access::sample> tint_symbol_8 [[texture(0)]], sampler tint_symbol_9 [[sampler(0)]], tint_symbol_2 tint_symbol_1 [[stage_in]]) {
float4 const inner_result_1 = fs_main_inner(tint_symbol_1.texcoord, tint_symbol_8, tint_symbol_9);
void tint_discard_func() {
discard_fragment();
}
fragment tint_symbol_3 fs_main(texture2d<float, access::sample> tint_symbol_11 [[texture(0)]], sampler tint_symbol_12 [[sampler(0)]], tint_symbol_2 tint_symbol_1 [[stage_in]]) {
thread bool tint_symbol_10 = false;
float4 const inner_result_1 = fs_main_inner(tint_symbol_1.texcoord, &(tint_symbol_10), tint_symbol_11, tint_symbol_12);
if (tint_symbol_10) {
tint_discard_func();
tint_symbol_3 const tint_symbol_4 = {};
return tint_symbol_4;
}
tint_symbol_3 wrapper_result_1 = {};
wrapper_result_1.value = inner_result_1;
return wrapper_result_1;

View File

@ -1,10 +1,10 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 137
; Bound: 140
; Schema: 0
OpCapability Shader
%116 = OpExtInstImport "GLSL.std.450"
%118 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %vs_main "vs_main" %VertexIndex_1 %texcoords_1 %position_1 %vertex_point_size
OpEntryPoint Fragment %fs_main "fs_main" %texcoord_1 %value
@ -30,6 +30,7 @@
OpName %output "output"
OpName %flipY "flipY"
OpName %vs_main "vs_main"
OpName %tint_discard_func "tint_discard_func"
OpName %fs_main_inner "fs_main_inner"
OpName %texcoord_0 "texcoord"
OpName %clampedTexcoord "clampedTexcoord"
@ -114,10 +115,10 @@
%89 = OpConstantComposite %v2float %float_0 %float_1
%void = OpTypeVoid
%103 = OpTypeFunction %void
%111 = OpTypeFunction %v4float %v2float
%117 = OpConstantComposite %v2float %float_0 %float_0
%113 = OpTypeFunction %v4float %v2float
%119 = OpConstantComposite %v2float %float_0 %float_0
%v2bool = OpTypeVector %bool 2
%129 = OpTypeSampledImage %27
%132 = OpTypeSampledImage %27
%vs_main_inner = OpFunction %VertexOutputs None %28
%VertexIndex = OpFunctionParameter %uint
%32 = OpLabel
@ -184,34 +185,39 @@
OpStore %vertex_point_size %float_1
OpReturn
OpFunctionEnd
%fs_main_inner = OpFunction %v4float None %111
%tint_discard_func = OpFunction %void None %103
%112 = OpLabel
OpKill
OpFunctionEnd
%fs_main_inner = OpFunction %v4float None %113
%texcoord_0 = OpFunctionParameter %v2float
%114 = OpLabel
%116 = OpLabel
%clampedTexcoord = OpVariable %_ptr_Function_v2float Function %8
%srcColor = OpVariable %_ptr_Function_v4float Function %12
%115 = OpExtInst %v2float %116 NClamp %texcoord_0 %117 %58
OpStore %clampedTexcoord %115
%121 = OpLoad %v2float %clampedTexcoord
%122 = OpFOrdEqual %v2bool %121 %texcoord_0
%120 = OpAll %bool %122
%119 = OpLogicalNot %bool %120
OpSelectionMerge %124 None
OpBranchConditional %119 %125 %124
%125 = OpLabel
OpKill
%124 = OpLabel
%127 = OpLoad %24 %mySampler
%128 = OpLoad %27 %myTexture
%130 = OpSampledImage %129 %128 %127
%126 = OpImageSampleImplicitLod %v4float %130 %texcoord_0
OpStore %srcColor %126
%132 = OpLoad %v4float %srcColor
OpReturnValue %132
%117 = OpExtInst %v2float %118 NClamp %texcoord_0 %119 %58
OpStore %clampedTexcoord %117
%123 = OpLoad %v2float %clampedTexcoord
%124 = OpFOrdEqual %v2bool %123 %texcoord_0
%122 = OpAll %bool %124
%121 = OpLogicalNot %bool %122
OpSelectionMerge %126 None
OpBranchConditional %121 %127 %126
%127 = OpLabel
%128 = OpFunctionCall %void %tint_discard_func
OpReturnValue %12
%126 = OpLabel
%130 = OpLoad %24 %mySampler
%131 = OpLoad %27 %myTexture
%133 = OpSampledImage %132 %131 %130
%129 = OpImageSampleImplicitLod %v4float %133 %texcoord_0
OpStore %srcColor %129
%135 = OpLoad %v4float %srcColor
OpReturnValue %135
OpFunctionEnd
%fs_main = OpFunction %void None %103
%134 = OpLabel
%136 = OpLoad %v2float %texcoord_1
%135 = OpFunctionCall %v4float %fs_main_inner %136
OpStore %value %135
%137 = OpLabel
%139 = OpLoad %v2float %texcoord_1
%138 = OpFunctionCall %v4float %fs_main_inner %139
OpStore %value %138
OpReturn
OpFunctionEnd

View File

@ -3,9 +3,11 @@ precision mediump float;
layout(location = 1) flat in ivec3 x_1;
layout(location = 2) out int value;
bool tint_discard = false;
int f(int x) {
if ((x == 10)) {
discard;
tint_discard = true;
return 0;
}
return x;
}
@ -14,6 +16,9 @@ int tint_symbol(ivec3 x) {
int y = x.x;
while (true) {
int r = f(y);
if (tint_discard) {
return 0;
}
if ((r == 0)) {
break;
}
@ -21,8 +26,16 @@ int tint_symbol(ivec3 x) {
return y;
}
void tint_discard_func() {
discard;
}
void main() {
int inner_result = tint_symbol(x_1);
if (tint_discard) {
tint_discard_func();
return;
}
value = inner_result;
return;
}

View File

@ -1,12 +1,11 @@
static bool tint_discard = false;
int f(int x) {
if (true) {
if ((x == 10)) {
discard;
}
return x;
if ((x == 10)) {
tint_discard = true;
return 0;
}
int unused;
return unused;
return x;
}
struct tint_symbol_1 {
@ -20,6 +19,9 @@ int main_inner(int3 x) {
int y = x.x;
[loop] while (true) {
const int r = f(y);
if (tint_discard) {
return 0;
}
if ((r == 0)) {
break;
}
@ -27,8 +29,17 @@ int main_inner(int3 x) {
return y;
}
void tint_discard_func() {
discard;
}
tint_symbol_2 main(tint_symbol_1 tint_symbol) {
const int inner_result = main_inner(tint_symbol.x);
if (tint_discard) {
tint_discard_func();
const tint_symbol_2 tint_symbol_3 = (tint_symbol_2)0;
return tint_symbol_3;
}
tint_symbol_2 wrapper_result = (tint_symbol_2)0;
wrapper_result.value = inner_result;
return wrapper_result;

View File

@ -1,9 +1,10 @@
#include <metal_stdlib>
using namespace metal;
int f(int x) {
int f(int x, thread bool* const tint_symbol_5) {
if ((x == 10)) {
discard_fragment();
*(tint_symbol_5) = true;
return int();
}
return x;
}
@ -16,10 +17,13 @@ struct tint_symbol_3 {
int value [[color(2)]];
};
int tint_symbol_inner(int3 x) {
int tint_symbol_inner(int3 x, thread bool* const tint_symbol_6) {
int y = x[0];
while (true) {
int const r = f(y);
int const r = f(y, tint_symbol_6);
if (*(tint_symbol_6)) {
return int();
}
if ((r == 0)) {
break;
}
@ -27,8 +31,18 @@ int tint_symbol_inner(int3 x) {
return y;
}
void tint_discard_func() {
discard_fragment();
}
fragment tint_symbol_3 tint_symbol(tint_symbol_2 tint_symbol_1 [[stage_in]]) {
int const inner_result = tint_symbol_inner(tint_symbol_1.x);
thread bool tint_symbol_7 = false;
int const inner_result = tint_symbol_inner(tint_symbol_1.x, &(tint_symbol_7));
if (tint_symbol_7) {
tint_discard_func();
tint_symbol_3 const tint_symbol_4 = {};
return tint_symbol_4;
}
tint_symbol_3 wrapper_result = {};
wrapper_result.value = inner_result;
return wrapper_result;

View File

@ -1,7 +1,7 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 41
; Bound: 51
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
@ -9,8 +9,10 @@
OpExecutionMode %main OriginUpperLeft
OpName %x_1 "x_1"
OpName %value "value"
OpName %tint_discard "tint_discard"
OpName %f "f"
OpName %x "x"
OpName %tint_discard_func "tint_discard_func"
OpName %main_inner "main_inner"
OpName %x_0 "x"
OpName %y "y"
@ -25,55 +27,71 @@
%_ptr_Output_int = OpTypePointer Output %int
%7 = OpConstantNull %int
%value = OpVariable %_ptr_Output_int Output %7
%8 = OpTypeFunction %int %int
%int_10 = OpConstant %int 10
%bool = OpTypeBool
%17 = OpTypeFunction %int %v3int
%false = OpConstantFalse %bool
%_ptr_Private_bool = OpTypePointer Private %bool
%tint_discard = OpVariable %_ptr_Private_bool Private %false
%12 = OpTypeFunction %int %int
%int_10 = OpConstant %int 10
%true = OpConstantTrue %bool
%void = OpTypeVoid
%21 = OpTypeFunction %void
%25 = OpTypeFunction %int %v3int
%_ptr_Function_int = OpTypePointer Function %int
%int_0 = OpConstant %int 0
%void = OpTypeVoid
%35 = OpTypeFunction %void
%f = OpFunction %int None %8
%f = OpFunction %int None %12
%x = OpFunctionParameter %int
%11 = OpLabel
%13 = OpIEqual %bool %x %int_10
OpSelectionMerge %15 None
OpBranchConditional %13 %16 %15
%16 = OpLabel
OpKill
%15 = OpLabel
%17 = OpIEqual %bool %x %int_10
OpSelectionMerge %18 None
OpBranchConditional %17 %19 %18
%19 = OpLabel
OpStore %tint_discard %true
OpReturnValue %7
%18 = OpLabel
OpReturnValue %x
OpFunctionEnd
%main_inner = OpFunction %int None %17
%x_0 = OpFunctionParameter %v3int
%20 = OpLabel
%y = OpVariable %_ptr_Function_int Function %7
%21 = OpCompositeExtract %int %x_0 0
OpStore %y %21
OpBranch %24
%tint_discard_func = OpFunction %void None %21
%24 = OpLabel
OpLoopMerge %25 %26 None
OpBranch %27
%27 = OpLabel
%29 = OpLoad %int %y
%28 = OpFunctionCall %int %f %29
%31 = OpIEqual %bool %28 %int_0
OpSelectionMerge %32 None
OpBranchConditional %31 %33 %32
%33 = OpLabel
OpBranch %25
%32 = OpLabel
OpBranch %26
%26 = OpLabel
OpBranch %24
%25 = OpLabel
%34 = OpLoad %int %y
OpReturnValue %34
OpKill
OpFunctionEnd
%main = OpFunction %void None %35
%38 = OpLabel
%40 = OpLoad %v3int %x_1
%39 = OpFunctionCall %int %main_inner %40
OpStore %value %39
%main_inner = OpFunction %int None %25
%x_0 = OpFunctionParameter %v3int
%28 = OpLabel
%y = OpVariable %_ptr_Function_int Function %7
%29 = OpCompositeExtract %int %x_0 0
OpStore %y %29
OpBranch %32
%32 = OpLabel
OpLoopMerge %33 %34 None
OpBranch %35
%35 = OpLabel
%37 = OpLoad %int %y
%36 = OpFunctionCall %int %f %37
%38 = OpLoad %bool %tint_discard
OpSelectionMerge %39 None
OpBranchConditional %38 %40 %39
%40 = OpLabel
%41 = OpFunctionCall %void %tint_discard_func
OpReturnValue %7
%39 = OpLabel
%43 = OpIEqual %bool %36 %int_0
OpSelectionMerge %44 None
OpBranchConditional %43 %45 %44
%45 = OpLabel
OpBranch %33
%44 = OpLabel
OpBranch %34
%34 = OpLabel
OpBranch %32
%33 = OpLabel
%46 = OpLoad %int %y
OpReturnValue %46
OpFunctionEnd
%main = OpFunction %void None %21
%48 = OpLabel
%50 = OpLoad %v3int %x_1
%49 = OpFunctionCall %int %main_inner %50
OpStore %value %49
OpReturn
OpFunctionEnd

View File

@ -39,6 +39,7 @@ layout(binding = 2) uniform Mesh_1 {
} x_137;
vec4 glFragColor = vec4(0.0f, 0.0f, 0.0f, 0.0f);
bool tint_discard = false;
void main_1() {
vec3 viewDirectionW = vec3(0.0f, 0.0f, 0.0f);
vec4 baseColor = vec4(0.0f, 0.0f, 0.0f, 0.0f);
@ -57,10 +58,12 @@ void main_1() {
vec3 finalSpecular = vec3(0.0f, 0.0f, 0.0f);
vec4 color = vec4(0.0f, 0.0f, 0.0f, 0.0f);
if ((fClipDistance3 > 0.0f)) {
discard;
tint_discard = true;
return;
}
if ((fClipDistance4 > 0.0f)) {
discard;
tint_discard = true;
return;
}
vec4 x_34 = x_29.vEyePosition;
vec3 x_38 = vec3(0.0f, 0.0f, 0.0f);
@ -115,12 +118,24 @@ main_out tint_symbol(float fClipDistance3_param, float fClipDistance4_param) {
fClipDistance3 = fClipDistance3_param;
fClipDistance4 = fClipDistance4_param;
main_1();
main_out tint_symbol_1 = main_out(glFragColor);
return tint_symbol_1;
if (tint_discard) {
main_out tint_symbol_1 = main_out(vec4(0.0f, 0.0f, 0.0f, 0.0f));
return tint_symbol_1;
}
main_out tint_symbol_2 = main_out(glFragColor);
return tint_symbol_2;
}
void tint_discard_func() {
discard;
}
void main() {
main_out inner_result = tint_symbol(fClipDistance3_param_1, fClipDistance4_param_1);
if (tint_discard) {
tint_discard_func();
return;
}
glFragColor_1_1 = inner_result.glFragColor_1;
return;
}

View File

@ -1,5 +1,3 @@
SKIP: FAILED
static float fClipDistance3 = 0.0f;
static float fClipDistance4 = 0.0f;
cbuffer cbuffer_x_29 : register(b0, space0) {
@ -12,6 +10,7 @@ cbuffer cbuffer_x_137 : register(b2, space0) {
uint4 x_137[1];
};
static float4 glFragColor = float4(0.0f, 0.0f, 0.0f, 0.0f);
static bool tint_discard = false;
void main_1() {
float3 viewDirectionW = float3(0.0f, 0.0f, 0.0f);
@ -31,10 +30,12 @@ void main_1() {
float3 finalSpecular = float3(0.0f, 0.0f, 0.0f);
float4 color = float4(0.0f, 0.0f, 0.0f, 0.0f);
if ((fClipDistance3 > 0.0f)) {
discard;
tint_discard = true;
return;
}
if ((fClipDistance4 > 0.0f)) {
discard;
tint_discard = true;
return;
}
const float4 x_34 = asfloat(x_29[0]);
const float3 x_38 = float3(0.0f, 0.0f, 0.0f);
@ -96,15 +97,26 @@ main_out main_inner(float fClipDistance3_param, float fClipDistance4_param) {
fClipDistance3 = fClipDistance3_param;
fClipDistance4 = fClipDistance4_param;
main_1();
const main_out tint_symbol_8 = {glFragColor};
return tint_symbol_8;
if (tint_discard) {
const main_out tint_symbol_8 = (main_out)0;
return tint_symbol_8;
}
const main_out tint_symbol_9 = {glFragColor};
return tint_symbol_9;
}
void tint_discard_func() {
discard;
}
tint_symbol_2 main(tint_symbol_1 tint_symbol) {
const main_out inner_result = main_inner(tint_symbol.fClipDistance3_param, tint_symbol.fClipDistance4_param);
if (tint_discard) {
tint_discard_func();
const tint_symbol_2 tint_symbol_10 = (tint_symbol_2)0;
return tint_symbol_10;
}
tint_symbol_2 wrapper_result = (tint_symbol_2)0;
wrapper_result.glFragColor_1 = inner_result.glFragColor_1;
return wrapper_result;
}
Internal error: unread predicate

View File

@ -28,7 +28,7 @@ struct Mesh {
/* 0x0000 */ float visibility;
};
void main_1(thread float* const tint_symbol_5, thread float* const tint_symbol_6, const constant Scene* const tint_symbol_7, const constant Material* const tint_symbol_8, const constant Mesh* const tint_symbol_9, thread float4* const tint_symbol_10) {
void main_1(thread float* const tint_symbol_7, thread bool* const tint_symbol_8, thread float* const tint_symbol_9, const constant Scene* const tint_symbol_10, const constant Material* const tint_symbol_11, const constant Mesh* const tint_symbol_12, thread float4* const tint_symbol_13) {
float3 viewDirectionW = 0.0f;
float4 baseColor = 0.0f;
float3 diffuseColor = 0.0f;
@ -45,21 +45,23 @@ void main_1(thread float* const tint_symbol_5, thread float* const tint_symbol_6
float3 finalDiffuse = 0.0f;
float3 finalSpecular = 0.0f;
float4 color = 0.0f;
float const x_9 = *(tint_symbol_5);
float const x_9 = *(tint_symbol_7);
if ((x_9 > 0.0f)) {
discard_fragment();
*(tint_symbol_8) = true;
return;
}
float const x_17 = *(tint_symbol_6);
float const x_17 = *(tint_symbol_9);
if ((x_17 > 0.0f)) {
discard_fragment();
*(tint_symbol_8) = true;
return;
}
float4 const x_34 = (*(tint_symbol_7)).vEyePosition;
float4 const x_34 = (*(tint_symbol_10)).vEyePosition;
float3 const x_38 = float3(0.0f, 0.0f, 0.0f);
viewDirectionW = normalize((float3(x_34[0], x_34[1], x_34[2]) - x_38));
baseColor = float4(1.0f, 1.0f, 1.0f, 1.0f);
float4 const x_52 = (*(tint_symbol_8)).vDiffuseColor;
float4 const x_52 = (*(tint_symbol_11)).vDiffuseColor;
diffuseColor = float3(x_52[0], x_52[1], x_52[2]);
float const x_60 = (*(tint_symbol_8)).vDiffuseColor[3];
float const x_60 = (*(tint_symbol_11)).vDiffuseColor[3];
alpha = x_60;
float3 const x_62 = float3(0.0f, 0.0f, 0.0f);
float3 const x_64 = float3(0.0f, 0.0f, 0.0f);
@ -76,12 +78,12 @@ void main_1(thread float* const tint_symbol_5, thread float* const tint_symbol_6
shadow = 1.0f;
refractionColor = float4(0.0f, 0.0f, 0.0f, 1.0f);
reflectionColor = float4(0.0f, 0.0f, 0.0f, 1.0f);
float3 const x_94 = (*(tint_symbol_8)).vEmissiveColor;
float3 const x_94 = (*(tint_symbol_11)).vEmissiveColor;
emissiveColor = x_94;
float3 const x_96 = diffuseBase;
float3 const x_97 = diffuseColor;
float3 const x_99 = emissiveColor;
float3 const x_103 = (*(tint_symbol_8)).vAmbientColor;
float3 const x_103 = (*(tint_symbol_11)).vAmbientColor;
float4 const x_108 = baseColor;
finalDiffuse = (clamp((((x_96 * x_97) + x_99) + x_103), float3(0.0f, 0.0f, 0.0f), float3(1.0f, 1.0f, 1.0f)) * float3(x_108[0], x_108[1], x_108[2]));
finalSpecular = float3(0.0f, 0.0f, 0.0f);
@ -97,11 +99,11 @@ void main_1(thread float* const tint_symbol_5, thread float* const tint_symbol_6
float3 const x_132 = fmax(float3(x_129[0], x_129[1], x_129[2]), float3(0.0f, 0.0f, 0.0f));
float4 const x_133 = color;
color = float4(x_132[0], x_132[1], x_132[2], x_133[3]);
float const x_140 = (*(tint_symbol_9)).visibility;
float const x_140 = (*(tint_symbol_12)).visibility;
float const x_142 = color[3];
color[3] = (x_142 * x_140);
float4 const x_147 = color;
*(tint_symbol_10) = x_147;
*(tint_symbol_13) = x_147;
return;
}
@ -118,19 +120,33 @@ struct tint_symbol_3 {
float4 glFragColor_1 [[color(0)]];
};
main_out tint_symbol_inner(float fClipDistance3_param, float fClipDistance4_param, thread float* const tint_symbol_11, thread float* const tint_symbol_12, const constant Scene* const tint_symbol_13, const constant Material* const tint_symbol_14, const constant Mesh* const tint_symbol_15, thread float4* const tint_symbol_16) {
*(tint_symbol_11) = fClipDistance3_param;
*(tint_symbol_12) = fClipDistance4_param;
main_1(tint_symbol_11, tint_symbol_12, tint_symbol_13, tint_symbol_14, tint_symbol_15, tint_symbol_16);
main_out const tint_symbol_4 = {.glFragColor_1=*(tint_symbol_16)};
return tint_symbol_4;
main_out tint_symbol_inner(float fClipDistance3_param, float fClipDistance4_param, thread float* const tint_symbol_14, thread float* const tint_symbol_15, thread bool* const tint_symbol_16, const constant Scene* const tint_symbol_17, const constant Material* const tint_symbol_18, const constant Mesh* const tint_symbol_19, thread float4* const tint_symbol_20) {
*(tint_symbol_14) = fClipDistance3_param;
*(tint_symbol_15) = fClipDistance4_param;
main_1(tint_symbol_14, tint_symbol_16, tint_symbol_15, tint_symbol_17, tint_symbol_18, tint_symbol_19, tint_symbol_20);
if (*(tint_symbol_16)) {
main_out const tint_symbol_4 = {};
return tint_symbol_4;
}
main_out const tint_symbol_5 = {.glFragColor_1=*(tint_symbol_20)};
return tint_symbol_5;
}
fragment tint_symbol_3 tint_symbol(const constant Scene* tint_symbol_19 [[buffer(0)]], const constant Material* tint_symbol_20 [[buffer(1)]], const constant Mesh* tint_symbol_21 [[buffer(2)]], tint_symbol_2 tint_symbol_1 [[stage_in]]) {
thread float tint_symbol_17 = 0.0f;
thread float tint_symbol_18 = 0.0f;
thread float4 tint_symbol_22 = 0.0f;
main_out const inner_result = tint_symbol_inner(tint_symbol_1.fClipDistance3_param, tint_symbol_1.fClipDistance4_param, &(tint_symbol_17), &(tint_symbol_18), tint_symbol_19, tint_symbol_20, tint_symbol_21, &(tint_symbol_22));
void tint_discard_func() {
discard_fragment();
}
fragment tint_symbol_3 tint_symbol(const constant Scene* tint_symbol_24 [[buffer(0)]], const constant Material* tint_symbol_25 [[buffer(1)]], const constant Mesh* tint_symbol_26 [[buffer(2)]], tint_symbol_2 tint_symbol_1 [[stage_in]]) {
thread float tint_symbol_21 = 0.0f;
thread float tint_symbol_22 = 0.0f;
thread bool tint_symbol_23 = false;
thread float4 tint_symbol_27 = 0.0f;
main_out const inner_result = tint_symbol_inner(tint_symbol_1.fClipDistance3_param, tint_symbol_1.fClipDistance4_param, &(tint_symbol_21), &(tint_symbol_22), &(tint_symbol_23), tint_symbol_24, tint_symbol_25, tint_symbol_26, &(tint_symbol_27));
if (tint_symbol_23) {
tint_discard_func();
tint_symbol_3 const tint_symbol_6 = {};
return tint_symbol_6;
}
tint_symbol_3 wrapper_result = {};
wrapper_result.glFragColor_1 = inner_result.glFragColor_1;
return wrapper_result;

View File

@ -1,10 +1,10 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 187
; Bound: 198
; Schema: 0
OpCapability Shader
%69 = OpExtInstImport "GLSL.std.450"
%73 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %fClipDistance3_param_1 %fClipDistance4_param_1 %glFragColor_1_1
OpExecutionMode %main OriginUpperLeft
@ -27,6 +27,7 @@
OpMemberName %Mesh 0 "visibility"
OpName %x_137 "x_137"
OpName %glFragColor "glFragColor"
OpName %tint_discard "tint_discard"
OpName %main_1 "main_1"
OpName %viewDirectionW "viewDirectionW"
OpName %baseColor "baseColor"
@ -44,6 +45,7 @@
OpName %finalDiffuse "finalDiffuse"
OpName %finalSpecular "finalSpecular"
OpName %color "color"
OpName %tint_discard_func "tint_discard_func"
OpName %main_out "main_out"
OpMemberName %main_out 0 "glFragColor_1"
OpName %main_inner "main_inner"
@ -97,199 +99,217 @@
%x_137 = OpVariable %_ptr_Uniform_Mesh Uniform
%_ptr_Private_v4float = OpTypePointer Private %v4float
%glFragColor = OpVariable %_ptr_Private_v4float Private %8
%bool = OpTypeBool
%false = OpConstantFalse %bool
%_ptr_Private_bool = OpTypePointer Private %bool
%tint_discard = OpVariable %_ptr_Private_bool Private %false
%void = OpTypeVoid
%25 = OpTypeFunction %void
%29 = OpTypeFunction %void
%_ptr_Function_v3float = OpTypePointer Function %v3float
%31 = OpConstantNull %v3float
%35 = OpConstantNull %v3float
%_ptr_Function_v4float = OpTypePointer Function %v4float
%_ptr_Function_float = OpTypePointer Function %float
%v2float = OpTypeVector %float 2
%_ptr_Function_v2float = OpTypePointer Function %v2float
%41 = OpConstantNull %v2float
%45 = OpConstantNull %v2float
%float_0 = OpConstant %float 0
%bool = OpTypeBool
%true = OpConstantTrue %bool
%uint = OpTypeInt 32 0
%uint_0 = OpConstant %uint 0
%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
%67 = OpConstantComposite %v3float %float_0 %float_0 %float_0
%71 = OpConstantComposite %v3float %float_0 %float_0 %float_0
%float_1 = OpConstant %float 1
%76 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
%80 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
%uint_3 = OpConstant %uint 3
%_ptr_Uniform_float = OpTypePointer Uniform %float
%92 = OpConstantComposite %v2float %float_0 %float_0
%93 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
%110 = OpConstantComposite %v3float %float_1 %float_1 %float_1
%111 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
%96 = OpConstantComposite %v2float %float_0 %float_0
%97 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
%114 = OpConstantComposite %v3float %float_1 %float_1 %float_1
%115 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
%uint_1 = OpConstant %uint 1
%main_out = OpTypeStruct %v4float
%172 = OpTypeFunction %main_out %float %float
%main_1 = OpFunction %void None %25
%28 = OpLabel
%viewDirectionW = OpVariable %_ptr_Function_v3float Function %31
%178 = OpTypeFunction %main_out %float %float
%189 = OpConstantNull %main_out
%main_1 = OpFunction %void None %29
%32 = OpLabel
%viewDirectionW = OpVariable %_ptr_Function_v3float Function %35
%baseColor = OpVariable %_ptr_Function_v4float Function %8
%diffuseColor = OpVariable %_ptr_Function_v3float Function %31
%diffuseColor = OpVariable %_ptr_Function_v3float Function %35
%alpha = OpVariable %_ptr_Function_float Function %11
%normalW = OpVariable %_ptr_Function_v3float Function %31
%uvOffset = OpVariable %_ptr_Function_v2float Function %41
%baseAmbientColor = OpVariable %_ptr_Function_v3float Function %31
%normalW = OpVariable %_ptr_Function_v3float Function %35
%uvOffset = OpVariable %_ptr_Function_v2float Function %45
%baseAmbientColor = OpVariable %_ptr_Function_v3float Function %35
%glossiness = OpVariable %_ptr_Function_float Function %11
%diffuseBase = OpVariable %_ptr_Function_v3float Function %31
%diffuseBase = OpVariable %_ptr_Function_v3float Function %35
%shadow = OpVariable %_ptr_Function_float Function %11
%refractionColor = OpVariable %_ptr_Function_v4float Function %8
%reflectionColor = OpVariable %_ptr_Function_v4float Function %8
%emissiveColor = OpVariable %_ptr_Function_v3float Function %31
%finalDiffuse = OpVariable %_ptr_Function_v3float Function %31
%finalSpecular = OpVariable %_ptr_Function_v3float Function %31
%emissiveColor = OpVariable %_ptr_Function_v3float Function %35
%finalDiffuse = OpVariable %_ptr_Function_v3float Function %35
%finalSpecular = OpVariable %_ptr_Function_v3float Function %35
%color = OpVariable %_ptr_Function_v4float Function %8
%52 = OpLoad %float %fClipDistance3
%54 = OpFOrdGreaterThan %bool %52 %float_0
OpSelectionMerge %56 None
OpBranchConditional %54 %57 %56
%57 = OpLabel
OpKill
%56 = OpLabel
%58 = OpLoad %float %fClipDistance4
%59 = OpFOrdGreaterThan %bool %58 %float_0
OpSelectionMerge %60 None
OpBranchConditional %59 %61 %60
%61 = OpLabel
OpKill
%56 = OpLoad %float %fClipDistance3
%58 = OpFOrdGreaterThan %bool %56 %float_0
OpSelectionMerge %59 None
OpBranchConditional %58 %60 %59
%60 = OpLabel
%65 = OpAccessChain %_ptr_Uniform_v4float %x_29 %uint_0
%66 = OpLoad %v4float %65
%70 = OpCompositeExtract %float %66 0
%71 = OpCompositeExtract %float %66 1
%72 = OpCompositeExtract %float %66 2
%73 = OpCompositeConstruct %v3float %70 %71 %72
%74 = OpFSub %v3float %73 %67
%68 = OpExtInst %v3float %69 Normalize %74
OpStore %viewDirectionW %68
OpStore %baseColor %76
%77 = OpAccessChain %_ptr_Uniform_v4float %x_49 %uint_0
%78 = OpLoad %v4float %77
%79 = OpCompositeExtract %float %78 0
%80 = OpCompositeExtract %float %78 1
%81 = OpCompositeExtract %float %78 2
%82 = OpCompositeConstruct %v3float %79 %80 %81
OpStore %diffuseColor %82
%85 = OpAccessChain %_ptr_Uniform_float %x_49 %uint_0 %uint_3
%86 = OpLoad %float %85
OpStore %alpha %86
%90 = OpDPdx %v3float %67
%91 = OpDPdy %v3float %67
%89 = OpExtInst %v3float %69 Cross %90 %91
%88 = OpFNegate %v3float %89
%87 = OpExtInst %v3float %69 Normalize %88
OpStore %normalW %87
OpStore %uvOffset %92
%94 = OpLoad %v4float %baseColor
%95 = OpCompositeExtract %float %94 0
%96 = OpCompositeExtract %float %94 1
%97 = OpCompositeExtract %float %94 2
%98 = OpCompositeConstruct %v3float %95 %96 %97
%99 = OpCompositeExtract %float %93 0
%100 = OpCompositeExtract %float %93 1
%101 = OpCompositeExtract %float %93 2
OpStore %tint_discard %true
OpReturn
%59 = OpLabel
%62 = OpLoad %float %fClipDistance4
%63 = OpFOrdGreaterThan %bool %62 %float_0
OpSelectionMerge %64 None
OpBranchConditional %63 %65 %64
%65 = OpLabel
OpStore %tint_discard %true
OpReturn
%64 = OpLabel
%69 = OpAccessChain %_ptr_Uniform_v4float %x_29 %uint_0
%70 = OpLoad %v4float %69
%74 = OpCompositeExtract %float %70 0
%75 = OpCompositeExtract %float %70 1
%76 = OpCompositeExtract %float %70 2
%77 = OpCompositeConstruct %v3float %74 %75 %76
%78 = OpFSub %v3float %77 %71
%72 = OpExtInst %v3float %73 Normalize %78
OpStore %viewDirectionW %72
OpStore %baseColor %80
%81 = OpAccessChain %_ptr_Uniform_v4float %x_49 %uint_0
%82 = OpLoad %v4float %81
%83 = OpCompositeExtract %float %82 0
%84 = OpCompositeExtract %float %82 1
%85 = OpCompositeExtract %float %82 2
%86 = OpCompositeConstruct %v3float %83 %84 %85
OpStore %diffuseColor %86
%89 = OpAccessChain %_ptr_Uniform_float %x_49 %uint_0 %uint_3
%90 = OpLoad %float %89
OpStore %alpha %90
%94 = OpDPdx %v3float %71
%95 = OpDPdy %v3float %71
%93 = OpExtInst %v3float %73 Cross %94 %95
%92 = OpFNegate %v3float %93
%91 = OpExtInst %v3float %73 Normalize %92
OpStore %normalW %91
OpStore %uvOffset %96
%98 = OpLoad %v4float %baseColor
%99 = OpCompositeExtract %float %98 0
%100 = OpCompositeExtract %float %98 1
%101 = OpCompositeExtract %float %98 2
%102 = OpCompositeConstruct %v3float %99 %100 %101
%103 = OpFMul %v3float %98 %102
%104 = OpLoad %v4float %baseColor
%105 = OpCompositeExtract %float %103 0
%106 = OpCompositeExtract %float %103 1
%107 = OpCompositeExtract %float %103 2
%108 = OpCompositeExtract %float %104 3
%109 = OpCompositeConstruct %v4float %105 %106 %107 %108
OpStore %baseColor %109
OpStore %baseAmbientColor %110
%103 = OpCompositeExtract %float %97 0
%104 = OpCompositeExtract %float %97 1
%105 = OpCompositeExtract %float %97 2
%106 = OpCompositeConstruct %v3float %103 %104 %105
%107 = OpFMul %v3float %102 %106
%108 = OpLoad %v4float %baseColor
%109 = OpCompositeExtract %float %107 0
%110 = OpCompositeExtract %float %107 1
%111 = OpCompositeExtract %float %107 2
%112 = OpCompositeExtract %float %108 3
%113 = OpCompositeConstruct %v4float %109 %110 %111 %112
OpStore %baseColor %113
OpStore %baseAmbientColor %114
OpStore %glossiness %float_0
OpStore %diffuseBase %67
OpStore %diffuseBase %71
OpStore %shadow %float_1
OpStore %refractionColor %111
OpStore %reflectionColor %111
%113 = OpAccessChain %_ptr_Uniform_v3float %x_49 %uint_3
%114 = OpLoad %v3float %113
OpStore %emissiveColor %114
%115 = OpLoad %v3float %diffuseBase
%116 = OpLoad %v3float %diffuseColor
%117 = OpLoad %v3float %emissiveColor
%119 = OpAccessChain %_ptr_Uniform_v3float %x_49 %uint_1
%120 = OpLoad %v3float %119
%121 = OpLoad %v4float %baseColor
%123 = OpFMul %v3float %115 %116
%124 = OpFAdd %v3float %123 %117
%125 = OpFAdd %v3float %124 %120
%122 = OpExtInst %v3float %69 NClamp %125 %67 %110
%126 = OpCompositeExtract %float %121 0
%127 = OpCompositeExtract %float %121 1
%128 = OpCompositeExtract %float %121 2
%129 = OpCompositeConstruct %v3float %126 %127 %128
%130 = OpFMul %v3float %122 %129
OpStore %finalDiffuse %130
OpStore %finalSpecular %67
%131 = OpLoad %v3float %finalDiffuse
%132 = OpLoad %v3float %baseAmbientColor
%133 = OpLoad %v3float %finalSpecular
%134 = OpLoad %v4float %reflectionColor
%135 = OpLoad %v4float %refractionColor
%136 = OpFMul %v3float %131 %132
%137 = OpFAdd %v3float %136 %133
%138 = OpCompositeExtract %float %134 0
%139 = OpCompositeExtract %float %134 1
%140 = OpCompositeExtract %float %134 2
%141 = OpCompositeConstruct %v3float %138 %139 %140
%142 = OpFAdd %v3float %137 %141
%143 = OpCompositeExtract %float %135 0
%144 = OpCompositeExtract %float %135 1
%145 = OpCompositeExtract %float %135 2
%146 = OpCompositeConstruct %v3float %143 %144 %145
%147 = OpFAdd %v3float %142 %146
%148 = OpLoad %float %alpha
%149 = OpCompositeExtract %float %147 0
%150 = OpCompositeExtract %float %147 1
%151 = OpCompositeExtract %float %147 2
%152 = OpCompositeConstruct %v4float %149 %150 %151 %148
OpStore %color %152
%153 = OpLoad %v4float %color
%155 = OpCompositeExtract %float %153 0
%156 = OpCompositeExtract %float %153 1
%157 = OpCompositeExtract %float %153 2
%158 = OpCompositeConstruct %v3float %155 %156 %157
%154 = OpExtInst %v3float %69 NMax %158 %67
%159 = OpLoad %v4float %color
%160 = OpCompositeExtract %float %154 0
%161 = OpCompositeExtract %float %154 1
%162 = OpCompositeExtract %float %154 2
%163 = OpCompositeExtract %float %159 3
%164 = OpCompositeConstruct %v4float %160 %161 %162 %163
OpStore %color %164
%165 = OpAccessChain %_ptr_Uniform_float %x_137 %uint_0
%166 = OpLoad %float %165
%167 = OpAccessChain %_ptr_Function_float %color %uint_3
%168 = OpLoad %float %167
%169 = OpAccessChain %_ptr_Function_float %color %uint_3
%170 = OpFMul %float %168 %166
OpStore %169 %170
%171 = OpLoad %v4float %color
OpStore %glFragColor %171
OpStore %refractionColor %115
OpStore %reflectionColor %115
%117 = OpAccessChain %_ptr_Uniform_v3float %x_49 %uint_3
%118 = OpLoad %v3float %117
OpStore %emissiveColor %118
%119 = OpLoad %v3float %diffuseBase
%120 = OpLoad %v3float %diffuseColor
%121 = OpLoad %v3float %emissiveColor
%123 = OpAccessChain %_ptr_Uniform_v3float %x_49 %uint_1
%124 = OpLoad %v3float %123
%125 = OpLoad %v4float %baseColor
%127 = OpFMul %v3float %119 %120
%128 = OpFAdd %v3float %127 %121
%129 = OpFAdd %v3float %128 %124
%126 = OpExtInst %v3float %73 NClamp %129 %71 %114
%130 = OpCompositeExtract %float %125 0
%131 = OpCompositeExtract %float %125 1
%132 = OpCompositeExtract %float %125 2
%133 = OpCompositeConstruct %v3float %130 %131 %132
%134 = OpFMul %v3float %126 %133
OpStore %finalDiffuse %134
OpStore %finalSpecular %71
%135 = OpLoad %v3float %finalDiffuse
%136 = OpLoad %v3float %baseAmbientColor
%137 = OpLoad %v3float %finalSpecular
%138 = OpLoad %v4float %reflectionColor
%139 = OpLoad %v4float %refractionColor
%140 = OpFMul %v3float %135 %136
%141 = OpFAdd %v3float %140 %137
%142 = OpCompositeExtract %float %138 0
%143 = OpCompositeExtract %float %138 1
%144 = OpCompositeExtract %float %138 2
%145 = OpCompositeConstruct %v3float %142 %143 %144
%146 = OpFAdd %v3float %141 %145
%147 = OpCompositeExtract %float %139 0
%148 = OpCompositeExtract %float %139 1
%149 = OpCompositeExtract %float %139 2
%150 = OpCompositeConstruct %v3float %147 %148 %149
%151 = OpFAdd %v3float %146 %150
%152 = OpLoad %float %alpha
%153 = OpCompositeExtract %float %151 0
%154 = OpCompositeExtract %float %151 1
%155 = OpCompositeExtract %float %151 2
%156 = OpCompositeConstruct %v4float %153 %154 %155 %152
OpStore %color %156
%157 = OpLoad %v4float %color
%159 = OpCompositeExtract %float %157 0
%160 = OpCompositeExtract %float %157 1
%161 = OpCompositeExtract %float %157 2
%162 = OpCompositeConstruct %v3float %159 %160 %161
%158 = OpExtInst %v3float %73 NMax %162 %71
%163 = OpLoad %v4float %color
%164 = OpCompositeExtract %float %158 0
%165 = OpCompositeExtract %float %158 1
%166 = OpCompositeExtract %float %158 2
%167 = OpCompositeExtract %float %163 3
%168 = OpCompositeConstruct %v4float %164 %165 %166 %167
OpStore %color %168
%169 = OpAccessChain %_ptr_Uniform_float %x_137 %uint_0
%170 = OpLoad %float %169
%171 = OpAccessChain %_ptr_Function_float %color %uint_3
%172 = OpLoad %float %171
%173 = OpAccessChain %_ptr_Function_float %color %uint_3
%174 = OpFMul %float %172 %170
OpStore %173 %174
%175 = OpLoad %v4float %color
OpStore %glFragColor %175
OpReturn
OpFunctionEnd
%main_inner = OpFunction %main_out None %172
%tint_discard_func = OpFunction %void None %29
%177 = OpLabel
OpKill
OpFunctionEnd
%main_inner = OpFunction %main_out None %178
%fClipDistance3_param = OpFunctionParameter %float
%fClipDistance4_param = OpFunctionParameter %float
%177 = OpLabel
%183 = OpLabel
OpStore %fClipDistance3 %fClipDistance3_param
OpStore %fClipDistance4 %fClipDistance4_param
%178 = OpFunctionCall %void %main_1
%179 = OpLoad %v4float %glFragColor
%180 = OpCompositeConstruct %main_out %179
OpReturnValue %180
%184 = OpFunctionCall %void %main_1
%185 = OpLoad %bool %tint_discard
OpSelectionMerge %186 None
OpBranchConditional %185 %187 %186
%187 = OpLabel
%188 = OpFunctionCall %void %tint_discard_func
OpReturnValue %189
%186 = OpLabel
%190 = OpLoad %v4float %glFragColor
%191 = OpCompositeConstruct %main_out %190
OpReturnValue %191
OpFunctionEnd
%main = OpFunction %void None %25
%182 = OpLabel
%184 = OpLoad %float %fClipDistance3_param_1
%185 = OpLoad %float %fClipDistance4_param_1
%183 = OpFunctionCall %main_out %main_inner %184 %185
%186 = OpCompositeExtract %v4float %183 0
OpStore %glFragColor_1_1 %186
%main = OpFunction %void None %29
%193 = OpLabel
%195 = OpLoad %float %fClipDistance3_param_1
%196 = OpLoad %float %fClipDistance4_param_1
%194 = OpFunctionCall %main_out %main_inner %195 %196
%197 = OpCompositeExtract %v4float %194 0
OpStore %glFragColor_1_1 %197
OpReturn
OpFunctionEnd

View File

@ -9,17 +9,30 @@ bug/tint/1369.wgsl:9:9 warning: code is unreachable
#version 310 es
precision mediump float;
bool tint_discard = false;
bool call_discard() {
discard;
tint_discard = true;
return false;
return true;
}
void f() {
bool v = call_discard();
if (tint_discard) {
return;
}
bool also_unreachable = false;
}
void tint_discard_func() {
discard;
}
void main() {
f();
if (tint_discard) {
tint_discard_func();
return;
}
return;
}

View File

@ -6,17 +6,24 @@ bug/tint/1369.wgsl:9:9 warning: code is unreachable
var also_unreachable : bool;
^^^^^^^^^^^^^^^^
static bool tint_discard = false;
bool call_discard() {
if (true) {
discard;
return true;
}
bool unused;
return unused;
tint_discard = true;
return false;
return true;
}
void tint_discard_func() {
discard;
}
void f() {
bool v = call_discard();
if (tint_discard) {
tint_discard_func();
return;
}
bool also_unreachable = false;
return;
}

View File

@ -9,13 +9,23 @@ bug/tint/1369.wgsl:9:9 warning: code is unreachable
#include <metal_stdlib>
using namespace metal;
bool call_discard() {
discard_fragment();
bool call_discard(thread bool* const tint_symbol) {
*(tint_symbol) = true;
return bool();
return true;
}
void tint_discard_func() {
discard_fragment();
}
fragment void f() {
bool v = call_discard();
thread bool tint_symbol_1 = false;
bool v = call_discard(&(tint_symbol_1));
if (tint_symbol_1) {
tint_discard_func();
return;
}
bool also_unreachable = false;
return;
}

View File

@ -9,29 +9,47 @@ bug/tint/1369.wgsl:9:9 warning: code is unreachable
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 13
; Bound: 23
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %f "f"
OpExecutionMode %f OriginUpperLeft
OpName %tint_discard "tint_discard"
OpName %call_discard "call_discard"
OpName %tint_discard_func "tint_discard_func"
OpName %f "f"
OpName %v "v"
%bool = OpTypeBool
%1 = OpTypeFunction %bool
%false = OpConstantFalse %bool
%_ptr_Private_bool = OpTypePointer Private %bool
%tint_discard = OpVariable %_ptr_Private_bool Private %false
%5 = OpTypeFunction %bool
%true = OpConstantTrue %bool
%9 = OpConstantNull %bool
%void = OpTypeVoid
%5 = OpTypeFunction %void
%10 = OpTypeFunction %void
%_ptr_Function_bool = OpTypePointer Function %bool
%12 = OpConstantNull %bool
%call_discard = OpFunction %bool None %1
%4 = OpLabel
%call_discard = OpFunction %bool None %5
%7 = OpLabel
OpStore %tint_discard %true
OpReturnValue %9
OpFunctionEnd
%tint_discard_func = OpFunction %void None %10
%13 = OpLabel
OpKill
OpFunctionEnd
%f = OpFunction %void None %5
%8 = OpLabel
%v = OpVariable %_ptr_Function_bool Function %12
%9 = OpFunctionCall %bool %call_discard
OpStore %v %9
%f = OpFunction %void None %10
%15 = OpLabel
%v = OpVariable %_ptr_Function_bool Function %9
%16 = OpFunctionCall %bool %call_discard
OpStore %v %16
%19 = OpLoad %bool %tint_discard
OpSelectionMerge %20 None
OpBranchConditional %19 %21 %20
%21 = OpLabel
%22 = OpFunctionCall %void %tint_discard_func
OpReturn
%20 = OpLabel
OpReturn
OpFunctionEnd

View File

@ -1,17 +0,0 @@
SKIP: FAILED
warning: code is unreachable
static uint var_1 = 0u;
void main_1() {
[loop] while (true) {
discard;
}
discard;
}
void main() {
main_1();
return;
}

View File

@ -1,50 +0,0 @@
SKIP: FAILED
cbuffer cbuffer_x_6 : register(b0, space0) {
uint4 x_6[1];
};
static float4 x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
void func_() {
const float x_28 = asfloat(x_6[0].x);
if ((1.0f > x_28)) {
discard;
}
return;
}
void main_1() {
x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
[loop] while (true) {
func_();
if (false) {
} else {
break;
}
}
x_GLF_color = float4(1.0f, 0.0f, 0.0f, 1.0f);
return;
}
struct main_out {
float4 x_GLF_color_1;
};
struct tint_symbol {
float4 x_GLF_color_1 : SV_Target0;
};
main_out main_inner() {
main_1();
const main_out tint_symbol_2 = {x_GLF_color};
return tint_symbol_2;
}
tint_symbol main() {
const main_out inner_result = main_inner();
tint_symbol wrapper_result = (tint_symbol)0;
wrapper_result.x_GLF_color_1 = inner_result.x_GLF_color_1;
return wrapper_result;
}
C:\src\tint\test\Shader@0x0000016102DC2B30(16,10-21): warning X3557: loop only executes for 0 iteration(s), consider removing [loop]
C:\src\tint\test\Shader@0x0000016102DC2B30(8,15-18): internal error: invalid access of unbound variable

View File

@ -1,50 +0,0 @@
SKIP: FAILED
cbuffer cbuffer_x_6 : register(b0, space0) {
uint4 x_6[1];
};
static float4 x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
void func_() {
const float x_28 = asfloat(x_6[0].x);
if ((1.0f > x_28)) {
discard;
}
return;
}
void main_1() {
x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
[loop] while (true) {
func_();
if (false) {
} else {
break;
}
}
x_GLF_color = float4(1.0f, 0.0f, 0.0f, 1.0f);
return;
}
struct main_out {
float4 x_GLF_color_1;
};
struct tint_symbol {
float4 x_GLF_color_1 : SV_Target0;
};
main_out main_inner() {
main_1();
const main_out tint_symbol_2 = {x_GLF_color};
return tint_symbol_2;
}
tint_symbol main() {
const main_out inner_result = main_inner();
tint_symbol wrapper_result = (tint_symbol)0;
wrapper_result.x_GLF_color_1 = inner_result.x_GLF_color_1;
return wrapper_result;
}
C:\src\tint\test\Shader@0x0000026A3937ED10(16,10-21): warning X3557: loop only executes for 0 iteration(s), consider removing [loop]
C:\src\tint\test\Shader@0x0000026A3937ED10(8,15-18): internal error: invalid access of unbound variable

View File

@ -1,64 +0,0 @@
SKIP: FAILED
cbuffer cbuffer_x_7 : register(b0, space0) {
uint4 x_7[1];
};
static float4 gl_FragCoord = float4(0.0f, 0.0f, 0.0f, 0.0f);
static float4 x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
float3 computePoint_() {
if (true) {
const float x_48 = asfloat(x_7[0].x);
const float x_50 = asfloat(x_7[0].y);
if ((x_48 > x_50)) {
discard;
}
return float3(0.0f, 0.0f, 0.0f);
}
float3 unused;
return unused;
}
void main_1() {
bool x_34 = false;
[loop] while (true) {
const float3 x_36 = computePoint_();
const float x_41 = gl_FragCoord.x;
if ((x_41 < 0.0f)) {
x_34 = true;
break;
}
const float3 x_45 = computePoint_();
x_GLF_color = float4(1.0f, 0.0f, 0.0f, 1.0f);
x_34 = true;
break;
}
return;
}
struct main_out {
float4 x_GLF_color_1;
};
struct tint_symbol_1 {
float4 gl_FragCoord_param : SV_Position;
};
struct tint_symbol_2 {
float4 x_GLF_color_1 : SV_Target0;
};
main_out main_inner(float4 gl_FragCoord_param) {
gl_FragCoord = gl_FragCoord_param;
main_1();
const main_out tint_symbol_4 = {x_GLF_color};
return tint_symbol_4;
}
tint_symbol_2 main(tint_symbol_1 tint_symbol) {
const main_out inner_result = main_inner(tint_symbol.gl_FragCoord_param);
tint_symbol_2 wrapper_result = (tint_symbol_2)0;
wrapper_result.x_GLF_color_1 = inner_result.x_GLF_color_1;
return wrapper_result;
}
C:\src\tint\test\Shader@0x0000014F8C58FE70(22,10-21): warning X3557: loop only executes for 0 iteration(s), consider removing [loop]
C:\src\tint\test\Shader@0x0000014F8C58FE70(11,10-13): internal error: invalid access of unbound variable

View File

@ -1,64 +0,0 @@
SKIP: FAILED
cbuffer cbuffer_x_7 : register(b0, space0) {
uint4 x_7[1];
};
static float4 gl_FragCoord = float4(0.0f, 0.0f, 0.0f, 0.0f);
static float4 x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
float3 computePoint_() {
if (true) {
const float x_48 = asfloat(x_7[0].x);
const float x_50 = asfloat(x_7[0].y);
if ((x_48 > x_50)) {
discard;
}
return float3(0.0f, 0.0f, 0.0f);
}
float3 unused;
return unused;
}
void main_1() {
bool x_34 = false;
[loop] while (true) {
const float3 x_36 = computePoint_();
const float x_41 = gl_FragCoord.x;
if ((x_41 < 0.0f)) {
x_34 = true;
break;
}
const float3 x_45 = computePoint_();
x_GLF_color = float4(1.0f, 0.0f, 0.0f, 1.0f);
x_34 = true;
break;
}
return;
}
struct main_out {
float4 x_GLF_color_1;
};
struct tint_symbol_1 {
float4 gl_FragCoord_param : SV_Position;
};
struct tint_symbol_2 {
float4 x_GLF_color_1 : SV_Target0;
};
main_out main_inner(float4 gl_FragCoord_param) {
gl_FragCoord = gl_FragCoord_param;
main_1();
const main_out tint_symbol_4 = {x_GLF_color};
return tint_symbol_4;
}
tint_symbol_2 main(tint_symbol_1 tint_symbol) {
const main_out inner_result = main_inner(tint_symbol.gl_FragCoord_param);
tint_symbol_2 wrapper_result = (tint_symbol_2)0;
wrapper_result.x_GLF_color_1 = inner_result.x_GLF_color_1;
return wrapper_result;
}
C:\src\tint\test\Shader@0x0000017E3AA920C0(22,10-21): warning X3557: loop only executes for 0 iteration(s), consider removing [loop]
C:\src\tint\test\Shader@0x0000017E3AA920C0(11,10-13): internal error: invalid access of unbound variable