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/combine_samplers.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/loop_to_for_loop.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<CanonicalizeEntryPointIO>();
manager.Add<ExpandCompoundAssignment>();
manager.Add<PromoteSideEffectsToDecl>();
manager.Add<UnwindDiscardFunctions>();
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 {
a : array<vec4<i32>, 4>,
}
ivec4 a[4];
};
var<private> counter : i32;
fn foo() -> i32 {
counter += 1;
int counter = 0;
int foo() {
counter = (counter + 1);
return counter;
}
fn bar() -> i32 {
counter += 2;
int bar() {
counter = (counter + 2);
return counter;
}
fn main() {
var x = S();
let p = &(x);
(*(p)).a[foo()][bar()] += 5;
void tint_symbol() {
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)));
int tint_symbol_3 = foo();
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
var<private> a : i32;
var<private> b : f32;
fn foo(maybe_zero : i32) {
a /= 0;
a %= 0;
a /= maybe_zero;
a %= maybe_zero;
b /= 0.0;
b %= 0.0;
b /= f32(maybe_zero);
b %= f32(maybe_zero);
float tint_float_modulo(float lhs, float rhs) {
return (lhs - rhs * trunc(lhs / rhs));
}
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
int a = 0;
float b = 0.0f;
void foo(int maybe_zero) {
a = (a / 0);
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 {
a : i32,
b : vec4<f32>,
c : mat2x2<f32>,
}
int a;
vec4 b;
mat2 c;
};
@group(0) @binding(0) var<storage, read_write> v : S;
var<private> i : u32;
fn idx1() -> i32 {
i += 1u;
layout(binding = 0, std430) buffer S_1 {
int a;
vec4 b;
mat2 c;
} v;
uint i = 0u;
int idx1() {
i = (i + 1u);
return 1;
}
fn idx2() -> i32 {
i += 2u;
int idx2() {
i = (i + 2u);
return 1;
}
fn idx3() -> i32 {
i += 3u;
int idx3() {
i = (i + 3u);
return 1;
}
fn foo() {
var a = array<f32, 4>();
for(a[idx1()] *= 2.0; (a[idx2()] < 10.0); a[idx3()] += 1.0) {
void foo() {
float a[4] = float[4](0.0f, 0.0f, 0.0f, 0.0f);
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
fn foo() {
var<function> a : i32;
var<function> b : vec4<f32>;
var<function> c : mat2x2<f32>;
a /= 2;
b *= mat4x4<f32>();
c *= 2.0;
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
void foo() {
int a = 0;
vec4 b = vec4(0.0f, 0.0f, 0.0f, 0.0f);
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 {
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 {
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 {
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 {
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
var<private> a : i32;
var<private> b : vec4<f32>;
var<private> c : mat2x2<f32>;
fn foo() {
a /= 2;
b *= mat4x4<f32>();
c *= 2.0;
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
int a = 0;
vec4 b = vec4(0.0f, 0.0f, 0.0f, 0.0f);
mat2 c = mat2(0.0f, 0.0f, 0.0f, 0.0f);
void foo() {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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
var<workgroup> a : i32;
var<workgroup> b : vec4<f32>;
var<workgroup> c : mat2x2<f32>;
fn foo() {
a /= 2;
b *= mat4x4<f32>();
c *= 2.0;
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
shared int a;
shared vec4 b;
shared mat2 c;
void foo() {
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