[ir] Change unary not to a binary equal

This CL removes unary `not` and instead emits `x == false`. When coming
back out of IR we can detect the `== false` and convert back to a `!`.

Bug: tint:1928
Change-Id: I905493182533ac2787ab9fe9245c8b53d51c1298
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/131580
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
dan sinclair 2023-05-04 17:09:07 +00:00 committed by Dawn LUCI CQ
parent 6500875f1a
commit 34f41c7bad
7 changed files with 25 additions and 22 deletions

View File

@ -203,6 +203,25 @@ TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
}
TEST_F(IR_InstructionTest, CreateNot) {
auto& b = CreateEmptyBuilder();
const auto* inst =
b.builder.Not(b.builder.ir.types.Get<type::Bool>(), b.builder.Constant(true));
ASSERT_TRUE(inst->Is<Binary>());
EXPECT_EQ(inst->GetKind(), Binary::Kind::kEqual);
ASSERT_TRUE(inst->LHS()->Is<Constant>());
auto lhs = inst->LHS()->As<Constant>()->value;
ASSERT_TRUE(lhs->Is<constant::Scalar<bool>>());
EXPECT_TRUE(lhs->As<constant::Scalar<bool>>()->ValueAs<bool>());
ASSERT_TRUE(inst->RHS()->Is<Constant>());
auto rhs = inst->RHS()->As<Constant>()->value;
ASSERT_TRUE(rhs->Is<constant::Scalar<bool>>());
EXPECT_FALSE(rhs->As<constant::Scalar<bool>>()->ValueAs<bool>());
}
TEST_F(IR_InstructionTest, CreateShiftLeft) {
auto& b = CreateEmptyBuilder();

View File

@ -16,6 +16,8 @@
#include <utility>
#include "src/tint/constant/scalar.h"
namespace tint::ir {
Builder::Builder() {}
@ -194,8 +196,8 @@ Unary* Builder::Negation(const type::Type* type, Value* val) {
return CreateUnary(Unary::Kind::kNegation, type, val);
}
Unary* Builder::Not(const type::Type* type, Value* val) {
return CreateUnary(Unary::Kind::kNot, type, val);
Binary* Builder::Not(const type::Type* type, Value* val) {
return Equal(type, val, Constant(create<constant::Scalar<bool>>(type, false)));
}
ir::Bitcast* Builder::Bitcast(const type::Type* type, Value* val) {

View File

@ -300,7 +300,7 @@ class Builder {
/// @param type the result type of the expression
/// @param val the value
/// @returns the operation
Unary* Not(const type::Type* type, Value* val);
Binary* Not(const type::Type* type, Value* val);
/// Creates a bitcast instruction
/// @param type the result type of the bitcast

View File

@ -833,7 +833,7 @@ utils::Result<Value*> BuilderImpl::EmitUnary(const ast::UnaryOpExpression* expr)
auto* sem = program_->Sem().Get(expr);
auto* ty = sem->Type()->Clone(clone_ctx_.type_ctx);
Unary* inst = nullptr;
Instruction* inst = nullptr;
switch (expr->op) {
case ast::UnaryOp::kAddressOf:
inst = builder.AddressOf(ty, val.Get());

View File

@ -493,9 +493,6 @@ void Disassembler::EmitUnary(const Unary* u) {
case Unary::Kind::kNegation:
out_ << "negation";
break;
case Unary::Kind::kNot:
out_ << "not";
break;
}
out_ << " ";
EmitValue(u->Val());

View File

@ -29,7 +29,6 @@ class Unary : public utils::Castable<Unary, Instruction> {
kComplement,
kIndirection,
kNegation,
kNot,
};
/// Constructor

View File

@ -87,20 +87,6 @@ TEST_F(IR_InstructionTest, CreateNegation) {
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
}
TEST_F(IR_InstructionTest, CreateNot) {
auto& b = CreateEmptyBuilder();
const auto* inst =
b.builder.Not(b.builder.ir.types.Get<type::Bool>(), b.builder.Constant(true));
ASSERT_TRUE(inst->Is<Unary>());
EXPECT_EQ(inst->GetKind(), Unary::Kind::kNot);
ASSERT_TRUE(inst->Val()->Is<Constant>());
auto lhs = inst->Val()->As<Constant>()->value;
ASSERT_TRUE(lhs->Is<constant::Scalar<bool>>());
EXPECT_TRUE(lhs->As<constant::Scalar<bool>>()->ValueAs<bool>());
}
TEST_F(IR_InstructionTest, Unary_Usage) {
auto& b = CreateEmptyBuilder();
const auto* inst =