Validate scalar constructor and implement conversion to vecN<bool> in spir-v backend

After implementing validation and fairly exhaustive tests, discovered
that conversion of scalar vector to bool vector did not work in the
spir-v backend. For module scope variables, we use and rely on the
FoldConstants transform to ensure no conversion needs to take place.
This is necessary because we cannot easily introduce temporary values
and refer to them when casting at module scope. Note that for the same
reason, module-level conversions are always constant foldable, so this
works. For function-level conversions, implemented support to emit a
comparison against a zero value, and store the result in the bool
vector.

Bug: tint:865
Change-Id: I0528045e803f176e03428bc7eac31ae06920bbd7
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/54744
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
Antonio Maiorano
2021-06-18 15:32:21 +00:00
committed by Tint LUCI CQ
parent 0507273047
commit adbbd0ba66
19 changed files with 851 additions and 56 deletions

View File

@@ -0,0 +1,31 @@
fn constant_with_non_constant() {
var a : f32 = f32();
var b : vec2<f32> = vec2<f32>(f32(i32(1)), a);
}
[[stage(compute)]]
fn main() {
var bool_var1 : bool = bool(123u);
var bool_var2 : bool = bool(123);
var bool_var3 : bool = bool(123.0);
var i32_var1 : i32 = i32(123u);
var i32_var2 : i32 = i32(123.0);
var u32_var1 : u32 = u32(123);
var u32_var2 : u32 = u32(123.0);
var v3bool_var1 : vec3<bool> = vec3<bool>(vec3<u32>(123u));
var v3bool_var11 : vec3<bool> = vec3<bool>(vec3<u32>(1234u));
var v3bool_var2 : vec3<bool> = vec3<bool>(vec3<i32>(123));
var v3bool_var3 : vec3<bool> = vec3<bool>(vec3<f32>(123.0));
var v3i32_var1 : vec3<i32> = vec3<i32>(vec3<u32>(123u));
var v3i32_var2 : vec3<i32> = vec3<i32>(vec3<f32>(123.0));
var v3u32_var1 : vec3<u32> = vec3<u32>(vec3<i32>(123));
var v3u32_var2 : vec3<u32> = vec3<u32>(vec3<f32>(123.0));
var v3bool_var4 : vec3<bool> = vec3<bool>(vec2<bool>(vec2<f32>(123.0)), true);
var v4bool_var5 : vec4<bool> = vec4<bool>(vec2<bool>(vec2<f32>(123.0, 0.0)), vec2<bool>(true, bool(f32(0.0))));
}

View File

@@ -0,0 +1,26 @@
void constant_with_non_constant() {
float a = 0.0f;
float2 b = float2(float(int(1)), a);
}
[numthreads(1, 1, 1)]
void main() {
bool bool_var1 = bool(123u);
bool bool_var2 = bool(123);
bool bool_var3 = bool(123.0f);
int i32_var1 = int(123u);
int i32_var2 = int(123.0f);
uint u32_var1 = uint(123);
uint u32_var2 = uint(123.0f);
bool3 v3bool_var1 = bool3(uint3((123u).xxx));
bool3 v3bool_var11 = bool3(uint3((1234u).xxx));
bool3 v3bool_var2 = bool3(int3((123).xxx));
bool3 v3bool_var3 = bool3(float3((123.0f).xxx));
int3 v3i32_var1 = int3(uint3((123u).xxx));
int3 v3i32_var2 = int3(float3((123.0f).xxx));
uint3 v3u32_var1 = uint3(int3((123).xxx));
uint3 v3u32_var2 = uint3(float3((123.0f).xxx));
bool3 v3bool_var4 = bool3(bool2(float2((123.0f).xx)), true);
bool4 v4bool_var5 = bool4(bool2(float2(123.0f, 0.0f)), bool2(true, bool(float(0.0f))));
return;
}

View File

