glsl: Implement compound assignment

Use the ExpandCompoundAssignment transform to convert compound
assignments to regular assignments.

Bug: tint:1325
Change-Id: I0567131aa7c6b4beb6e25c0c6c559795e9c58c19
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/85286
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
James Price 2022-03-31 22:30:10 +00:00
parent 16eeff387c
commit 0e1f57cbc2
33 changed files with 455 additions and 347 deletions

View File

@ -24,6 +24,7 @@
#include "src/tint/transform/canonicalize_entry_point_io.h" #include "src/tint/transform/canonicalize_entry_point_io.h"
#include "src/tint/transform/combine_samplers.h" #include "src/tint/transform/combine_samplers.h"
#include "src/tint/transform/decompose_memory_access.h" #include "src/tint/transform/decompose_memory_access.h"
#include "src/tint/transform/expand_compound_assignment.h"
#include "src/tint/transform/fold_trivial_single_use_lets.h" #include "src/tint/transform/fold_trivial_single_use_lets.h"
#include "src/tint/transform/loop_to_for_loop.h" #include "src/tint/transform/loop_to_for_loop.h"
#include "src/tint/transform/manager.h" #include "src/tint/transform/manager.h"
@ -84,6 +85,7 @@ Output Glsl::Run(const Program* in, const DataMap& inputs) const {
manager.Add<ZeroInitWorkgroupMemory>(); manager.Add<ZeroInitWorkgroupMemory>();
} }
manager.Add<CanonicalizeEntryPointIO>(); manager.Add<CanonicalizeEntryPointIO>();
manager.Add<ExpandCompoundAssignment>();
manager.Add<PromoteSideEffectsToDecl>(); manager.Add<PromoteSideEffectsToDecl>();
manager.Add<UnwindDiscardFunctions>(); manager.Add<UnwindDiscardFunctions>();
manager.Add<SimplifyPointers>(); manager.Add<SimplifyPointers>();

View File

