tint: Fix MSL generation of '&' and '|' with booleans
The bitwise-and and bitwise-or binary operators on booleans result in an integer. Explicitly cast this back to a boolean. Fixed: tint:1540 Fixed: tint:1541 Change-Id: I395176f291e6080c88b8cff18e14ed6cd1234074 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/90501 Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
parent
35f0fcaac0
commit
e6b6777c8e
|
@ -513,6 +513,22 @@ bool GeneratorImpl::EmitBinary(std::ostream& out, const ast::BinaryExpression* e
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle '&' and '|' of booleans.
|
||||||
|
if ((expr->IsAnd() || expr->IsOr()) && lhs_type->Is<sem::Bool>()) {
|
||||||
|
out << "bool";
|
||||||
|
ScopedParen sp(out);
|
||||||
|
if (!EmitExpression(out, expr->lhs)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!emit_op()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!EmitExpression(out, expr->rhs)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Emit as usual
|
// Emit as usual
|
||||||
ScopedParen sp(out);
|
ScopedParen sp(out);
|
||||||
if (!EmitExpression(out, expr->lhs)) {
|
if (!EmitExpression(out, expr->lhs)) {
|
||||||
|
|
|
@ -171,5 +171,31 @@ TEST_F(MslBinaryTest, ModVec3F32) {
|
||||||
EXPECT_EQ(out.str(), "fmod(left, right)");
|
EXPECT_EQ(out.str(), "fmod(left, right)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(MslBinaryTest, BoolAnd) {
|
||||||
|
auto* left = Var("left", nullptr, Expr(true));
|
||||||
|
auto* right = Var("right", nullptr, Expr(false));
|
||||||
|
auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kAnd, Expr(left), Expr(right));
|
||||||
|
WrapInFunction(left, right, expr);
|
||||||
|
|
||||||
|
GeneratorImpl& gen = Build();
|
||||||
|
|
||||||
|
std::stringstream out;
|
||||||
|
ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
|
||||||
|
EXPECT_EQ(out.str(), "bool(left & right)");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(MslBinaryTest, BoolOr) {
|
||||||
|
auto* left = Var("left", nullptr, Expr(true));
|
||||||
|
auto* right = Var("right", nullptr, Expr(false));
|
||||||
|
auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kOr, Expr(left), Expr(right));
|
||||||
|
WrapInFunction(left, right, expr);
|
||||||
|
|
||||||
|
GeneratorImpl& gen = Build();
|
||||||
|
|
||||||
|
std::stringstream out;
|
||||||
|
ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
|
||||||
|
EXPECT_EQ(out.str(), "bool(left | right)");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace tint::writer::msl
|
} // namespace tint::writer::msl
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
struct S {
|
||||||
|
e: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
@stage(compute)
|
||||||
|
@workgroup_size(1)
|
||||||
|
fn main() {
|
||||||
|
var b : bool;
|
||||||
|
var v = S(true & b);
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#version 310 es
|
||||||
|
|
||||||
|
struct S {
|
||||||
|
bool e;
|
||||||
|
};
|
||||||
|
|
||||||
|
void tint_symbol() {
|
||||||
|
bool b = false;
|
||||||
|
S v = S(bool(uint(true) & uint(b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||||
|
void main() {
|
||||||
|
tint_symbol();
|
||||||
|
return;
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
struct S {
|
||||||
|
bool e;
|
||||||
|
};
|
||||||
|
|
||||||
|
[numthreads(1, 1, 1)]
|
||||||
|
void main() {
|
||||||
|
bool b = false;
|
||||||
|
S v = {(true & b)};
|
||||||
|
return;
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include <metal_stdlib>
|
||||||
|
|
||||||
|
using namespace metal;
|
||||||
|
struct S {
|
||||||
|
bool e;
|
||||||
|
};
|
||||||
|
|
||||||
|
kernel void tint_symbol() {
|
||||||
|
bool b = false;
|
||||||
|
S v = {.e=bool(true & b)};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
; SPIR-V
|
||||||
|
; Version: 1.3
|
||||||
|
; Generator: Google Tint Compiler; 0
|
||||||
|
; Bound: 17
|
||||||
|
; Schema: 0
|
||||||
|
OpCapability Shader
|
||||||
|
OpMemoryModel Logical GLSL450
|
||||||
|
OpEntryPoint GLCompute %main "main"
|
||||||
|
OpExecutionMode %main LocalSize 1 1 1
|
||||||
|
OpName %main "main"
|
||||||
|
OpName %b "b"
|
||||||
|
OpName %S "S"
|
||||||
|
OpMemberName %S 0 "e"
|
||||||
|
OpName %v "v"
|
||||||
|
OpMemberDecorate %S 0 Offset 0
|
||||||
|
%void = OpTypeVoid
|
||||||
|
%1 = OpTypeFunction %void
|
||||||
|
%bool = OpTypeBool
|
||||||
|
%_ptr_Function_bool = OpTypePointer Function %bool
|
||||||
|
%8 = OpConstantNull %bool
|
||||||
|
%S = OpTypeStruct %bool
|
||||||
|
%true = OpConstantTrue %bool
|
||||||
|
%_ptr_Function_S = OpTypePointer Function %S
|
||||||
|
%16 = OpConstantNull %S
|
||||||
|
%main = OpFunction %void None %1
|
||||||
|
%4 = OpLabel
|
||||||
|
%b = OpVariable %_ptr_Function_bool Function %8
|
||||||
|
%v = OpVariable %_ptr_Function_S Function %16
|
||||||
|
%11 = OpLoad %bool %b
|
||||||
|
%12 = OpLogicalAnd %bool %true %11
|
||||||
|
%13 = OpCompositeConstruct %S %12
|
||||||
|
OpStore %v %13
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
|
@ -0,0 +1,9 @@
|
||||||
|
struct S {
|
||||||
|
e : bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
@stage(compute) @workgroup_size(1)
|
||||||
|
fn main() {
|
||||||
|
var b : bool;
|
||||||
|
var v = S((true & b));
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
@stage(compute)
|
||||||
|
@workgroup_size(1)
|
||||||
|
fn main() {
|
||||||
|
var v = select(true & true, true, false);
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
#version 310 es
|
||||||
|
|
||||||
|
void tint_symbol() {
|
||||||
|
bool v = (false ? true : bool(uint(true) & uint(true)));
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||||
|
void main() {
|
||||||
|
tint_symbol();
|
||||||
|
return;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
[numthreads(1, 1, 1)]
|
||||||
|
void main() {
|
||||||
|
bool v = (false ? true : (true & true));
|
||||||
|
return;
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
#include <metal_stdlib>
|
||||||
|
|
||||||
|
using namespace metal;
|
||||||
|
kernel void tint_symbol() {
|
||||||
|
bool v = select(bool(true & true), true, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
; SPIR-V
|
||||||
|
; Version: 1.3
|
||||||
|
; Generator: Google Tint Compiler; 0
|
||||||
|
; Bound: 13
|
||||||
|
; Schema: 0
|
||||||
|
OpCapability Shader
|
||||||
|
OpMemoryModel Logical GLSL450
|
||||||
|
OpEntryPoint GLCompute %main "main"
|
||||||
|
OpExecutionMode %main LocalSize 1 1 1
|
||||||
|
OpName %main "main"
|
||||||
|
OpName %v "v"
|
||||||
|
%void = OpTypeVoid
|
||||||
|
%1 = OpTypeFunction %void
|
||||||
|
%bool = OpTypeBool
|
||||||
|
%false = OpConstantFalse %bool
|
||||||
|
%true = OpConstantTrue %bool
|
||||||
|
%_ptr_Function_bool = OpTypePointer Function %bool
|
||||||
|
%12 = OpConstantNull %bool
|
||||||
|
%main = OpFunction %void None %1
|
||||||
|
%4 = OpLabel
|
||||||
|
%v = OpVariable %_ptr_Function_bool Function %12
|
||||||
|
%9 = OpLogicalAnd %bool %true %true
|
||||||
|
%5 = OpSelect %bool %false %true %9
|
||||||
|
OpStore %v %5
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
|
@ -0,0 +1,4 @@
|
||||||
|
@stage(compute) @workgroup_size(1)
|
||||||
|
fn main() {
|
||||||
|
var v = select((true & true), true, false);
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
@stage(compute) @workgroup_size(1)
|
||||||
|
fn f() {
|
||||||
|
let a = true;
|
||||||
|
let b = false;
|
||||||
|
let r : bool = a & b;
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
#version 310 es
|
||||||
|
|
||||||
|
void f() {
|
||||||
|
bool r = bool(uint(true) & uint(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||||
|
void main() {
|
||||||
|
f();
|
||||||
|
return;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
[numthreads(1, 1, 1)]
|
||||||
|
void f() {
|
||||||
|
const bool r = (true & false);
|
||||||
|
return;
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
#include <metal_stdlib>
|
||||||
|
|
||||||
|
using namespace metal;
|
||||||
|
kernel void f() {
|
||||||
|
bool const a = true;
|
||||||
|
bool const b = false;
|
||||||
|
bool const r = bool(a & b);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
; SPIR-V
|
||||||
|
; Version: 1.3
|
||||||
|
; Generator: Google Tint Compiler; 0
|
||||||
|
; Bound: 9
|
||||||
|
; Schema: 0
|
||||||
|
OpCapability Shader
|
||||||
|
OpMemoryModel Logical GLSL450
|
||||||
|
OpEntryPoint GLCompute %f "f"
|
||||||
|
OpExecutionMode %f LocalSize 1 1 1
|
||||||
|
OpName %f "f"
|
||||||
|
%void = OpTypeVoid
|
||||||
|
%1 = OpTypeFunction %void
|
||||||
|
%bool = OpTypeBool
|
||||||
|
%true = OpConstantTrue %bool
|
||||||
|
%false = OpConstantFalse %bool
|
||||||
|
%f = OpFunction %void None %1
|
||||||
|
%4 = OpLabel
|
||||||
|
%8 = OpLogicalAnd %bool %true %false
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
|
@ -0,0 +1,6 @@
|
||||||
|
@stage(compute) @workgroup_size(1)
|
||||||
|
fn f() {
|
||||||
|
let a = true;
|
||||||
|
let b = false;
|
||||||
|
let r : bool = (a & b);
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
@stage(compute) @workgroup_size(1)
|
||||||
|
fn f() {
|
||||||
|
let a = vec3<bool>(true, true, false);
|
||||||
|
let b = vec3<bool>(true, false, true);
|
||||||
|
let r : vec3<bool> = a & b;
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
#version 310 es
|
||||||
|
|
||||||
|
void f() {
|
||||||
|
bvec3 a = bvec3(true, true, false);
|
||||||
|
bvec3 b = bvec3(true, false, true);
|
||||||
|
bvec3 r = bvec3(uvec3(a) & uvec3(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||||
|
void main() {
|
||||||
|
f();
|
||||||
|
return;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
[numthreads(1, 1, 1)]
|
||||||
|
void f() {
|
||||||
|
const bool3 a = bool3(true, true, false);
|
||||||
|
const bool3 b = bool3(true, false, true);
|
||||||
|
const bool3 r = (a & b);
|
||||||
|
return;
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
#include <metal_stdlib>
|
||||||
|
|
||||||
|
using namespace metal;
|
||||||
|
kernel void f() {
|
||||||
|
bool3 const a = bool3(true, true, false);
|
||||||
|
bool3 const b = bool3(true, false, true);
|
||||||
|
bool3 const r = (a & b);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
; SPIR-V
|
||||||
|
; Version: 1.3
|
||||||
|
; Generator: Google Tint Compiler; 0
|
||||||
|
; Bound: 12
|
||||||
|
; Schema: 0
|
||||||
|
OpCapability Shader
|
||||||
|
OpMemoryModel Logical GLSL450
|
||||||
|
OpEntryPoint GLCompute %f "f"
|
||||||
|
OpExecutionMode %f LocalSize 1 1 1
|
||||||
|
OpName %f "f"
|
||||||
|
%void = OpTypeVoid
|
||||||
|
%1 = OpTypeFunction %void
|
||||||
|
%bool = OpTypeBool
|
||||||
|
%v3bool = OpTypeVector %bool 3
|
||||||
|
%true = OpConstantTrue %bool
|
||||||
|
%false = OpConstantFalse %bool
|
||||||
|
%9 = OpConstantComposite %v3bool %true %true %false
|
||||||
|
%10 = OpConstantComposite %v3bool %true %false %true
|
||||||
|
%f = OpFunction %void None %1
|
||||||
|
%4 = OpLabel
|
||||||
|
%11 = OpLogicalAnd %v3bool %9 %10
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
|
@ -0,0 +1,6 @@
|
||||||
|
@stage(compute) @workgroup_size(1)
|
||||||
|
fn f() {
|
||||||
|
let a = vec3<bool>(true, true, false);
|
||||||
|
let b = vec3<bool>(true, false, true);
|
||||||
|
let r : vec3<bool> = (a & b);
|
||||||
|
}
|
Loading…
Reference in New Issue