@@ -0,0 +1,29 @@
#include <metal_stdlib>
using namespace metal;
void constant_with_non_constant() {
float a = float();
float2 b = float2(float(int(1)), a);
}
kernel void tint_symbol() {
bool bool_var1 = bool(123u);
bool bool_var2 = bool(123);
bool bool_var3 = bool(123.0f);
int i32_var1 = int(123u);
int i32_var2 = int(123.0f);
uint u32_var1 = uint(123);
uint u32_var2 = uint(123.0f);
bool3 v3bool_var1 = bool3(uint3(123u));
bool3 v3bool_var11 = bool3(uint3(1234u));
bool3 v3bool_var2 = bool3(int3(123));
bool3 v3bool_var3 = bool3(float3(123.0f));
int3 v3i32_var1 = int3(uint3(123u));
int3 v3i32_var2 = int3(float3(123.0f));
uint3 v3u32_var1 = uint3(int3(123));
uint3 v3u32_var2 = uint3(float3(123.0f));
bool3 v3bool_var4 = bool3(bool2(float2(123.0f)), true);
bool4 v4bool_var5 = bool4(bool2(float2(123.0f, 0.0f)), bool2(true, bool(float(0.0f))));
return;
}

View File

@@ -0,0 +1,117 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 65
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
OpName %constant_with_non_constant "constant_with_non_constant"
OpName %a "a"
OpName %b "b"
OpName %main "main"
OpName %bool_var1 "bool_var1"
OpName %bool_var2 "bool_var2"
OpName %bool_var3 "bool_var3"
OpName %i32_var1 "i32_var1"
OpName %i32_var2 "i32_var2"
OpName %u32_var1 "u32_var1"
OpName %u32_var2 "u32_var2"
OpName %v3bool_var1 "v3bool_var1"
OpName %v3bool_var11 "v3bool_var11"
OpName %v3bool_var2 "v3bool_var2"
OpName %v3bool_var3 "v3bool_var3"
OpName %v3i32_var1 "v3i32_var1"
OpName %v3i32_var2 "v3i32_var2"
OpName %v3u32_var1 "v3u32_var1"
OpName %v3u32_var2 "v3u32_var2"
OpName %v3bool_var4 "v3bool_var4"
OpName %v4bool_var5 "v4bool_var5"
%void = OpTypeVoid
%1 = OpTypeFunction %void
%float = OpTypeFloat 32
%6 = OpConstantNull %float
%_ptr_Function_float = OpTypePointer Function %float
%v2float = OpTypeVector %float 2
%float_1 = OpConstant %float 1
%_ptr_Function_v2float = OpTypePointer Function %v2float
%15 = OpConstantNull %v2float
%bool = OpTypeBool
%true = OpConstantTrue %bool
%_ptr_Function_bool = OpTypePointer Function %bool
%22 = OpConstantNull %bool
%int = OpTypeInt 32 1
%int_123 = OpConstant %int 123
%_ptr_Function_int = OpTypePointer Function %int
%29 = OpConstantNull %int
%uint = OpTypeInt 32 0
%uint_123 = OpConstant %uint 123
%_ptr_Function_uint = OpTypePointer Function %uint
%35 = OpConstantNull %uint
%v3bool = OpTypeVector %bool 3
%38 = OpConstantComposite %v3bool %true %true %true
%_ptr_Function_v3bool = OpTypePointer Function %v3bool
%41 = OpConstantNull %v3bool
%v3int = OpTypeVector %int 3
%46 = OpConstantComposite %v3int %int_123 %int_123 %int_123
%_ptr_Function_v3int = OpTypePointer Function %v3int
%49 = OpConstantNull %v3int
%v3uint = OpTypeVector %uint 3
%52 = OpConstantComposite %v3uint %uint_123 %uint_123 %uint_123
%_ptr_Function_v3uint = OpTypePointer Function %v3uint
%55 = OpConstantNull %v3uint
%57 = OpConstantComposite %v3bool %true %true %true
%v4bool = OpTypeVector %bool 4
%false = OpConstantFalse %bool
%61 = OpConstantComposite %v4bool %true %false %true %false
%_ptr_Function_v4bool = OpTypePointer Function %v4bool
%64 = OpConstantNull %v4bool
%constant_with_non_constant = OpFunction %void None %1
%4 = OpLabel
%a = OpVariable %_ptr_Function_float Function %6
%b = OpVariable %_ptr_Function_v2float Function %15
OpStore %a %6
%11 = OpLoad %float %a
%12 = OpCompositeConstruct %v2float %float_1 %11
OpStore %b %12
OpReturn
OpFunctionEnd
%main = OpFunction %void None %1
%17 = OpLabel
%bool_var1 = OpVariable %_ptr_Function_bool Function %22
%bool_var2 = OpVariable %_ptr_Function_bool Function %22
%bool_var3 = OpVariable %_ptr_Function_bool Function %22
%i32_var1 = OpVariable %_ptr_Function_int Function %29
%i32_var2 = OpVariable %_ptr_Function_int Function %29
%u32_var1 = OpVariable %_ptr_Function_uint Function %35
%u32_var2 = OpVariable %_ptr_Function_uint Function %35
%v3bool_var1 = OpVariable %_ptr_Function_v3bool Function %41
%v3bool_var11 = OpVariable %_ptr_Function_v3bool Function %41
%v3bool_var2 = OpVariable %_ptr_Function_v3bool Function %41
%v3bool_var3 = OpVariable %_ptr_Function_v3bool Function %41
%v3i32_var1 = OpVariable %_ptr_Function_v3int Function %49
%v3i32_var2 = OpVariable %_ptr_Function_v3int Function %49
%v3u32_var1 = OpVariable %_ptr_Function_v3uint Function %55
%v3u32_var2 = OpVariable %_ptr_Function_v3uint Function %55
%v3bool_var4 = OpVariable %_ptr_Function_v3bool Function %41
%v4bool_var5 = OpVariable %_ptr_Function_v4bool Function %64
OpStore %bool_var1 %true
OpStore %bool_var2 %true
OpStore %bool_var3 %true
OpStore %i32_var1 %int_123
OpStore %i32_var2 %int_123
OpStore %u32_var1 %uint_123
OpStore %u32_var2 %uint_123
OpStore %v3bool_var1 %38
OpStore %v3bool_var11 %38
OpStore %v3bool_var2 %38
OpStore %v3bool_var3 %38
OpStore %v3i32_var1 %46
OpStore %v3i32_var2 %46
OpStore %v3u32_var1 %52
OpStore %v3u32_var2 %52
OpStore %v3bool_var4 %57
OpStore %v4bool_var5 %61
OpReturn
OpFunctionEnd

