• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/transform/remove_phonies.h"
16 
17 #include <memory>
18 #include <utility>
19 #include <vector>
20 
21 #include "src/transform/test_helper.h"
22 
23 namespace tint {
24 namespace transform {
25 namespace {
26 
27 using RemovePhoniesTest = TransformTest;
28 
TEST_F(RemovePhoniesTest,EmptyModule)29 TEST_F(RemovePhoniesTest, EmptyModule) {
30   auto* src = "";
31   auto* expect = "";
32 
33   auto got = Run<RemovePhonies>(src);
34 
35   EXPECT_EQ(expect, str(got));
36 }
37 
TEST_F(RemovePhoniesTest,NoSideEffects)38 TEST_F(RemovePhoniesTest, NoSideEffects) {
39   auto* src = R"(
40 [[group(0), binding(0)]] var t : texture_2d<f32>;
41 
42 fn f() {
43   var v : i32;
44   _ = &v;
45   _ = 1;
46   _ = 1 + 2;
47   _ = t;
48   _ = u32(3.0);
49   _ = f32(i32(4u));
50   _ = vec2<f32>(5.0);
51   _ = vec3<i32>(6, 7, 8);
52   _ = mat2x2<f32>(9.0, 10.0, 11.0, 12.0);
53 }
54 )";
55 
56   auto* expect = R"(
57 [[group(0), binding(0)]] var t : texture_2d<f32>;
58 
59 fn f() {
60   var v : i32;
61 }
62 )";
63 
64   auto got = Run<RemovePhonies>(src);
65 
66   EXPECT_EQ(expect, str(got));
67 }
68 
TEST_F(RemovePhoniesTest,SingleSideEffects)69 TEST_F(RemovePhoniesTest, SingleSideEffects) {
70   auto* src = R"(
71 fn neg(a : i32) -> i32 {
72   return -(a);
73 }
74 
75 fn add(a : i32, b : i32) -> i32 {
76   return (a + b);
77 }
78 
79 fn f() {
80   _ = neg(1);
81   _ = add(2, 3);
82   _ = add(neg(4), neg(5));
83   _ = u32(neg(6));
84   _ = f32(add(7, 8));
85   _ = vec2<f32>(f32(neg(9)));
86   _ = vec3<i32>(1, neg(10), 3);
87   _ = mat2x2<f32>(1.0, f32(add(11, 12)), 3.0, 4.0);
88 }
89 )";
90 
91   auto* expect = R"(
92 fn neg(a : i32) -> i32 {
93   return -(a);
94 }
95 
96 fn add(a : i32, b : i32) -> i32 {
97   return (a + b);
98 }
99 
100 fn f() {
101   neg(1);
102   add(2, 3);
103   add(neg(4), neg(5));
104   neg(6);
105   add(7, 8);
106   neg(9);
107   neg(10);
108   add(11, 12);
109 }
110 )";
111 
112   auto got = Run<RemovePhonies>(src);
113 
114   EXPECT_EQ(expect, str(got));
115 }
116 
TEST_F(RemovePhoniesTest,MultipleSideEffects)117 TEST_F(RemovePhoniesTest, MultipleSideEffects) {
118   auto* src = R"(
119 fn neg(a : i32) -> i32 {
120   return -(a);
121 }
122 
123 fn add(a : i32, b : i32) -> i32 {
124   return (a + b);
125 }
126 
127 fn xor(a : u32, b : u32) -> u32 {
128   return (a ^ b);
129 }
130 
131 fn f() {
132   _ = (1 + add(2 + add(3, 4), 5)) * add(6, 7) * neg(8);
133   _ = add(9, neg(10)) + neg(11);
134   _ = xor(12u, 13u) + xor(14u, 15u);
135   _ = neg(16) / neg(17) + add(18, 19);
136 }
137 )";
138 
139   auto* expect = R"(
140 fn neg(a : i32) -> i32 {
141   return -(a);
142 }
143 
144 fn add(a : i32, b : i32) -> i32 {
145   return (a + b);
146 }
147 
148 fn xor(a : u32, b : u32) -> u32 {
149   return (a ^ b);
150 }
151 
152 fn phony_sink(p0 : i32, p1 : i32, p2 : i32) {
153 }
154 
155 fn phony_sink_1(p0 : i32, p1 : i32) {
156 }
157 
158 fn phony_sink_2(p0 : u32, p1 : u32) {
159 }
160 
161 fn f() {
162   phony_sink(add((2 + add(3, 4)), 5), add(6, 7), neg(8));
163   phony_sink_1(add(9, neg(10)), neg(11));
164   phony_sink_2(xor(12u, 13u), xor(14u, 15u));
165   phony_sink(neg(16), neg(17), add(18, 19));
166 }
167 )";
168 
169   auto got = Run<RemovePhonies>(src);
170 
171   EXPECT_EQ(expect, str(got));
172 }
173 
TEST_F(RemovePhoniesTest,ForLoop)174 TEST_F(RemovePhoniesTest, ForLoop) {
175   auto* src = R"(
176 [[block]]
177 struct S {
178   arr : array<i32>;
179 };
180 
181 [[group(0), binding(0)]] var<storage, read_write> s : S;
182 
183 fn x() -> i32 {
184   return 0;
185 }
186 
187 fn y() -> i32 {
188   return 0;
189 }
190 
191 fn z() -> i32 {
192   return 0;
193 }
194 
195 fn f() {
196   for (_ = &s.arr; ;_ = &s.arr) {
197     break;
198   }
199   for (_ = x(); ;_ = y() + z()) {
200     break;
201   }
202 }
203 )";
204 
205   auto* expect = R"(
206 [[block]]
207 struct S {
208   arr : array<i32>;
209 };
210 
211 [[group(0), binding(0)]] var<storage, read_write> s : S;
212 
213 fn x() -> i32 {
214   return 0;
215 }
216 
217 fn y() -> i32 {
218   return 0;
219 }
220 
221 fn z() -> i32 {
222   return 0;
223 }
224 
225 fn phony_sink(p0 : i32, p1 : i32) {
226 }
227 
228 fn f() {
229   for(; ; ) {
230     break;
231   }
232   for(x(); ; phony_sink(y(), z())) {
233     break;
234   }
235 }
236 )";
237 
238   auto got = Run<RemovePhonies>(src);
239 
240   EXPECT_EQ(expect, str(got));
241 }
242 
243 }  // namespace
244 }  // namespace transform
245 }  // namespace tint
246