blob: 57156cf7924e1125f369d50ed90a86a560215cf3 [file] [log] [blame]
Austin Engcc2516a2023-10-17 20:57:54 +00001// Copyright 2023 The Dawn & Tint Authors
dan sinclaireefa7fe2023-06-05 15:16:53 +00002//
Austin Engcc2516a2023-10-17 20:57:54 +00003// Redistribution and use in source and binary forms, with or without
4// modification, are permitted provided that the following conditions are met:
dan sinclaireefa7fe2023-06-05 15:16:53 +00005//
Austin Engcc2516a2023-10-17 20:57:54 +00006// 1. Redistributions of source code must retain the above copyright notice, this
7// list of conditions and the following disclaimer.
dan sinclaireefa7fe2023-06-05 15:16:53 +00008//
Austin Engcc2516a2023-10-17 20:57:54 +00009// 2. Redistributions in binary form must reproduce the above copyright notice,
10// this list of conditions and the following disclaimer in the documentation
11// and/or other materials provided with the distribution.
12//
13// 3. Neither the name of the copyright holder nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dan sinclaireefa7fe2023-06-05 15:16:53 +000027
dan sinclair16cb4bd2023-09-21 08:52:11 +000028#include <string>
29
dan sinclaireefa7fe2023-06-05 15:16:53 +000030#include "gtest/gtest-spi.h"
dan sinclair16cb4bd2023-09-21 08:52:11 +000031#include "src/tint/lang/core/ir/function.h"
Ben Claytond368f2c2023-08-01 00:37:35 +000032#include "src/tint/lang/core/ir/ir_helper_test.h"
dan sinclaireefa7fe2023-06-05 15:16:53 +000033
dan sinclair6f138fe2023-08-15 21:29:34 +000034namespace tint::core::ir {
dan sinclaireefa7fe2023-06-05 15:16:53 +000035namespace {
36
dan sinclairce6dffe2023-08-14 21:01:40 +000037using namespace tint::core::number_suffixes; // NOLINT
dan sinclaireefa7fe2023-06-05 15:16:53 +000038using IR_FunctionTest = IRTestHelper;
39
40TEST_F(IR_FunctionTest, Fail_NullReturnType) {
41 EXPECT_FATAL_FAILURE(
42 {
43 Module mod;
44 Builder b{mod};
Ben Claytonc67a4fa2023-06-09 19:34:20 +000045 b.Function("my_func", nullptr);
dan sinclaireefa7fe2023-06-05 15:16:53 +000046 },
47 "");
48}
49
50TEST_F(IR_FunctionTest, Fail_DoubleReturnBuiltin) {
51 EXPECT_FATAL_FAILURE(
52 {
53 Module mod;
54 Builder b{mod};
Ben Claytonc67a4fa2023-06-09 19:34:20 +000055 auto* f = b.Function("my_func", mod.Types().void_());
dan sinclaireefa7fe2023-06-05 15:16:53 +000056 f->SetReturnBuiltin(Function::ReturnBuiltin::kFragDepth);
57 f->SetReturnBuiltin(Function::ReturnBuiltin::kPosition);
58 },
59 "");
60}
61
62TEST_F(IR_FunctionTest, Fail_NullParam) {
63 EXPECT_FATAL_FAILURE(
64 {
65 Module mod;
66 Builder b{mod};
Ben Claytonc67a4fa2023-06-09 19:34:20 +000067 auto* f = b.Function("my_func", mod.Types().void_());
Ben Claytonb768af42023-06-09 23:31:16 +000068 f->SetParams({nullptr});
dan sinclaireefa7fe2023-06-05 15:16:53 +000069 },
70 "");
71}
72
Ben Clayton5acd44c2023-06-22 13:38:30 +000073TEST_F(IR_FunctionTest, Fail_NullBlock) {
dan sinclaireefa7fe2023-06-05 15:16:53 +000074 EXPECT_FATAL_FAILURE(
75 {
76 Module mod;
77 Builder b{mod};
Ben Claytonc67a4fa2023-06-09 19:34:20 +000078 auto* f = b.Function("my_func", mod.Types().void_());
Ben Clayton5acd44c2023-06-22 13:38:30 +000079 f->SetBlock(nullptr);
dan sinclaireefa7fe2023-06-05 15:16:53 +000080 },
81 "");
82}
83
dan sinclair16cb4bd2023-09-21 08:52:11 +000084TEST_F(IR_FunctionTest, Clone) {
85 auto* f =
86 b.Function("my_func", mod.Types().i32(), Function::PipelineStage::kCompute, {{2, 3, 4}});
87 f->SetReturnBuiltin(Function::ReturnBuiltin::kFragDepth);
88 f->SetReturnLocation(
89 1, Interpolation{core::InterpolationType::kFlat, core::InterpolationSampling::kCentroid});
90 f->SetReturnInvariant(true);
91
92 auto* param1 = b.FunctionParam("a", mod.Types().i32());
93 auto* param2 = b.FunctionParam("b", mod.Types().f32());
94 f->SetParams({param1, param2});
95
96 auto* new_param1 = clone_ctx.Clone(param1);
97 auto* new_param2 = clone_ctx.Clone(param2);
98 auto* new_f = clone_ctx.Clone(f);
99
100 EXPECT_NE(f, new_f);
101 EXPECT_EQ(std::string("my_func"), mod.NameOf(new_f).Name());
102
103 EXPECT_EQ(Function::PipelineStage::kCompute, new_f->Stage());
104 EXPECT_TRUE(new_f->WorkgroupSize().has_value());
105 auto wg = new_f->WorkgroupSize().value();
106 EXPECT_EQ(2u, wg[0]);
107 EXPECT_EQ(3u, wg[1]);
108 EXPECT_EQ(4u, wg[2]);
109
110 EXPECT_EQ(mod.Types().i32(), new_f->ReturnType());
111
112 EXPECT_TRUE(new_f->ReturnBuiltin().has_value());
113 EXPECT_EQ(Function::ReturnBuiltin::kFragDepth, new_f->ReturnBuiltin().value());
114
115 EXPECT_TRUE(new_f->ReturnLocation().has_value());
116 auto loc = new_f->ReturnLocation().value();
117 EXPECT_EQ(1u, loc.value);
118 EXPECT_EQ(core::InterpolationType::kFlat, loc.interpolation->type);
119 EXPECT_EQ(core::InterpolationSampling::kCentroid, loc.interpolation->sampling);
120
121 EXPECT_TRUE(new_f->ReturnInvariant());
122
123 EXPECT_EQ(2u, new_f->Params().Length());
124 EXPECT_EQ(new_param1, new_f->Params()[0]);
125 EXPECT_EQ(new_param2, new_f->Params()[1]);
126
James Pricef744cf42023-09-28 09:35:11 +0000127 // Cloned functions are not automatically added to the module.
128 EXPECT_EQ(mod.functions.Length(), 1u);
dan sinclair16cb4bd2023-09-21 08:52:11 +0000129}
130
131TEST_F(IR_FunctionTest, CloneWithExits) {
132 auto* f = b.Function("my_func", mod.Types().void_());
133 b.Append(f->Block(), [&] { b.Return(f); });
134
135 auto* new_f = clone_ctx.Clone(f);
136 EXPECT_EQ(1u, new_f->Block()->Length());
137 EXPECT_TRUE(new_f->Block()->Front()->Is<Return>());
138 EXPECT_EQ(new_f, new_f->Block()->Front()->As<Return>()->Func());
139}
140
dan sinclaireefa7fe2023-06-05 15:16:53 +0000141} // namespace
dan sinclair6f138fe2023-08-15 21:29:34 +0000142} // namespace tint::core::ir