| // Copyright 2021 The Dawn & Tint Authors |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are met: |
| // |
| // 1. Redistributions of source code must retain the above copyright notice, this |
| // list of conditions and the following disclaimer. |
| // |
| // 2. Redistributions in binary form must reproduce the above copyright notice, |
| // this list of conditions and the following disclaimer in the documentation |
| // and/or other materials provided with the distribution. |
| // |
| // 3. Neither the name of the copyright holder nor the names of its |
| // contributors may be used to endorse or promote products derived from |
| // this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
| // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| #include "src/tint/lang/wgsl/ast/transform/promote_side_effects_to_decl.h" |
| |
| #include "src/tint/lang/wgsl/ast/transform/helper_test.h" |
| |
| namespace tint::ast::transform { |
| namespace { |
| |
| using PromoteSideEffectsToDeclTest = TransformTest; |
| |
| TEST_F(PromoteSideEffectsToDeclTest, EmptyModule) { |
| auto* src = ""; |
| auto* expect = ""; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Unary_Arith_SE) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| let r = -(a(0)); |
| } |
| )"; |
| |
| auto* expect = src; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_BothSE) { |
| auto* src = R"( |
| fn a() -> i32 { |
| return 1; |
| } |
| |
| fn b() -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| let r = a() + b(); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a() -> i32 { |
| return 1; |
| } |
| |
| fn b() -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| let tint_symbol : i32 = a(); |
| let tint_symbol_1 : i32 = b(); |
| let r = (tint_symbol + tint_symbol_1); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_LeftSE) { |
| auto* src = R"( |
| fn a() -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| let r = a() + b; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a() -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| let tint_symbol : i32 = a(); |
| let r = (tint_symbol + b); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_RightSE) { |
| auto* src = R"( |
| fn a() -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| let r = b + a(); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a() -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| let tint_symbol : i32 = b; |
| let tint_symbol_1 : i32 = a(); |
| let r = (tint_symbol + tint_symbol_1); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_LeftmostSE) { |
| auto* src = R"( |
| fn a() -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| var c = 1; |
| var d = 1; |
| let r = a() + b + c + d; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a() -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| var c = 1; |
| var d = 1; |
| let tint_symbol : i32 = a(); |
| let r = (((tint_symbol + b) + c) + d); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_RightmostSE) { |
| auto* src = R"( |
| fn a() -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| var c = 1; |
| var d = 1; |
| let r = b + c + d + a(); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a() -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| var c = 1; |
| var d = 1; |
| let tint_symbol : i32 = ((b + c) + d); |
| let tint_symbol_1 : i32 = a(); |
| let r = (tint_symbol + tint_symbol_1); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_MiddleSE) { |
| auto* src = R"( |
| fn a() -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| var c = 1; |
| var d = 1; |
| var e = 1; |
| let r = b + c + a() + d + e; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a() -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| var c = 1; |
| var d = 1; |
| var e = 1; |
| let tint_symbol : i32 = (b + c); |
| let tint_symbol_1 : i32 = a(); |
| let r = (((tint_symbol + tint_symbol_1) + d) + e); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_ThreeSE) { |
| auto* src = R"( |
| fn a(v : i32) -> i32 { |
| return v; |
| } |
| |
| fn f() { |
| let r = a(0) + a(1) + a(2); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(v : i32) -> i32 { |
| return v; |
| } |
| |
| fn f() { |
| let tint_symbol : i32 = a(0); |
| let tint_symbol_1 : i32 = a(1); |
| let tint_symbol_2 : i32 = a(2); |
| let r = ((tint_symbol + tint_symbol_1) + tint_symbol_2); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_Constants_NoRecvSE) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| let r = ((((1 + a(0)) - 2) + 3) - 4); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| let tint_symbol : i32 = a(0); |
| let r = ((((1 + tint_symbol) - 2) + 3) - 4); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_Constants_RecvSE) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| let r = a(0) + 1 + b + a(1) + 2; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| let tint_symbol : i32 = a(0); |
| let tint_symbol_1 : i32 = b; |
| let tint_symbol_2 : i32 = a(1); |
| let r = ((((tint_symbol + 1) + tint_symbol_1) + tint_symbol_2) + 2); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_Constants_ConstAndSEAndVar) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn main() { |
| var b = 1; |
| var c = 1; |
| let r = 1 + a(0) + b; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn main() { |
| var b = 1; |
| var c = 1; |
| let tint_symbol : i32 = a(0); |
| let r = ((1 + tint_symbol) + b); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_Constants_VarAndSEAndConst) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn main() { |
| var b = 1; |
| let r = b + a(0) + 1; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn main() { |
| var b = 1; |
| let tint_symbol : i32 = b; |
| let tint_symbol_1 : i32 = a(0); |
| let r = ((tint_symbol + tint_symbol_1) + 1); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_Constants_SEAndVarAndConstAndVar) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn main() { |
| var b = 1; |
| var c = 1; |
| let r = a(0) + b + 1 + c; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn main() { |
| var b = 1; |
| var c = 1; |
| let tint_symbol : i32 = a(0); |
| let r = (((tint_symbol + b) + 1) + c); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_Builtins_WithSE) { |
| auto* src = R"( |
| struct SB { |
| a : atomic<i32>, |
| } |
| |
| @group(0) @binding(0) var<storage, read_write> sb : SB; |
| |
| fn f() { |
| var b = 0; |
| let r = atomicAdd(&sb.a, 123) + b; |
| } |
| )"; |
| |
| auto* expect = R"( |
| struct SB { |
| a : atomic<i32>, |
| } |
| |
| @group(0) @binding(0) var<storage, read_write> sb : SB; |
| |
| fn f() { |
| var b = 0; |
| let tint_symbol : i32 = atomicAdd(&(sb.a), 123); |
| let r = (tint_symbol + b); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_Builtins_NoSEAndVar) { |
| auto* src = R"( |
| struct SB { |
| a : atomic<i32>, |
| } |
| |
| @group(0) @binding(0) var<storage, read_write> sb : SB; |
| |
| fn f() { |
| var b = 0; |
| let r = (atomicLoad(&(sb.a)) + b); |
| } |
| )"; |
| |
| auto* expect = src; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_Builtins_NoSEAndSE) { |
| auto* src = R"( |
| struct SB { |
| a : atomic<i32>, |
| } |
| |
| @group(0) @binding(0) var<storage, read_write> sb : SB; |
| |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 0; |
| let r = (atomicLoad(&(sb.a)) + a(0)); |
| } |
| )"; |
| |
| auto* expect = R"( |
| struct SB { |
| a : atomic<i32>, |
| } |
| |
| @group(0) @binding(0) var<storage, read_write> sb : SB; |
| |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 0; |
| let tint_symbol : i32 = atomicLoad(&(sb.a)); |
| let tint_symbol_1 : i32 = a(0); |
| let r = (tint_symbol + tint_symbol_1); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_Vector_RightSE) { |
| auto* src = R"( |
| fn a() -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b : vec3<i32>; |
| var c : i32; |
| let r = b[c] + a(); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a() -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b : vec3<i32>; |
| var c : i32; |
| let tint_symbol : i32 = c; |
| let tint_symbol_1 : i32 = b[tint_symbol]; |
| let tint_symbol_2 : i32 = a(); |
| let r = (tint_symbol_1 + tint_symbol_2); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_InCall) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn g(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| let r = g(a(0)) - g(b + a(1)); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn g(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| let tint_symbol : i32 = a(0); |
| let tint_symbol_1 : i32 = g(tint_symbol); |
| let tint_symbol_2 : i32 = b; |
| let tint_symbol_3 : i32 = a(1); |
| let tint_symbol_4 : i32 = g((tint_symbol_2 + tint_symbol_3)); |
| let r = (tint_symbol_1 - tint_symbol_4); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_InTypeInit) { |
| auto* src = R"( |
| |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| let r = i32(a(0)) + i32(a(1) + b) - i32(a(2) - a(3)); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| let tint_symbol : i32 = a(0); |
| let tint_symbol_1 : i32 = i32(tint_symbol); |
| let tint_symbol_2 : i32 = a(1); |
| let tint_symbol_3 : i32 = i32((tint_symbol_2 + b)); |
| let tint_symbol_4 : i32 = a(2); |
| let tint_symbol_5 : i32 = a(3); |
| let tint_symbol_6 : i32 = i32((tint_symbol_4 - tint_symbol_5)); |
| let r = ((tint_symbol_1 + tint_symbol_3) - tint_symbol_6); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_InTypeConversion) { |
| auto* src = R"( |
| |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1u; |
| let r = u32(a(0)) + u32(a(1)) - b; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1u; |
| let tint_symbol : i32 = a(0); |
| let tint_symbol_1 : u32 = u32(tint_symbol); |
| let tint_symbol_2 : i32 = a(1); |
| let tint_symbol_3 : u32 = u32(tint_symbol_2); |
| let r = ((tint_symbol_1 + tint_symbol_3) - b); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_InIntrinsic) { |
| auto* src = R"( |
| |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| let r = abs(a(0)) + abs(a(1) + b) - abs(a(2) + a(3)); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| let tint_symbol : i32 = a(0); |
| let tint_symbol_1 : i32 = abs(tint_symbol); |
| let tint_symbol_2 : i32 = a(1); |
| let tint_symbol_3 : i32 = abs((tint_symbol_2 + b)); |
| let tint_symbol_4 : i32 = a(2); |
| let tint_symbol_5 : i32 = a(3); |
| let tint_symbol_6 : i32 = abs((tint_symbol_4 + tint_symbol_5)); |
| let r = ((tint_symbol_1 + tint_symbol_3) - tint_symbol_6); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_InMemberAccessor) { |
| auto* src = R"( |
| |
| struct S { |
| v : i32, |
| } |
| |
| fn a(i : i32) -> S { |
| return S(); |
| } |
| |
| fn f() { |
| var b = 1; |
| let r = a(0).v + b + a(1).v; |
| } |
| )"; |
| |
| auto* expect = R"( |
| struct S { |
| v : i32, |
| } |
| |
| fn a(i : i32) -> S { |
| return S(); |
| } |
| |
| fn f() { |
| var b = 1; |
| let tint_symbol : S = a(0); |
| let tint_symbol_1 : i32 = b; |
| let tint_symbol_2 : S = a(1); |
| let r = ((tint_symbol.v + tint_symbol_1) + tint_symbol_2.v); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_InUnary) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| let r = -a(0) + -(b + a(1)); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| let tint_symbol : i32 = -(a(0)); |
| let tint_symbol_1 : i32 = b; |
| let tint_symbol_2 : i32 = a(1); |
| let r = (tint_symbol + -((tint_symbol_1 + tint_symbol_2))); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_InBitcast) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| let r = bitcast<u32>(a(0) + a(1)); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| let tint_symbol : i32 = a(0); |
| let tint_symbol_1 : i32 = a(1); |
| let r = bitcast<u32>((tint_symbol + tint_symbol_1)); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_InForLoopInit) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| for(var r = a(0) + b; ; ) { |
| var marker = 0; |
| break; |
| } |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| { |
| let tint_symbol : i32 = a(0); |
| var r = (tint_symbol + b); |
| loop { |
| { |
| var marker = 0; |
| break; |
| } |
| } |
| } |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_InForLoopCond) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| for(; a(0) + b > 0;) { |
| var marker = 0; |
| } |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| loop { |
| let tint_symbol : i32 = a(0); |
| if (!(((tint_symbol + b) > 0))) { |
| break; |
| } |
| { |
| var marker = 0; |
| } |
| } |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_InForLoopCont) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| var r = 0; |
| for(; ; r = a(0) + b) { |
| var marker = 0; |
| break; |
| } |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| var r = 0; |
| loop { |
| { |
| var marker = 0; |
| break; |
| } |
| |
| continuing { |
| let tint_symbol : i32 = a(0); |
| r = (tint_symbol + b); |
| } |
| } |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_InForLoopInitCondCont) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| var c = 2; |
| var d = 3; |
| var r = 0; |
| for(var r = a(0) + b; a(1) + c > 0; r = a(2) + d) { |
| var marker = 0; |
| } |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| var c = 2; |
| var d = 3; |
| var r = 0; |
| { |
| let tint_symbol : i32 = a(0); |
| var r = (tint_symbol + b); |
| loop { |
| let tint_symbol_1 : i32 = a(1); |
| if (!(((tint_symbol_1 + c) > 0))) { |
| break; |
| } |
| { |
| var marker = 0; |
| } |
| |
| continuing { |
| let tint_symbol_2 : i32 = a(2); |
| r = (tint_symbol_2 + d); |
| } |
| } |
| } |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_InWhileCond) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| while(a(0) + b > 0) { |
| var marker = 0; |
| } |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| loop { |
| let tint_symbol : i32 = a(0); |
| if (!(((tint_symbol + b) > 0))) { |
| break; |
| } |
| { |
| var marker = 0; |
| } |
| } |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_InElseIf) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| if (true) { |
| var marker = 0; |
| } else if (a(0) + b > 0) { |
| var marker = 1; |
| } |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| if (true) { |
| var marker = 0; |
| } else { |
| let tint_symbol : i32 = a(0); |
| if (((tint_symbol + b) > 0)) { |
| var marker = 1; |
| } |
| } |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_InElseIfChain) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| if (true) { |
| var marker = 0; |
| } else if (true) { |
| var marker = 1; |
| } else if (a(0) + b > 0) { |
| var marker = 2; |
| } else if (a(1) + a(2) > 0) { |
| var marker = 3; |
| } else if (true) { |
| var marker = 4; |
| } else { |
| var marker = 5; |
| } |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| if (true) { |
| var marker = 0; |
| } else if (true) { |
| var marker = 1; |
| } else { |
| let tint_symbol : i32 = a(0); |
| if (((tint_symbol + b) > 0)) { |
| var marker = 2; |
| } else { |
| let tint_symbol_1 : i32 = a(1); |
| let tint_symbol_2 : i32 = a(2); |
| if (((tint_symbol_1 + tint_symbol_2) > 0)) { |
| var marker = 3; |
| } else if (true) { |
| var marker = 4; |
| } else { |
| var marker = 5; |
| } |
| } |
| } |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_InReturn) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() -> i32 { |
| var b = 1; |
| return b + a(0); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() -> i32 { |
| var b = 1; |
| let tint_symbol : i32 = b; |
| let tint_symbol_1 : i32 = a(0); |
| return (tint_symbol + tint_symbol_1); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Arith_InSwitch) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| switch (b + a(0)) { |
| default: { |
| } |
| } |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return i; |
| } |
| |
| fn f() { |
| var b = 1; |
| let tint_symbol : i32 = b; |
| let tint_symbol_1 : i32 = a(0); |
| switch((tint_symbol + tint_symbol_1)) { |
| default: { |
| } |
| } |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_LeftSE) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| let r = a(0) && b; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| var tint_symbol = a(0); |
| if (tint_symbol) { |
| tint_symbol = b; |
| } |
| let r = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_RightSE) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| let r = b && a(0); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| var tint_symbol = b; |
| if (tint_symbol) { |
| tint_symbol = a(0); |
| } |
| let r = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_BothSE) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| let r = a(0) && a(1); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var tint_symbol = a(0); |
| if (tint_symbol) { |
| tint_symbol = a(1); |
| } |
| let r = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_LeftmostSE) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| var c = true; |
| var d = true; |
| let r = a(0) && b && c && d; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| var c = true; |
| var d = true; |
| var tint_symbol_2 = a(0); |
| if (tint_symbol_2) { |
| tint_symbol_2 = b; |
| } |
| var tint_symbol_1 = tint_symbol_2; |
| if (tint_symbol_1) { |
| tint_symbol_1 = c; |
| } |
| var tint_symbol = tint_symbol_1; |
| if (tint_symbol) { |
| tint_symbol = d; |
| } |
| let r = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_RightmostSE) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| var c = true; |
| var d = true; |
| let r = b && c && d && a(0); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| var c = true; |
| var d = true; |
| var tint_symbol = ((b && c) && d); |
| if (tint_symbol) { |
| tint_symbol = a(0); |
| } |
| let r = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_MiddleSE) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| var c = true; |
| var d = true; |
| let r = b && c && a(0) && c && d; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| var c = true; |
| var d = true; |
| var tint_symbol_2 = (b && c); |
| if (tint_symbol_2) { |
| tint_symbol_2 = a(0); |
| } |
| var tint_symbol_1 = tint_symbol_2; |
| if (tint_symbol_1) { |
| tint_symbol_1 = c; |
| } |
| var tint_symbol = tint_symbol_1; |
| if (tint_symbol) { |
| tint_symbol = d; |
| } |
| let r = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_Constants_NoRecvSE) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| let r = true && a(0) && false && a(1); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var tint_symbol_2 = true; |
| if (tint_symbol_2) { |
| tint_symbol_2 = a(0); |
| } |
| var tint_symbol_1 = tint_symbol_2; |
| if (tint_symbol_1) { |
| tint_symbol_1 = false; |
| } |
| var tint_symbol = tint_symbol_1; |
| if (tint_symbol) { |
| tint_symbol = a(1); |
| } |
| let r = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_Constants_RecvSE) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| let r = b && true && a(0) && false && a(1); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| var tint_symbol_2 = (b && true); |
| if (tint_symbol_2) { |
| tint_symbol_2 = a(0); |
| } |
| var tint_symbol_1 = tint_symbol_2; |
| if (tint_symbol_1) { |
| tint_symbol_1 = false; |
| } |
| var tint_symbol = tint_symbol_1; |
| if (tint_symbol) { |
| tint_symbol = a(1); |
| } |
| let r = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_Constants_ConstAndSEAndVar) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn main() { |
| var b = true; |
| var c = true; |
| let r = true && a(0) && b; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn main() { |
| var b = true; |
| var c = true; |
| var tint_symbol_1 = true; |
| if (tint_symbol_1) { |
| tint_symbol_1 = a(0); |
| } |
| var tint_symbol = tint_symbol_1; |
| if (tint_symbol) { |
| tint_symbol = b; |
| } |
| let r = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_Constants_VarAndSEAndConst) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn main() { |
| var b = true; |
| let r = b && a(0) && true; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn main() { |
| var b = true; |
| var tint_symbol_1 = b; |
| if (tint_symbol_1) { |
| tint_symbol_1 = a(0); |
| } |
| var tint_symbol = tint_symbol_1; |
| if (tint_symbol) { |
| tint_symbol = true; |
| } |
| let r = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_Constants_SEAndVarAndConstAndVar) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn main() { |
| var b = true; |
| var c = true; |
| let r = a(0) && b && true && c; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn main() { |
| var b = true; |
| var c = true; |
| var tint_symbol_2 = a(0); |
| if (tint_symbol_2) { |
| tint_symbol_2 = b; |
| } |
| var tint_symbol_1 = tint_symbol_2; |
| if (tint_symbol_1) { |
| tint_symbol_1 = true; |
| } |
| var tint_symbol = tint_symbol_1; |
| if (tint_symbol) { |
| tint_symbol = c; |
| } |
| let r = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_MixedSE) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| var c = true; |
| var d = true; |
| let r = (b && a(0)) || (c && a(1) && c && d) || a(2); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| var c = true; |
| var d = true; |
| var tint_symbol_2 = b; |
| if (tint_symbol_2) { |
| tint_symbol_2 = a(0); |
| } |
| var tint_symbol_1 = tint_symbol_2; |
| if (!(tint_symbol_1)) { |
| var tint_symbol_5 = c; |
| if (tint_symbol_5) { |
| tint_symbol_5 = a(1); |
| } |
| var tint_symbol_4 = tint_symbol_5; |
| if (tint_symbol_4) { |
| tint_symbol_4 = c; |
| } |
| var tint_symbol_3 = tint_symbol_4; |
| if (tint_symbol_3) { |
| tint_symbol_3 = d; |
| } |
| tint_symbol_1 = tint_symbol_3; |
| } |
| var tint_symbol = tint_symbol_1; |
| if (!(tint_symbol)) { |
| tint_symbol = a(2); |
| } |
| let r = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_NestedAnds) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| let r = a(0) && (a(1) && (a(2) && (a(3) && (a(4) && a(5))))); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var tint_symbol = a(0); |
| if (tint_symbol) { |
| var tint_symbol_1 = a(1); |
| if (tint_symbol_1) { |
| var tint_symbol_2 = a(2); |
| if (tint_symbol_2) { |
| var tint_symbol_3 = a(3); |
| if (tint_symbol_3) { |
| var tint_symbol_4 = a(4); |
| if (tint_symbol_4) { |
| tint_symbol_4 = a(5); |
| } |
| tint_symbol_3 = tint_symbol_4; |
| } |
| tint_symbol_2 = tint_symbol_3; |
| } |
| tint_symbol_1 = tint_symbol_2; |
| } |
| tint_symbol = tint_symbol_1; |
| } |
| let r = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_NestedOrs) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| let r = a(0) || (a(1) || (a(2) || (a(3) || (a(4) || a(5))))); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var tint_symbol = a(0); |
| if (!(tint_symbol)) { |
| var tint_symbol_1 = a(1); |
| if (!(tint_symbol_1)) { |
| var tint_symbol_2 = a(2); |
| if (!(tint_symbol_2)) { |
| var tint_symbol_3 = a(3); |
| if (!(tint_symbol_3)) { |
| var tint_symbol_4 = a(4); |
| if (!(tint_symbol_4)) { |
| tint_symbol_4 = a(5); |
| } |
| tint_symbol_3 = tint_symbol_4; |
| } |
| tint_symbol_2 = tint_symbol_3; |
| } |
| tint_symbol_1 = tint_symbol_2; |
| } |
| tint_symbol = tint_symbol_1; |
| } |
| let r = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_MultipleStatements) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| let r1 = b && a(0); |
| let r2 = a(1) || b; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| var tint_symbol = b; |
| if (tint_symbol) { |
| tint_symbol = a(0); |
| } |
| let r1 = tint_symbol; |
| var tint_symbol_1 = a(1); |
| if (!(tint_symbol_1)) { |
| tint_symbol_1 = b; |
| } |
| let r2 = tint_symbol_1; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_InCall) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn g(v : bool) -> bool { |
| return v; |
| } |
| |
| fn f() { |
| var b = true; |
| g(b && a(1)); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn g(v : bool) -> bool { |
| return v; |
| } |
| |
| fn f() { |
| var b = true; |
| var tint_symbol = b; |
| if (tint_symbol) { |
| tint_symbol = a(1); |
| } |
| g(tint_symbol); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_InTypeInit) { |
| auto* src = R"( |
| |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| let r = (bool(a(0)) && bool(a(1) && b)) || bool(a(2) && a(3)); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| let tint_symbol_2 : bool = a(0); |
| var tint_symbol_1 = bool(tint_symbol_2); |
| if (tint_symbol_1) { |
| var tint_symbol_3 = a(1); |
| if (tint_symbol_3) { |
| tint_symbol_3 = b; |
| } |
| tint_symbol_1 = bool(tint_symbol_3); |
| } |
| var tint_symbol = tint_symbol_1; |
| if (!(tint_symbol)) { |
| var tint_symbol_4 = a(2); |
| if (tint_symbol_4) { |
| tint_symbol_4 = a(3); |
| } |
| tint_symbol = bool(tint_symbol_4); |
| } |
| let r = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_InTypeConversion) { |
| auto* src = R"( |
| |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = true; |
| let r = (bool(a(0)) && bool(a(1))) || b; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = true; |
| let tint_symbol_2 : i32 = a(0); |
| var tint_symbol_1 = bool(tint_symbol_2); |
| if (tint_symbol_1) { |
| let tint_symbol_3 : i32 = a(1); |
| tint_symbol_1 = bool(tint_symbol_3); |
| } |
| var tint_symbol = tint_symbol_1; |
| if (!(tint_symbol)) { |
| tint_symbol = b; |
| } |
| let r = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| // Make sure we process logical binary expressions of non-logical binary |
| // expressions. |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_OfNonLogical) { |
| auto* src = R"( |
| |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| let r = bool(a(0) == b) && bool(a(1) == b); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| let tint_symbol_1 : i32 = a(0); |
| var tint_symbol = bool((tint_symbol_1 == b)); |
| if (tint_symbol) { |
| let tint_symbol_2 : i32 = a(1); |
| tint_symbol = bool((tint_symbol_2 == b)); |
| } |
| let r = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_InIntrinsic) { |
| auto* src = R"( |
| |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| let r = (all(a(0)) && all(a(1) && b)) || all(a(2) && a(3)); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| let tint_symbol_2 : bool = a(0); |
| var tint_symbol_1 = all(tint_symbol_2); |
| if (tint_symbol_1) { |
| var tint_symbol_3 = a(1); |
| if (tint_symbol_3) { |
| tint_symbol_3 = b; |
| } |
| tint_symbol_1 = all(tint_symbol_3); |
| } |
| var tint_symbol = tint_symbol_1; |
| if (!(tint_symbol)) { |
| var tint_symbol_4 = a(2); |
| if (tint_symbol_4) { |
| tint_symbol_4 = a(3); |
| } |
| tint_symbol = all(tint_symbol_4); |
| } |
| let r = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_InMemberAccessor) { |
| auto* src = R"( |
| |
| struct S { |
| v : bool, |
| } |
| |
| fn a(i : i32) -> S { |
| return S(); |
| } |
| |
| fn f() { |
| var b = true; |
| let r = a(0).v && b && a(1).v; |
| } |
| )"; |
| |
| auto* expect = R"( |
| struct S { |
| v : bool, |
| } |
| |
| fn a(i : i32) -> S { |
| return S(); |
| } |
| |
| fn f() { |
| var b = true; |
| let tint_symbol_2 : S = a(0); |
| var tint_symbol_1 = tint_symbol_2.v; |
| if (tint_symbol_1) { |
| tint_symbol_1 = b; |
| } |
| var tint_symbol = tint_symbol_1; |
| if (tint_symbol) { |
| let tint_symbol_3 : S = a(1); |
| tint_symbol = tint_symbol_3.v; |
| } |
| let r = tint_symbol; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_InUnary) { |
| auto* src = R"( |
| |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| let r = !(b || a(1)); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| var tint_symbol = b; |
| if (!(tint_symbol)) { |
| tint_symbol = a(1); |
| } |
| let r = !(tint_symbol); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_InBitcast) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| let r = bitcast<u32>(i32(a(0) && a(1))); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| var tint_symbol = a(0); |
| if (tint_symbol) { |
| tint_symbol = a(1); |
| } |
| let tint_symbol_1 : i32 = i32(tint_symbol); |
| let r = bitcast<u32>(tint_symbol_1); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_InForLoopInit) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| for(var r = a(0) && b; ; ) { |
| var marker = 0; |
| break; |
| } |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| { |
| var tint_symbol = a(0); |
| if (tint_symbol) { |
| tint_symbol = b; |
| } |
| var r = tint_symbol; |
| loop { |
| { |
| var marker = 0; |
| break; |
| } |
| } |
| } |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_InForLoopCond) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| for(; a(0) && b;) { |
| var marker = 0; |
| } |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| loop { |
| var tint_symbol = a(0); |
| if (tint_symbol) { |
| tint_symbol = b; |
| } |
| if (!(tint_symbol)) { |
| break; |
| } |
| { |
| var marker = 0; |
| } |
| } |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_InForLoopCont) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| var r = true; |
| for(; ; r = a(0) && b) { |
| var marker = 0; |
| break; |
| } |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| var r = true; |
| loop { |
| { |
| var marker = 0; |
| break; |
| } |
| |
| continuing { |
| var tint_symbol = a(0); |
| if (tint_symbol) { |
| tint_symbol = b; |
| } |
| r = tint_symbol; |
| } |
| } |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_InForLoopInitCondCont) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| var c = true; |
| var d = true; |
| var r = true; |
| for(var r = a(0) && b; a(1) && c; r = a(2) && d) { |
| var marker = 0; |
| } |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| var c = true; |
| var d = true; |
| var r = true; |
| { |
| var tint_symbol = a(0); |
| if (tint_symbol) { |
| tint_symbol = b; |
| } |
| var r = tint_symbol; |
| loop { |
| var tint_symbol_1 = a(1); |
| if (tint_symbol_1) { |
| tint_symbol_1 = c; |
| } |
| if (!(tint_symbol_1)) { |
| break; |
| } |
| { |
| var marker = 0; |
| } |
| |
| continuing { |
| var tint_symbol_2 = a(2); |
| if (tint_symbol_2) { |
| tint_symbol_2 = d; |
| } |
| r = tint_symbol_2; |
| } |
| } |
| } |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_InWhileCond) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| while(a(0) && b) { |
| var marker = 0; |
| } |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| loop { |
| var tint_symbol = a(0); |
| if (tint_symbol) { |
| tint_symbol = b; |
| } |
| if (!(tint_symbol)) { |
| break; |
| } |
| { |
| var marker = 0; |
| } |
| } |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_InElseIf) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| if (true) { |
| var marker = 0; |
| } else if (a(0) && b) { |
| var marker = 1; |
| } |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| if (true) { |
| var marker = 0; |
| } else { |
| var tint_symbol = a(0); |
| if (tint_symbol) { |
| tint_symbol = b; |
| } |
| if (tint_symbol) { |
| var marker = 1; |
| } |
| } |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Binary_Logical_InElseIfChain) { |
| auto* src = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| if (true) { |
| var marker = 0; |
| } else if (true) { |
| var marker = 1; |
| } else if (a(0) && b) { |
| var marker = 2; |
| } else if (a(1) && a(2)) { |
| var marker = 3; |
| } else if (true) { |
| var marker = 4; |
| } else { |
| var marker = 5; |
| } |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> bool { |
| return true; |
| } |
| |
| fn f() { |
| var b = true; |
| if (true) { |
| var marker = 0; |
| } else if (true) { |
| var marker = 1; |
| } else { |
| var tint_symbol = a(0); |
| if (tint_symbol) { |
| tint_symbol = b; |
| } |
| if (tint_symbol) { |
| var marker = 2; |
| } else { |
| var tint_symbol_1 = a(1); |
| if (tint_symbol_1) { |
| tint_symbol_1 = a(2); |
| } |
| if (tint_symbol_1) { |
| var marker = 3; |
| } else if (true) { |
| var marker = 4; |
| } else { |
| var marker = 5; |
| } |
| } |
| } |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Call_NoSE) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn g(a : i32, b : i32, c : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| var c = 1; |
| let r = g(b, c, 3); |
| } |
| )"; |
| |
| auto* expect = src; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Call_OneSE) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn g(a : i32, b : i32, c : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| let r = g(a(0), b, 3); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn g(a : i32, b : i32, c : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| let tint_symbol : i32 = a(0); |
| let r = g(tint_symbol, b, 3); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Call_AllSE) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn g(a : i32, b : i32, c : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| let r = g(a(0), a(1), a(2)); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn g(a : i32, b : i32, c : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| let tint_symbol : i32 = a(0); |
| let tint_symbol_1 : i32 = a(1); |
| let tint_symbol_2 : i32 = a(2); |
| let r = g(tint_symbol, tint_symbol_1, tint_symbol_2); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Call_MiddleNotSE) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn g(a : i32, b : i32, c : i32) -> i32 { |
| return 1; |
| } |
| |
| |
| fn f() { |
| var b = 1; |
| let r = g(a(0), b, a(1)); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn g(a : i32, b : i32, c : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 1; |
| let tint_symbol : i32 = a(0); |
| let tint_symbol_1 : i32 = b; |
| let tint_symbol_2 : i32 = a(1); |
| let r = g(tint_symbol, tint_symbol_1, tint_symbol_2); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Call_InBinary) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn g(i : i32, j : i32, k : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 0; |
| var c = 0; |
| var d = 0; |
| let r = b + g(c, a(0), d) + a(1); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn g(i : i32, j : i32, k : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = 0; |
| var c = 0; |
| var d = 0; |
| let tint_symbol : i32 = b; |
| let tint_symbol_1 : i32 = c; |
| let tint_symbol_2 : i32 = a(0); |
| let tint_symbol_3 : i32 = g(tint_symbol_1, tint_symbol_2, d); |
| let tint_symbol_4 : i32 = a(1); |
| let r = ((tint_symbol + tint_symbol_3) + tint_symbol_4); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, IndexAccessor_2D_LeftSE) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<array<i32, 10>, 10>(); |
| var c = 1; |
| var r = b[a(0)][c]; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<array<i32, 10>, 10>(); |
| var c = 1; |
| let tint_symbol : i32 = a(0); |
| var r = b[tint_symbol][c]; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, IndexAccessor_2D_RightSE) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<array<i32, 10>, 10>(); |
| var c = 1; |
| let tint_symbol = c; |
| let tint_symbol_1 = a(0); |
| var r = b[tint_symbol][tint_symbol_1]; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<array<i32, 10>, 10>(); |
| var c = 1; |
| let tint_symbol = c; |
| let tint_symbol_1 = a(0); |
| var r = b[tint_symbol][tint_symbol_1]; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, IndexAccessor_2D_BothSE) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<array<i32, 10>, 10>(); |
| var r = b[a(0)][a(1)]; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<array<i32, 10>, 10>(); |
| let tint_symbol : i32 = a(0); |
| let tint_symbol_1 : i32 = a(1); |
| var r = b[tint_symbol][tint_symbol_1]; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, IndexAccessor_2D_LeftSE_ViaPointerIndex) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<array<i32, 10>, 10>(); |
| let p = &b; |
| var c = 1; |
| var r = p[a(0)][c]; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<array<i32, 10>, 10>(); |
| let p = &(b); |
| var c = 1; |
| let tint_symbol : i32 = a(0); |
| var r = p[tint_symbol][c]; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, IndexAccessor_2D_RightSE_ViaPointerIndex) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<array<i32, 10>, 10>(); |
| let p = &b; |
| var c = 1; |
| let tint_symbol = c; |
| let tint_symbol_1 = a(0); |
| var r = p[tint_symbol][tint_symbol_1]; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<array<i32, 10>, 10>(); |
| let p = &(b); |
| var c = 1; |
| let tint_symbol = c; |
| let tint_symbol_1 = a(0); |
| var r = p[tint_symbol][tint_symbol_1]; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, IndexAccessor_2D_BothSE_ViaPointerIndex) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<array<i32, 10>, 10>(); |
| let p = &b; |
| var r = p[a(0)][a(1)]; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<array<i32, 10>, 10>(); |
| let p = &(b); |
| let tint_symbol : i32 = a(0); |
| let tint_symbol_1 : i32 = a(1); |
| var r = p[tint_symbol][tint_symbol_1]; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Assignment_ToPhony) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| _ = a(0); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| _ = a(0); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Assignment_ToArray1D) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<i32, 10>(); |
| b[a(0)] = a(1); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<i32, 10>(); |
| let tint_symbol : i32 = a(0); |
| b[tint_symbol] = a(1); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Assignment_ToArray2D) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<array<i32, 10>, 10>(); |
| b[a(0)][a(1)] = a(2); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<array<i32, 10>, 10>(); |
| let tint_symbol : i32 = a(0); |
| let tint_symbol_1 : i32 = a(1); |
| b[tint_symbol][tint_symbol_1] = a(2); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Assignment_ToArray3D) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<array<array<i32, 10>, 10>, 10>(); |
| b[a(0)][a(1)][a(2)] = a(3); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<array<array<i32, 10>, 10>, 10>(); |
| let tint_symbol : i32 = a(0); |
| let tint_symbol_1 : i32 = a(1); |
| let tint_symbol_2 : i32 = a(2); |
| b[tint_symbol][tint_symbol_1][tint_symbol_2] = a(3); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Assignment_ToArray_FromArray) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<i32, 3>(); |
| var d = array<array<i32, 3>, 3>(); |
| var a_1 = 0; |
| b[a(2)] = d[a(0)][a_1]; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = array<i32, 3>(); |
| var d = array<array<i32, 3>, 3>(); |
| var a_1 = 0; |
| let tint_symbol : i32 = a(2); |
| let tint_symbol_1 : i32 = a(0); |
| b[tint_symbol] = d[tint_symbol_1][a_1]; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Assignment_ToVec_BothSE) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = vec3<i32>(); |
| b[a(0)] = a(1); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = vec3<i32>(); |
| let tint_symbol : i32 = a(0); |
| b[tint_symbol] = a(1); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Assignment_ToVec_LeftSE) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = vec3<i32>(); |
| var c = 0; |
| b[a(0)] = c; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = vec3<i32>(); |
| var c = 0; |
| let tint_symbol : i32 = a(0); |
| b[tint_symbol] = c; |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, Assignment_ToVec_RightSE) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = vec3<i32>(); |
| var c = 0; |
| b[c] = a(0); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var b = vec3<i32>(); |
| var c = 0; |
| let tint_symbol : i32 = c; |
| b[tint_symbol] = a(0); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, TypeInitializer_Struct) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| struct S { |
| x : i32, |
| y : i32, |
| z : i32, |
| } |
| |
| fn f() { |
| var r = S(a(0), a(1), a(2)); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| struct S { |
| x : i32, |
| y : i32, |
| z : i32, |
| } |
| |
| fn f() { |
| let tint_symbol : i32 = a(0); |
| let tint_symbol_1 : i32 = a(1); |
| let tint_symbol_2 : i32 = a(2); |
| var r = S(tint_symbol, tint_symbol_1, tint_symbol_2); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, TypeInitializer_Array1D) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var r = array<i32, 3>(a(0), a(1), a(2)); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| let tint_symbol : i32 = a(0); |
| let tint_symbol_1 : i32 = a(1); |
| let tint_symbol_2 : i32 = a(2); |
| var r = array<i32, 3>(tint_symbol, tint_symbol_1, tint_symbol_2); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, TypeInitializer_Array2D) { |
| auto* src = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| var r = array<array<i32, 2>, 2>(array<i32, 2>(a(0), a(1)), array<i32, 2>(a(2), a(3))); |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> i32 { |
| return 1; |
| } |
| |
| fn f() { |
| let tint_symbol : i32 = a(0); |
| let tint_symbol_1 : i32 = a(1); |
| let tint_symbol_2 : array<i32, 2u> = array<i32, 2>(tint_symbol, tint_symbol_1); |
| let tint_symbol_3 : i32 = a(2); |
| let tint_symbol_4 : i32 = a(3); |
| let tint_symbol_5 : array<i32, 2u> = array<i32, 2>(tint_symbol_3, tint_symbol_4); |
| var r = array<array<i32, 2>, 2>(tint_symbol_2, tint_symbol_5); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, MemberAccessor_Vec) { |
| auto* src = R"( |
| fn a(i : i32) -> vec3<i32> { |
| return vec3<i32>(); |
| } |
| |
| fn f() { |
| var r = a(0).x + a(1).y; |
| } |
| )"; |
| |
| auto* expect = R"( |
| fn a(i : i32) -> vec3<i32> { |
| return vec3<i32>(); |
| } |
| |
| fn f() { |
| let tint_symbol : vec3<i32> = a(0); |
| let tint_symbol_1 : vec3<i32> = a(1); |
| var r = (tint_symbol.x + tint_symbol_1.y); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, MemberAccessor_Struct) { |
| auto* src = R"( |
| struct S { |
| x : i32, |
| y : i32, |
| } |
| |
| fn a(i : i32) -> S { |
| return S(); |
| } |
| |
| fn f() { |
| var r = a(0).x + a(1).y; |
| } |
| )"; |
| |
| auto* expect = R"( |
| struct S { |
| x : i32, |
| y : i32, |
| } |
| |
| fn a(i : i32) -> S { |
| return S(); |
| } |
| |
| fn f() { |
| let tint_symbol : S = a(0); |
| let tint_symbol_1 : S = a(1); |
| var r = (tint_symbol.x + tint_symbol_1.y); |
| } |
| )"; |
| |
| auto got = Run<PromoteSideEffectsToDecl>(src); |
| |
| EXPECT_EQ(expect, str(got)); |
| } |
| |
| TEST_F(PromoteSideEffectsToDeclTest, MemberAccessor_Struct_Mixed) { |
| auto* src = R"( |
| struct S { |
| x : i32, |
| y : i32, |
| arr : array<i32, 10>, |
| } |
| |
| fn a(i : i32) -> S { |
| return S(); |
| } |
| |
| fn b(i : i32) -> i32 { |
|