View File

@@ -0,0 +1,25 @@
fn constant_with_non_constant() {
var a : f32 = f32();
var b : vec2<f32> = vec2<f32>(f32(i32(1)), a);
}
[[stage(compute)]]
fn main() {
var bool_var1 : bool = bool(123u);
var bool_var2 : bool = bool(123);
var bool_var3 : bool = bool(123.0);
var i32_var1 : i32 = i32(123u);
var i32_var2 : i32 = i32(123.0);
var u32_var1 : u32 = u32(123);
var u32_var2 : u32 = u32(123.0);
var v3bool_var1 : vec3<bool> = vec3<bool>(vec3<u32>(123u));
var v3bool_var11 : vec3<bool> = vec3<bool>(vec3<u32>(1234u));
var v3bool_var2 : vec3<bool> = vec3<bool>(vec3<i32>(123));
var v3bool_var3 : vec3<bool> = vec3<bool>(vec3<f32>(123.0));
var v3i32_var1 : vec3<i32> = vec3<i32>(vec3<u32>(123u));
var v3i32_var2 : vec3<i32> = vec3<i32>(vec3<f32>(123.0));
var v3u32_var1 : vec3<u32> = vec3<u32>(vec3<i32>(123));
var v3u32_var2 : vec3<u32> = vec3<u32>(vec3<f32>(123.0));
var v3bool_var4 : vec3<bool> = vec3<bool>(vec2<bool>(vec2<f32>(123.0)), true);
var v4bool_var5 : vec4<bool> = vec4<bool>(vec2<bool>(vec2<f32>(123.0, 0.0)), vec2<bool>(true, bool(f32(0.0))));
}

View File

@@ -0,0 +1,43 @@
var<private> bool_var1 : bool = bool(1u);
var<private> bool_var2 : bool = bool(1);
var<private> bool_var3 : bool = bool(1.0);
var<private> i32_var1 : i32 = i32(1u);
var<private> i32_var2 : i32 = i32(1.0);
var<private> u32_var1 : u32 = u32(1);
var<private> u32_var2 : u32 = u32(1.0);
var<private> v3bool_var1 : vec3<bool> = vec3<bool>(vec3<u32>(1u));
var<private> v3bool_var2 : vec3<bool> = vec3<bool>(vec3<i32>(1));
var<private> v3bool_var3 : vec3<bool> = vec3<bool>(vec3<f32>(1.0));
var<private> v3i32_var1 : vec3<i32> = vec3<i32>(vec3<u32>(1u));
var<private> v3i32_var2 : vec3<i32> = vec3<i32>(vec3<f32>(1.0));
var<private> v3u32_var1 : vec3<u32> = vec3<u32>(vec3<i32>(1));
var<private> v3u32_var2 : vec3<u32> = vec3<u32>(vec3<f32>(1.0));
var<private> v3bool_var4 : vec3<bool> = vec3<bool>(vec2<bool>(vec2<f32>(123.0)), true);
var<private> v4bool_var5 : vec4<bool> = vec4<bool>(vec2<bool>(vec2<f32>(123.0, 0.0)), vec2<bool>(true, bool(f32(0.0))));
[[stage(compute)]]
fn main() {
// Reference the module-scope variables to stop them from being removed.
bool_var1 = bool();
bool_var2 = bool();
bool_var3 = bool();
i32_var1 = i32();
i32_var2 = i32();
u32_var1 = u32();
u32_var2 = u32();
v3bool_var1 = vec3<bool>();
v3bool_var2 = vec3<bool>();
v3bool_var3 = vec3<bool>();
v3bool_var4 = vec3<bool>();
v4bool_var5 = vec4<bool>();
v3i32_var1 = vec3<i32>();
v3i32_var2 = vec3<i32>();
v3u32_var1 = vec3<u32>();
v3u32_var2 = vec3<u32>();
}

View File

@@ -0,0 +1,37 @@
static bool bool_var1 = bool(1u);
static bool bool_var2 = bool(1);
static bool bool_var3 = bool(1.0f);
static int i32_var1 = int(1u);
static int i32_var2 = int(1.0f);
static uint u32_var1 = uint(1);
static uint u32_var2 = uint(1.0f);
static bool3 v3bool_var1 = bool3(uint3((1u).xxx));
static bool3 v3bool_var2 = bool3(int3((1).xxx));
static bool3 v3bool_var3 = bool3(float3((1.0f).xxx));
static int3 v3i32_var1 = int3(uint3((1u).xxx));
static int3 v3i32_var2 = int3(float3((1.0f).xxx));
static uint3 v3u32_var1 = uint3(int3((1).xxx));
static uint3 v3u32_var2 = uint3(float3((1.0f).xxx));
static bool3 v3bool_var4 = bool3(bool2(float2((123.0f).xx)), true);
static bool4 v4bool_var5 = bool4(bool2(float2(123.0f, 0.0f)), bool2(true, bool(float(0.0f))));
[numthreads(1, 1, 1)]
void main() {
bool_var1 = false;
bool_var2 = false;
bool_var3 = false;
i32_var1 = 0;
i32_var2 = 0;
u32_var1 = 0u;
u32_var2 = 0u;
v3bool_var1 = bool3(false, false, false);
v3bool_var2 = bool3(false, false, false);
v3bool_var3 = bool3(false, false, false);
v3bool_var4 = bool3(false, false, false);
v4bool_var5 = bool4(false, false, false, false);
v3i32_var1 = int3(0, 0, 0);
v3i32_var2 = int3(0, 0, 0);
v3u32_var1 = uint3(0u, 0u, 0u);
v3u32_var2 = uint3(0u, 0u, 0u);
return;
}

View File

@@ -0,0 +1,39 @@
#include <metal_stdlib>
using namespace metal;
kernel void tint_symbol() {
thread bool tint_symbol_1 = bool(1u);
thread bool tint_symbol_2 = bool(1);
thread bool tint_symbol_3 = bool(1.0f);
thread int tint_symbol_4 = int(1u);
thread int tint_symbol_5 = int(1.0f);
thread uint tint_symbol_6 = uint(1);
thread uint tint_symbol_7 = uint(1.0f);
thread bool3 tint_symbol_8 = bool3(uint3(1u));
thread bool3 tint_symbol_9 = bool3(int3(1));
thread bool3 tint_symbol_10 = bool3(float3(1.0f));
thread bool3 tint_symbol_11 = bool3(bool2(float2(123.0f)), true);
thread bool4 tint_symbol_12 = bool4(bool2(float2(123.0f, 0.0f)), bool2(true, bool(float(0.0f))));
thread int3 tint_symbol_13 = int3(uint3(1u));
thread int3 tint_symbol_14 = int3(float3(1.0f));
thread uint3 tint_symbol_15 = uint3(int3(1));
thread uint3 tint_symbol_16 = uint3(float3(1.0f));
tint_symbol_1 = bool();
tint_symbol_2 = bool();
tint_symbol_3 = bool();
tint_symbol_4 = int();
tint_symbol_5 = int();
tint_symbol_6 = uint();
tint_symbol_7 = uint();
tint_symbol_8 = bool3();
tint_symbol_9 = bool3();
tint_symbol_10 = bool3();
tint_symbol_11 = bool3();
tint_symbol_12 = bool4();
tint_symbol_13 = int3();
tint_symbol_14 = int3();
tint_symbol_15 = uint3();
tint_symbol_16 = uint3();
return;
}

View File

@@ -0,0 +1,94 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 51
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
OpName %bool_var1 "bool_var1"
OpName %bool_var2 "bool_var2"
OpName %bool_var3 "bool_var3"
OpName %i32_var1 "i32_var1"
OpName %i32_var2 "i32_var2"
OpName %u32_var1 "u32_var1"
OpName %u32_var2 "u32_var2"
OpName %v3bool_var1 "v3bool_var1"
OpName %v3bool_var2 "v3bool_var2"
OpName %v3bool_var3 "v3bool_var3"
OpName %v3i32_var1 "v3i32_var1"
OpName %v3i32_var2 "v3i32_var2"
OpName %v3u32_var1 "v3u32_var1"
OpName %v3u32_var2 "v3u32_var2"
OpName %v3bool_var4 "v3bool_var4"
OpName %v4bool_var5 "v4bool_var5"
OpName %main "main"
%bool = OpTypeBool
%true = OpConstantTrue %bool
%_ptr_Private_bool = OpTypePointer Private %bool
%bool_var1 = OpVariable %_ptr_Private_bool Private %true
%bool_var2 = OpVariable %_ptr_Private_bool Private %true
%bool_var3 = OpVariable %_ptr_Private_bool Private %true
%int = OpTypeInt 32 1
%int_1 = OpConstant %int 1
%_ptr_Private_int = OpTypePointer Private %int
%i32_var1 = OpVariable %_ptr_Private_int Private %int_1
%i32_var2 = OpVariable %_ptr_Private_int Private %int_1
%uint = OpTypeInt 32 0
%uint_1 = OpConstant %uint 1
%_ptr_Private_uint = OpTypePointer Private %uint
%u32_var1 = OpVariable %_ptr_Private_uint Private %uint_1
%u32_var2 = OpVariable %_ptr_Private_uint Private %uint_1
%v3bool = OpTypeVector %bool 3
%18 = OpConstantComposite %v3bool %true %true %true
%_ptr_Private_v3bool = OpTypePointer Private %v3bool
%v3bool_var1 = OpVariable %_ptr_Private_v3bool Private %18
%v3bool_var2 = OpVariable %_ptr_Private_v3bool Private %18
%v3bool_var3 = OpVariable %_ptr_Private_v3bool Private %18
%v3int = OpTypeVector %int 3
%24 = OpConstantComposite %v3int %int_1 %int_1 %int_1
%_ptr_Private_v3int = OpTypePointer Private %v3int
%v3i32_var1 = OpVariable %_ptr_Private_v3int Private %24
%v3i32_var2 = OpVariable %_ptr_Private_v3int Private %24
%v3uint = OpTypeVector %uint 3
%29 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
%_ptr_Private_v3uint = OpTypePointer Private %v3uint
%v3u32_var1 = OpVariable %_ptr_Private_v3uint Private %29
%v3u32_var2 = OpVariable %_ptr_Private_v3uint Private %29
%33 = OpConstantComposite %v3bool %true %true %true
%v3bool_var4 = OpVariable %_ptr_Private_v3bool Private %33
%v4bool = OpTypeVector %bool 4
%false = OpConstantFalse %bool
%37 = OpConstantComposite %v4bool %true %false %true %false
%_ptr_Private_v4bool = OpTypePointer Private %v4bool
%v4bool_var5 = OpVariable %_ptr_Private_v4bool Private %37
%void = OpTypeVoid
%40 = OpTypeFunction %void
%44 = OpConstantNull %bool
%45 = OpConstantNull %int
%46 = OpConstantNull %uint
%47 = OpConstantNull %v3bool
%48 = OpConstantNull %v4bool
%49 = OpConstantNull %v3int
%50 = OpConstantNull %v3uint
%main = OpFunction %void None %40
%43 = OpLabel
OpStore %bool_var1 %44
OpStore %bool_var2 %44
OpStore %bool_var3 %44
OpStore %i32_var1 %45
OpStore %i32_var2 %45
OpStore %u32_var1 %46
OpStore %u32_var2 %46
OpStore %v3bool_var1 %47
OpStore %v3bool_var2 %47
OpStore %v3bool_var3 %47
OpStore %v3bool_var4 %47
OpStore %v4bool_var5 %48
OpStore %v3i32_var1 %49
OpStore %v3i32_var2 %49
OpStore %v3u32_var1 %50
OpStore %v3u32_var2 %50
OpReturn
OpFunctionEnd

View File

@@ -0,0 +1,51 @@
var<private> bool_var1 : bool = bool(1u);
var<private> bool_var2 : bool = bool(1);
var<private> bool_var3 : bool = bool(1.0);
var<private> i32_var1 : i32 = i32(1u);
var<private> i32_var2 : i32 = i32(1.0);
var<private> u32_var1 : u32 = u32(1);
var<private> u32_var2 : u32 = u32(1.0);
var<private> v3bool_var1 : vec3<bool> = vec3<bool>(vec3<u32>(1u));
var<private> v3bool_var2 : vec3<bool> = vec3<bool>(vec3<i32>(1));
var<private> v3bool_var3 : vec3<bool> = vec3<bool>(vec3<f32>(1.0));
var<private> v3i32_var1 : vec3<i32> = vec3<i32>(vec3<u32>(1u));
var<private> v3i32_var2 : vec3<i32> = vec3<i32>(vec3<f32>(1.0));
var<private> v3u32_var1 : vec3<u32> = vec3<u32>(vec3<i32>(1));
var<private> v3u32_var2 : vec3<u32> = vec3<u32>(vec3<f32>(1.0));
var<private> v3bool_var4 : vec3<bool> = vec3<bool>(vec2<bool>(vec2<f32>(123.0)), true);
var<private> v4bool_var5 : vec4<bool> = vec4<bool>(vec2<bool>(vec2<f32>(123.0, 0.0)), vec2<bool>(true, bool(f32(0.0))));
[[stage(compute)]]
fn main() {
bool_var1 = bool();
bool_var2 = bool();
bool_var3 = bool();
i32_var1 = i32();
i32_var2 = i32();
u32_var1 = u32();
u32_var2 = u32();
v3bool_var1 = vec3<bool>();
v3bool_var2 = vec3<bool>();
v3bool_var3 = vec3<bool>();
v3bool_var4 = vec3<bool>();
v4bool_var5 = vec4<bool>();
v3i32_var1 = vec3<i32>();
v3i32_var2 = vec3<i32>();
v3u32_var1 = vec3<u32>();
v3u32_var2 = vec3<u32>();
}