@ -1,26 +1,29 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : array<vec4<i32>, 4>, ivec4 a[4];
} };
var<private> counter : i32; int counter = 0;
int foo() {
fn foo() -> i32 { counter = (counter + 1);
counter += 1;
return counter; return counter;
} }
fn bar() -> i32 { int bar() {
counter += 2; counter = (counter + 2);
return counter; return counter;
} }
fn main() { void tint_symbol() {
var x = S(); S x = S(ivec4[4](ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0)));
let p = &(x); int tint_symbol_3 = foo();
(*(p)).a[foo()][bar()] += 5; int tint_symbol_1_save = tint_symbol_3;
int tint_symbol_2 = bar();
x.a[tint_symbol_1_save][tint_symbol_2] = (x.a[tint_symbol_1_save][tint_symbol_2] + 5);
} }
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,19 +1,24 @@
SKIP: FAILED #version 310 es
float tint_float_modulo(float lhs, float rhs) {
var<private> a : i32; return (lhs - rhs * trunc(lhs / rhs));
}
var<private> b : f32;
fn foo(maybe_zero : i32) { layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
a /= 0; void unused_entry_point() {
a %= 0; return;
a /= maybe_zero; }
a %= maybe_zero; int a = 0;
b /= 0.0; float b = 0.0f;
b %= 0.0; void foo(int maybe_zero) {
b /= f32(maybe_zero); a = (a / 0);
b %= f32(maybe_zero); a = (a % 0);
a = (a / maybe_zero);
a = (a % maybe_zero);
b = (b / 0.0f);
b = tint_float_modulo(b, 0.0f);
b = (b / float(maybe_zero));
b = tint_float_modulo(b, float(maybe_zero));
} }
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,35 +1,55 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : i32, int a;
b : vec4<f32>, vec4 b;
c : mat2x2<f32>, mat2 c;
} };
@group(0) @binding(0) var<storage, read_write> v : S; layout(binding = 0, std430) buffer S_1 {
int a;
var<private> i : u32; vec4 b;
mat2 c;
fn idx1() -> i32 { } v;
i += 1u; uint i = 0u;
int idx1() {
i = (i + 1u);
return 1; return 1;
} }
fn idx2() -> i32 { int idx2() {
i += 2u; i = (i + 2u);
return 1; return 1;
} }
fn idx3() -> i32 { int idx3() {
i += 3u; i = (i + 3u);
return 1; return 1;
} }
fn foo() { void foo() {
var a = array<f32, 4>(); float a[4] = float[4](0.0f, 0.0f, 0.0f, 0.0f);
for(a[idx1()] *= 2.0; (a[idx2()] < 10.0); a[idx3()] += 1.0) { int tint_symbol_2 = idx1();
int tint_symbol_save = tint_symbol_2;
{
a[tint_symbol_save] = (a[tint_symbol_save] * 2.0f);
while (true) {
int tint_symbol_3 = idx2();
if (!((a[tint_symbol_3] < 10.0f))) {
break;
}
{
}
{
int tint_symbol_4 = idx3();
int tint_symbol_1_save = tint_symbol_4;
a[tint_symbol_1_save] = (a[tint_symbol_1_save] + 1.0f);
}
}
} }
} }
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,13 +1,15 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
fn foo() { void unused_entry_point() {
var<function> a : i32; return;
var<function> b : vec4<f32>; }
var<function> c : mat2x2<f32>; void foo() {
a /= 2; int a = 0;
b *= mat4x4<f32>(); vec4 b = vec4(0.0f, 0.0f, 0.0f, 0.0f);
c *= 2.0; mat2 c = mat2(0.0f, 0.0f, 0.0f, 0.0f);
a = (a / 2);
b = (b * mat4(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
c = (c * 2.0f);
} }
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : mat4x4<f32>, mat4 a;
};
layout(binding = 0, std430) buffer S_1 {
mat4 a;
} v;
void foo() {
v.a = (v.a - mat4(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a -= mat4x4<f32>();
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : mat4x4<f32>, mat4 a;
};
layout(binding = 0, std430) buffer S_1 {
mat4 a;
} v;
void foo() {
v.a = (v.a + mat4(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a += mat4x4<f32>();
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : mat4x4<f32>, mat4 a;
};
layout(binding = 0, std430) buffer S_1 {
mat4 a;
} v;
void foo() {
v.a = (v.a * 2.0f);
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a *= 2.0;
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : mat4x4<f32>, mat4 a;
};
layout(binding = 0, std430) buffer S_1 {
mat4 a;
} v;
void foo() {
v.a = (v.a * mat4(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a *= mat4x4<f32>();
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,16 +1,15 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
var<private> a : i32; void unused_entry_point() {
return;
var<private> b : vec4<f32>; }
int a = 0;
var<private> c : mat2x2<f32>; vec4 b = vec4(0.0f, 0.0f, 0.0f, 0.0f);
mat2 c = mat2(0.0f, 0.0f, 0.0f, 0.0f);
fn foo() { void foo() {
a /= 2; a = (a / 2);
b *= mat4x4<f32>(); b = (b * mat4(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
c *= 2.0; c = (c * 2.0f);
} }
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : i32, int a;
};
layout(binding = 0, std430) buffer S_1 {
int a;
} v;
void foo() {
v.a = (v.a & 2);
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a &= 2;
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : i32, int a;
};
layout(binding = 0, std430) buffer S_1 {
int a;
} v;
void foo() {
v.a = (v.a / 2);
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a /= 2;
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : i32, int a;
};
layout(binding = 0, std430) buffer S_1 {
int a;
} v;
void foo() {
v.a = (v.a - 2);
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a -= 2;
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : i32, int a;
};
layout(binding = 0, std430) buffer S_1 {
int a;
} v;
void foo() {
v.a = (v.a % 2);
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a %= 2;
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : i32, int a;
};
layout(binding = 0, std430) buffer S_1 {
int a;
} v;
void foo() {
v.a = (v.a | 2);
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a |= 2;
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : i32, int a;
};
layout(binding = 0, std430) buffer S_1 {
int a;
} v;
void foo() {
v.a = (v.a + 2);
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a += 2;
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : i32, int a;
};
layout(binding = 0, std430) buffer S_1 {
int a;
} v;
void foo() {
v.a = (v.a * 2);
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a *= 2;
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : i32, int a;
};
layout(binding = 0, std430) buffer S_1 {
int a;
} v;
void foo() {
v.a = (v.a ^ 2);
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a ^= 2;
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : vec4<i32>, ivec4 a;
};
layout(binding = 0, std430) buffer S_1 {
ivec4 a;
} v;
void foo() {
v.a = (v.a & ivec4(2));
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a &= vec4<i32>(2);
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : vec4<f32>, vec4 a;
};
layout(binding = 0, std430) buffer S_1 {
vec4 a;
} v;
void foo() {
v.a = (v.a / 2.0f);
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a /= 2.0;
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : vec4<i32>, ivec4 a;
};
layout(binding = 0, std430) buffer S_1 {
ivec4 a;
} v;
void foo() {
v.a = (v.a / ivec4(2));
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a /= vec4<i32>(2);
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : vec4<f32>, vec4 a;
};
layout(binding = 0, std430) buffer S_1 {
vec4 a;
} v;
void foo() {
v.a = (v.a - 2.0f);
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a -= 2.0;
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : vec4<i32>, ivec4 a;
};
layout(binding = 0, std430) buffer S_1 {
ivec4 a;
} v;
void foo() {
v.a = (v.a - ivec4(2));
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a -= vec4<i32>(2);
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : vec4<i32>, ivec4 a;
};
layout(binding = 0, std430) buffer S_1 {
ivec4 a;
} v;
void foo() {
v.a = (v.a % 2);
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a %= 2;
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : vec4<i32>, ivec4 a;
};
layout(binding = 0, std430) buffer S_1 {
ivec4 a;
} v;
void foo() {
v.a = (v.a % ivec4(2));
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a %= vec4<i32>(2);
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : vec4<i32>, ivec4 a;
};
layout(binding = 0, std430) buffer S_1 {
ivec4 a;
} v;
void foo() {
v.a = (v.a | ivec4(2));
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a |= vec4<i32>(2);
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : vec4<f32>, vec4 a;
};
layout(binding = 0, std430) buffer S_1 {
vec4 a;
} v;
void foo() {
v.a = (v.a + 2.0f);
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a += 2.0;
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : vec4<i32>, ivec4 a;
};
layout(binding = 0, std430) buffer S_1 {
ivec4 a;
} v;
void foo() {
v.a = (v.a + ivec4(2));
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a += vec4<i32>(2);
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : vec4<f32>, vec4 a;
};
layout(binding = 0, std430) buffer S_1 {
vec4 a;
} v;
void foo() {
v.a = (v.a * mat4(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a *= mat4x4<f32>();
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : vec4<f32>, vec4 a;
};
layout(binding = 0, std430) buffer S_1 {
vec4 a;
} v;
void foo() {
v.a = (v.a * 2.0f);
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a *= 2.0;
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : vec4<i32>, ivec4 a;
};
layout(binding = 0, std430) buffer S_1 {
ivec4 a;
} v;
void foo() {
v.a = (v.a * ivec4(2));
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a *= vec4<i32>(2);
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,14 +1,17 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
struct S { struct S {
a : vec4<i32>, ivec4 a;
};
layout(binding = 0, std430) buffer S_1 {
ivec4 a;
} v;
void foo() {
v.a = (v.a ^ ivec4(2));
} }
@group(0) @binding(0) var<storage, read_write> v : S;
fn foo() {
v.a ^= vec4<i32>(2);
}
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement

View File

@ -1,16 +1,15 @@
SKIP: FAILED #version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
var<workgroup> a : i32; void unused_entry_point() {
return;
var<workgroup> b : vec4<f32>; }
shared int a;
var<workgroup> c : mat2x2<f32>; shared vec4 b;
shared mat2 c;
fn foo() { void foo() {
a /= 2; a = (a / 2);
b *= mat4x4<f32>(); b = (b * mat4(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
c *= 2.0; c = (c * 2.0f);
} }
Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement