diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt index a8644b7341..06aa48355f 100644 --- a/src/tint/CMakeLists.txt +++ b/src/tint/CMakeLists.txt @@ -666,18 +666,18 @@ if(${TINT_BUILD_IR}) ir/function.h ir/if.cc ir/if.h + ir/instruction.cc + ir/instruction.h ir/loop.cc ir/loop.h ir/module.cc ir/module.h - ir/op.cc - ir/op.h - ir/register.cc - ir/register.h ir/switch.cc ir/switch.h ir/terminator.cc ir/terminator.h + ir/value.cc + ir/value.h ) endif() @@ -1341,9 +1341,9 @@ if(TINT_BUILD_TESTS) if (${TINT_BUILD_IR}) list(APPEND TINT_TEST_SRCS ir/builder_impl_test.cc - ir/op_test.cc - ir/register_test.cc + ir/instruction_test.cc ir/test_helper.h + ir/value_test.cc ) endif() diff --git a/src/tint/ir/block.h b/src/tint/ir/block.h index 850c13ca57..d27fdf4d64 100644 --- a/src/tint/ir/block.h +++ b/src/tint/ir/block.h @@ -16,7 +16,7 @@ #define SRC_TINT_IR_BLOCK_H_ #include "src/tint/ir/flow_node.h" -#include "src/tint/ir/op.h" +#include "src/tint/ir/instruction.h" #include "src/tint/utils/vector.h" namespace tint::ir { @@ -33,8 +33,8 @@ class Block : public Castable { /// The node this block branches too. const FlowNode* branch_target = nullptr; - /// The operations in the block - utils::Vector ops; + /// The instructions in the block + utils::Vector instructions; }; } // namespace tint::ir diff --git a/src/tint/ir/builder.cc b/src/tint/ir/builder.cc index 57a40a795e..04038079f4 100644 --- a/src/tint/ir/builder.cc +++ b/src/tint/ir/builder.cc @@ -93,84 +93,84 @@ void Builder::Branch(Block* from, FlowNode* to) { to->inbound_branches.Push(from); } -Register::Id Builder::AllocateRegister() { - return next_register_id++; +Value::Id Builder::AllocateValue() { + return next_value_id++; } -Op Builder::CreateOp(Op::Kind kind, Register lhs, Register rhs) { - return Op(kind, Register(AllocateRegister()), lhs, rhs); +Instruction Builder::CreateInstruction(Instruction::Kind kind, Value lhs, Value rhs) { + return Instruction(kind, Value(AllocateValue()), lhs, rhs); } -Op Builder::And(Register lhs, Register rhs) { - return CreateOp(Op::Kind::kAnd, lhs, rhs); +Instruction Builder::And(Value lhs, Value rhs) { + return CreateInstruction(Instruction::Kind::kAnd, lhs, rhs); } -Op Builder::Or(Register lhs, Register rhs) { - return CreateOp(Op::Kind::kOr, lhs, rhs); +Instruction Builder::Or(Value lhs, Value rhs) { + return CreateInstruction(Instruction::Kind::kOr, lhs, rhs); } -Op Builder::Xor(Register lhs, Register rhs) { - return CreateOp(Op::Kind::kXor, lhs, rhs); +Instruction Builder::Xor(Value lhs, Value rhs) { + return CreateInstruction(Instruction::Kind::kXor, lhs, rhs); } -Op Builder::LogicalAnd(Register lhs, Register rhs) { - return CreateOp(Op::Kind::kLogicalAnd, lhs, rhs); +Instruction Builder::LogicalAnd(Value lhs, Value rhs) { + return CreateInstruction(Instruction::Kind::kLogicalAnd, lhs, rhs); } -Op Builder::LogicalOr(Register lhs, Register rhs) { - return CreateOp(Op::Kind::kLogicalOr, lhs, rhs); +Instruction Builder::LogicalOr(Value lhs, Value rhs) { + return CreateInstruction(Instruction::Kind::kLogicalOr, lhs, rhs); } -Op Builder::Equal(Register lhs, Register rhs) { - return CreateOp(Op::Kind::kEqual, lhs, rhs); +Instruction Builder::Equal(Value lhs, Value rhs) { + return CreateInstruction(Instruction::Kind::kEqual, lhs, rhs); } -Op Builder::NotEqual(Register lhs, Register rhs) { - return CreateOp(Op::Kind::kNotEqual, lhs, rhs); +Instruction Builder::NotEqual(Value lhs, Value rhs) { + return CreateInstruction(Instruction::Kind::kNotEqual, lhs, rhs); } -Op Builder::LessThan(Register lhs, Register rhs) { - return CreateOp(Op::Kind::kLessThan, lhs, rhs); +Instruction Builder::LessThan(Value lhs, Value rhs) { + return CreateInstruction(Instruction::Kind::kLessThan, lhs, rhs); } -Op Builder::GreaterThan(Register lhs, Register rhs) { - return CreateOp(Op::Kind::kGreaterThan, lhs, rhs); +Instruction Builder::GreaterThan(Value lhs, Value rhs) { + return CreateInstruction(Instruction::Kind::kGreaterThan, lhs, rhs); } -Op Builder::LessThanEqual(Register lhs, Register rhs) { - return CreateOp(Op::Kind::kLessThanEqual, lhs, rhs); +Instruction Builder::LessThanEqual(Value lhs, Value rhs) { + return CreateInstruction(Instruction::Kind::kLessThanEqual, lhs, rhs); } -Op Builder::GreaterThanEqual(Register lhs, Register rhs) { - return CreateOp(Op::Kind::kGreaterThanEqual, lhs, rhs); +Instruction Builder::GreaterThanEqual(Value lhs, Value rhs) { + return CreateInstruction(Instruction::Kind::kGreaterThanEqual, lhs, rhs); } -Op Builder::ShiftLeft(Register lhs, Register rhs) { - return CreateOp(Op::Kind::kShiftLeft, lhs, rhs); +Instruction Builder::ShiftLeft(Value lhs, Value rhs) { + return CreateInstruction(Instruction::Kind::kShiftLeft, lhs, rhs); } -Op Builder::ShiftRight(Register lhs, Register rhs) { - return CreateOp(Op::Kind::kShiftRight, lhs, rhs); +Instruction Builder::ShiftRight(Value lhs, Value rhs) { + return CreateInstruction(Instruction::Kind::kShiftRight, lhs, rhs); } -Op Builder::Add(Register lhs, Register rhs) { - return CreateOp(Op::Kind::kAdd, lhs, rhs); +Instruction Builder::Add(Value lhs, Value rhs) { + return CreateInstruction(Instruction::Kind::kAdd, lhs, rhs); } -Op Builder::Subtract(Register lhs, Register rhs) { - return CreateOp(Op::Kind::kSubtract, lhs, rhs); +Instruction Builder::Subtract(Value lhs, Value rhs) { + return CreateInstruction(Instruction::Kind::kSubtract, lhs, rhs); } -Op Builder::Multiply(Register lhs, Register rhs) { - return CreateOp(Op::Kind::kMultiply, lhs, rhs); +Instruction Builder::Multiply(Value lhs, Value rhs) { + return CreateInstruction(Instruction::Kind::kMultiply, lhs, rhs); } -Op Builder::Divide(Register lhs, Register rhs) { - return CreateOp(Op::Kind::kDivide, lhs, rhs); +Instruction Builder::Divide(Value lhs, Value rhs) { + return CreateInstruction(Instruction::Kind::kDivide, lhs, rhs); } -Op Builder::Modulo(Register lhs, Register rhs) { - return CreateOp(Op::Kind::kModulo, lhs, rhs); +Instruction Builder::Modulo(Value lhs, Value rhs) { + return CreateInstruction(Instruction::Kind::kModulo, lhs, rhs); } } // namespace tint::ir diff --git a/src/tint/ir/builder.h b/src/tint/ir/builder.h index 091aac85f8..6776d350f7 100644 --- a/src/tint/ir/builder.h +++ b/src/tint/ir/builder.h @@ -17,12 +17,12 @@ #include "src/tint/ir/function.h" #include "src/tint/ir/if.h" +#include "src/tint/ir/instruction.h" #include "src/tint/ir/loop.h" #include "src/tint/ir/module.h" -#include "src/tint/ir/op.h" -#include "src/tint/ir/register.h" #include "src/tint/ir/switch.h" #include "src/tint/ir/terminator.h" +#include "src/tint/ir/value.h" // Forward Declarations namespace tint { @@ -88,124 +88,124 @@ class Builder { /// @param lhs the left-hand-side of the operation /// @param rhs the right-hand-side of the operation /// @returns the operation - Op CreateOp(Op::Kind kind, Register lhs, Register rhs); + Instruction CreateInstruction(Instruction::Kind kind, Value lhs, Value rhs); /// Creates an And operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Op And(Register lhs, Register rhs); + Instruction And(Value lhs, Value rhs); /// Creates an Or operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Op Or(Register lhs, Register rhs); + Instruction Or(Value lhs, Value rhs); /// Creates an Xor operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Op Xor(Register lhs, Register rhs); + Instruction Xor(Value lhs, Value rhs); /// Creates an LogicalAnd operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Op LogicalAnd(Register lhs, Register rhs); + Instruction LogicalAnd(Value lhs, Value rhs); /// Creates an LogicalOr operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Op LogicalOr(Register lhs, Register rhs); + Instruction LogicalOr(Value lhs, Value rhs); /// Creates an Equal operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Op Equal(Register lhs, Register rhs); + Instruction Equal(Value lhs, Value rhs); /// Creates an NotEqual operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Op NotEqual(Register lhs, Register rhs); + Instruction NotEqual(Value lhs, Value rhs); /// Creates an LessThan operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Op LessThan(Register lhs, Register rhs); + Instruction LessThan(Value lhs, Value rhs); /// Creates an GreaterThan operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Op GreaterThan(Register lhs, Register rhs); + Instruction GreaterThan(Value lhs, Value rhs); /// Creates an LessThanEqual operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Op LessThanEqual(Register lhs, Register rhs); + Instruction LessThanEqual(Value lhs, Value rhs); /// Creates an GreaterThanEqual operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Op GreaterThanEqual(Register lhs, Register rhs); + Instruction GreaterThanEqual(Value lhs, Value rhs); /// Creates an ShiftLeft operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Op ShiftLeft(Register lhs, Register rhs); + Instruction ShiftLeft(Value lhs, Value rhs); /// Creates an ShiftRight operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Op ShiftRight(Register lhs, Register rhs); + Instruction ShiftRight(Value lhs, Value rhs); /// Creates an Add operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Op Add(Register lhs, Register rhs); + Instruction Add(Value lhs, Value rhs); /// Creates an Subtract operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Op Subtract(Register lhs, Register rhs); + Instruction Subtract(Value lhs, Value rhs); /// Creates an Multiply operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Op Multiply(Register lhs, Register rhs); + Instruction Multiply(Value lhs, Value rhs); /// Creates an Divide operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Op Divide(Register lhs, Register rhs); + Instruction Divide(Value lhs, Value rhs); /// Creates an Modulo operation /// @param lhs the lhs of the add /// @param rhs the rhs of the add /// @returns the operation - Op Modulo(Register lhs, Register rhs); + Instruction Modulo(Value lhs, Value rhs); - /// @returns a unique register id - Register::Id AllocateRegister(); + /// @returns a unique Value id + Value::Id AllocateValue(); /// The IR module. Module ir; - /// The next register number to allocate - Register::Id next_register_id = 1; + /// The next Value number to allocate + Value::Id next_value_id = 1; }; } // namespace tint::ir diff --git a/src/tint/ir/builder_impl.cc b/src/tint/ir/builder_impl.cc index 06ed837b86..3af54f9cda 100644 --- a/src/tint/ir/builder_impl.cc +++ b/src/tint/ir/builder_impl.cc @@ -516,7 +516,7 @@ bool BuilderImpl::EmitBreakIf(const ast::BreakIfStatement* stmt) { return true; } -utils::Result BuilderImpl::EmitExpression(const ast::Expression* expr) { +utils::Result BuilderImpl::EmitExpression(const ast::Expression* expr) { return tint::Switch( expr, // [&](const ast::IndexAccessorExpression* a) { return EmitIndexAccessor(a); }, @@ -551,7 +551,7 @@ bool BuilderImpl::EmitVariable(const ast::Variable* var) { }); } -utils::Result BuilderImpl::EmitBinary(const ast::BinaryExpression* expr) { +utils::Result BuilderImpl::EmitBinary(const ast::BinaryExpression* expr) { auto lhs = EmitExpression(expr->lhs); if (!lhs) { return utils::Failure; @@ -562,89 +562,87 @@ utils::Result BuilderImpl::EmitBinary(const ast::BinaryExpression* exp return utils::Failure; } - Op op; + Instruction instr; switch (expr->op) { case ast::BinaryOp::kAnd: - op = builder.And(lhs.Get(), rhs.Get()); + instr = builder.And(lhs.Get(), rhs.Get()); break; case ast::BinaryOp::kOr: - op = builder.Or(lhs.Get(), rhs.Get()); + instr = builder.Or(lhs.Get(), rhs.Get()); break; case ast::BinaryOp::kXor: - op = builder.Xor(lhs.Get(), rhs.Get()); + instr = builder.Xor(lhs.Get(), rhs.Get()); break; case ast::BinaryOp::kLogicalAnd: - op = builder.LogicalAnd(lhs.Get(), rhs.Get()); + instr = builder.LogicalAnd(lhs.Get(), rhs.Get()); break; case ast::BinaryOp::kLogicalOr: - op = builder.LogicalOr(lhs.Get(), rhs.Get()); + instr = builder.LogicalOr(lhs.Get(), rhs.Get()); break; case ast::BinaryOp::kEqual: - op = builder.Equal(lhs.Get(), rhs.Get()); + instr = builder.Equal(lhs.Get(), rhs.Get()); break; case ast::BinaryOp::kNotEqual: - op = builder.NotEqual(lhs.Get(), rhs.Get()); + instr = builder.NotEqual(lhs.Get(), rhs.Get()); break; case ast::BinaryOp::kLessThan: - op = builder.LessThan(lhs.Get(), rhs.Get()); + instr = builder.LessThan(lhs.Get(), rhs.Get()); break; case ast::BinaryOp::kGreaterThan: - op = builder.GreaterThan(lhs.Get(), rhs.Get()); + instr = builder.GreaterThan(lhs.Get(), rhs.Get()); break; case ast::BinaryOp::kLessThanEqual: - op = builder.LessThanEqual(lhs.Get(), rhs.Get()); + instr = builder.LessThanEqual(lhs.Get(), rhs.Get()); break; case ast::BinaryOp::kGreaterThanEqual: - op = builder.GreaterThanEqual(lhs.Get(), rhs.Get()); + instr = builder.GreaterThanEqual(lhs.Get(), rhs.Get()); break; case ast::BinaryOp::kShiftLeft: - op = builder.ShiftLeft(lhs.Get(), rhs.Get()); + instr = builder.ShiftLeft(lhs.Get(), rhs.Get()); break; case ast::BinaryOp::kShiftRight: - op = builder.ShiftRight(lhs.Get(), rhs.Get()); + instr = builder.ShiftRight(lhs.Get(), rhs.Get()); break; case ast::BinaryOp::kAdd: - op = builder.Add(lhs.Get(), rhs.Get()); + instr = builder.Add(lhs.Get(), rhs.Get()); break; case ast::BinaryOp::kSubtract: - op = builder.Subtract(lhs.Get(), rhs.Get()); + instr = builder.Subtract(lhs.Get(), rhs.Get()); break; case ast::BinaryOp::kMultiply: - op = builder.Multiply(lhs.Get(), rhs.Get()); + instr = builder.Multiply(lhs.Get(), rhs.Get()); break; case ast::BinaryOp::kDivide: - op = builder.Divide(lhs.Get(), rhs.Get()); + instr = builder.Divide(lhs.Get(), rhs.Get()); break; case ast::BinaryOp::kModulo: - op = builder.Modulo(lhs.Get(), rhs.Get()); + instr = builder.Modulo(lhs.Get(), rhs.Get()); break; case ast::BinaryOp::kNone: TINT_ICE(IR, diagnostics_) << "missing binary operand type"; return utils::Failure; } - auto result = op.Result(); - current_flow_block->ops.Push(op); + auto result = instr.Result(); + current_flow_block->instructions.Push(instr); return result; } -utils::Result BuilderImpl::EmitLiteral(const ast::LiteralExpression* lit) { +utils::Result BuilderImpl::EmitLiteral(const ast::LiteralExpression* lit) { return tint::Switch( // lit, - [&](const ast::BoolLiteralExpression* l) { - return utils::Result{Register(l->value)}; - }, + [&](const ast::BoolLiteralExpression* l) { return utils::Result{Value(l->value)}; }, [&](const ast::FloatLiteralExpression* l) { if (l->suffix == ast::FloatLiteralExpression::Suffix::kF) { - return utils::Result{Register(f32(static_cast(l->value)))}; + return utils::Result{Value(f32(static_cast(l->value)))}; } - return utils::Result{Register(f16(static_cast(l->value)))}; + return utils::Result{Value(f16(static_cast(l->value)))}; }, [&](const ast::IntLiteralExpression* l) { if (l->suffix == ast::IntLiteralExpression::Suffix::kI) { - return utils::Result{Register(i32(l->value))}; + return utils::Result{Value(i32(l->value))}; } - return utils::Result{Register(u32(l->value))}; + return utils::Result{Value(u32(l->value))}; }, [&](Default) { diagnostics_.add_warning(tint::diag::System::IR, diff --git a/src/tint/ir/builder_impl.h b/src/tint/ir/builder_impl.h index ef5238ec6e..60eda73eb2 100644 --- a/src/tint/ir/builder_impl.h +++ b/src/tint/ir/builder_impl.h @@ -23,7 +23,7 @@ #include "src/tint/ir/builder.h" #include "src/tint/ir/flow_node.h" #include "src/tint/ir/module.h" -#include "src/tint/ir/register.h" +#include "src/tint/ir/value.h" #include "src/tint/utils/result.h" // Forward Declarations @@ -140,7 +140,7 @@ class BuilderImpl { /// Emits an expression /// @param expr the expression to emit /// @returns true if successful, false otherwise - utils::Result EmitExpression(const ast::Expression* expr); + utils::Result EmitExpression(const ast::Expression* expr); /// Emits a variable /// @param var the variable to emit @@ -149,13 +149,13 @@ class BuilderImpl { /// Emits a binary expression /// @param expr the binary expression - /// @returns the register storing the result if successful, utils::Failure otherwise - utils::Result EmitBinary(const ast::BinaryExpression* expr); + /// @returns the value storing the result if successful, utils::Failure otherwise + utils::Result EmitBinary(const ast::BinaryExpression* expr); /// Emits a literal expression /// @param lit the literal to emit /// @returns true if successful, false otherwise - utils::Result EmitLiteral(const ast::LiteralExpression* lit); + utils::Result EmitLiteral(const ast::LiteralExpression* lit); /// Emits a type /// @param ty the type to emit diff --git a/src/tint/ir/builder_impl_test.cc b/src/tint/ir/builder_impl_test.cc index 4a1efd53c5..6c8e496eaf 100644 --- a/src/tint/ir/builder_impl_test.cc +++ b/src/tint/ir/builder_impl_test.cc @@ -101,9 +101,9 @@ TEST_F(IR_BuilderImplTest, IfStatement) { EXPECT_EQ(flow->merge_target->branch_target, func->end_target); // Check condition - auto op = flow->condition; - ASSERT_TRUE(op.IsBool()); - EXPECT_TRUE(op.AsBool()); + auto instr = flow->condition; + ASSERT_TRUE(instr.IsBool()); + EXPECT_TRUE(instr.AsBool()); } TEST_F(IR_BuilderImplTest, IfStatement_TrueReturns) { @@ -502,9 +502,9 @@ TEST_F(IR_BuilderImplTest, Loop_WithReturn) { EXPECT_EQ(loop_flow->merge_target->branch_target, nullptr); // Check condition - auto op = if_flow->condition; - ASSERT_TRUE(op.IsBool()); - EXPECT_TRUE(op.AsBool()); + auto instr = if_flow->condition; + ASSERT_TRUE(instr.IsBool()); + EXPECT_TRUE(instr.AsBool()); } TEST_F(IR_BuilderImplTest, Loop_WithOnlyReturn) { @@ -947,9 +947,9 @@ TEST_F(IR_BuilderImplTest, While) { EXPECT_EQ(flow->merge_target->branch_target, func->end_target); // Check condition - auto op = if_flow->condition; - ASSERT_TRUE(op.IsBool()); - EXPECT_FALSE(op.AsBool()); + auto instr = if_flow->condition; + ASSERT_TRUE(instr.IsBool()); + EXPECT_FALSE(instr.AsBool()); } TEST_F(IR_BuilderImplTest, While_Return) { @@ -1071,9 +1071,9 @@ TEST_F(IR_BuilderImplTest, DISABLED_For) { EXPECT_EQ(flow->merge_target->branch_target, func->end_target); // Check condition - auto op = if_flow->condition; - ASSERT_TRUE(op.IsBool()); - EXPECT_FALSE(op.AsBool()); + auto instr = if_flow->condition; + ASSERT_TRUE(instr.IsBool()); + EXPECT_FALSE(instr.AsBool()); } TEST_F(IR_BuilderImplTest, For_NoInitCondOrContinuing) { @@ -1171,9 +1171,9 @@ TEST_F(IR_BuilderImplTest, Switch) { EXPECT_EQ(flow->merge_target->branch_target, func->end_target); // Check condition - auto op = flow->condition; - ASSERT_TRUE(op.IsI32()); - EXPECT_EQ(1_i, op.AsI32()); + auto instr = flow->condition; + ASSERT_TRUE(instr.IsI32()); + EXPECT_EQ(1_i, instr.AsI32()); } TEST_F(IR_BuilderImplTest, Switch_OnlyDefault) { @@ -1402,7 +1402,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Add) { ASSERT_TRUE(r); Disassembler d; - d.EmitBlockOps(b.current_flow_block); + d.EmitBlockInstructions(b.current_flow_block); EXPECT_EQ(d.AsString(), R"(%1 = 3 + 4 )"); } @@ -1413,7 +1413,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Subtract) { ASSERT_TRUE(r); Disassembler d; - d.EmitBlockOps(b.current_flow_block); + d.EmitBlockInstructions(b.current_flow_block); EXPECT_EQ(d.AsString(), R"(%1 = 3 - 4 )"); } @@ -1424,7 +1424,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Multiply) { ASSERT_TRUE(r); Disassembler d; - d.EmitBlockOps(b.current_flow_block); + d.EmitBlockInstructions(b.current_flow_block); EXPECT_EQ(d.AsString(), R"(%1 = 3 * 4 )"); } @@ -1435,7 +1435,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Div) { ASSERT_TRUE(r); Disassembler d; - d.EmitBlockOps(b.current_flow_block); + d.EmitBlockInstructions(b.current_flow_block); EXPECT_EQ(d.AsString(), R"(%1 = 3 / 4 )"); } @@ -1446,7 +1446,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Modulo) { ASSERT_TRUE(r); Disassembler d; - d.EmitBlockOps(b.current_flow_block); + d.EmitBlockInstructions(b.current_flow_block); EXPECT_EQ(d.AsString(), R"(%1 = 3 % 4 )"); } @@ -1457,7 +1457,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_And) { ASSERT_TRUE(r); Disassembler d; - d.EmitBlockOps(b.current_flow_block); + d.EmitBlockInstructions(b.current_flow_block); EXPECT_EQ(d.AsString(), R"(%1 = 3 & 4 )"); } @@ -1468,7 +1468,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Or) { ASSERT_TRUE(r); Disassembler d; - d.EmitBlockOps(b.current_flow_block); + d.EmitBlockInstructions(b.current_flow_block); EXPECT_EQ(d.AsString(), R"(%1 = 3 | 4 )"); } @@ -1479,7 +1479,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Xor) { ASSERT_TRUE(r); Disassembler d; - d.EmitBlockOps(b.current_flow_block); + d.EmitBlockInstructions(b.current_flow_block); EXPECT_EQ(d.AsString(), R"(%1 = 3 ^ 4 )"); } @@ -1490,7 +1490,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LogicalAnd) { ASSERT_TRUE(r); Disassembler d; - d.EmitBlockOps(b.current_flow_block); + d.EmitBlockInstructions(b.current_flow_block); EXPECT_EQ(d.AsString(), R"(%1 = 3 && 4 )"); } @@ -1501,7 +1501,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LogicalOr) { ASSERT_TRUE(r); Disassembler d; - d.EmitBlockOps(b.current_flow_block); + d.EmitBlockInstructions(b.current_flow_block); EXPECT_EQ(d.AsString(), R"(%1 = 3 || 4 )"); } @@ -1512,7 +1512,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Eqaul) { ASSERT_TRUE(r); Disassembler d; - d.EmitBlockOps(b.current_flow_block); + d.EmitBlockInstructions(b.current_flow_block); EXPECT_EQ(d.AsString(), R"(%1 = 3 == 4 )"); } @@ -1523,7 +1523,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_NotEqual) { ASSERT_TRUE(r); Disassembler d; - d.EmitBlockOps(b.current_flow_block); + d.EmitBlockInstructions(b.current_flow_block); EXPECT_EQ(d.AsString(), R"(%1 = 3 != 4 )"); } @@ -1534,7 +1534,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LessThan) { ASSERT_TRUE(r); Disassembler d; - d.EmitBlockOps(b.current_flow_block); + d.EmitBlockInstructions(b.current_flow_block); EXPECT_EQ(d.AsString(), R"(%1 = 3 < 4 )"); } @@ -1545,7 +1545,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_GreaterThan) { ASSERT_TRUE(r); Disassembler d; - d.EmitBlockOps(b.current_flow_block); + d.EmitBlockInstructions(b.current_flow_block); EXPECT_EQ(d.AsString(), R"(%1 = 3 > 4 )"); } @@ -1556,7 +1556,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LessThanEqual) { ASSERT_TRUE(r); Disassembler d; - d.EmitBlockOps(b.current_flow_block); + d.EmitBlockInstructions(b.current_flow_block); EXPECT_EQ(d.AsString(), R"(%1 = 3 <= 4 )"); } @@ -1567,7 +1567,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_GreaterThanEqual) { ASSERT_TRUE(r); Disassembler d; - d.EmitBlockOps(b.current_flow_block); + d.EmitBlockInstructions(b.current_flow_block); EXPECT_EQ(d.AsString(), R"(%1 = 3 >= 4 )"); } @@ -1578,7 +1578,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_ShiftLeft) { ASSERT_TRUE(r); Disassembler d; - d.EmitBlockOps(b.current_flow_block); + d.EmitBlockInstructions(b.current_flow_block); EXPECT_EQ(d.AsString(), R"(%1 = 3 << 4 )"); } @@ -1589,7 +1589,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_ShiftRight) { ASSERT_TRUE(r); Disassembler d; - d.EmitBlockOps(b.current_flow_block); + d.EmitBlockInstructions(b.current_flow_block); EXPECT_EQ(d.AsString(), R"(%1 = 3 >> 4 )"); } @@ -1601,7 +1601,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Compound) { ASSERT_TRUE(r); Disassembler d; - d.EmitBlockOps(b.current_flow_block); + d.EmitBlockInstructions(b.current_flow_block); EXPECT_EQ(d.AsString(), R"(%1 = 3 >> 4 %2 = %1 + 9 %3 = 1 < %2 diff --git a/src/tint/ir/disassembler.cc b/src/tint/ir/disassembler.cc index a648d68510..f98950fac0 100644 --- a/src/tint/ir/disassembler.cc +++ b/src/tint/ir/disassembler.cc @@ -61,9 +61,9 @@ std::ostream& Disassembler::Indent() { return out_; } -void Disassembler::EmitBlockOps(const Block* b) { - for (const auto& op : b->ops) { - out_ << op << std::endl; +void Disassembler::EmitBlockInstructions(const Block* b) { + for (const auto& instr : b->instructions) { + out_ << instr << std::endl; } } @@ -87,7 +87,7 @@ void Disassembler::Walk(const FlowNode* node) { }, [&](const ir::Block* b) { Indent() << "Block" << std::endl; - EmitBlockOps(b); + EmitBlockInstructions(b); Walk(b->branch_target); }, [&](const ir::Switch* s) { diff --git a/src/tint/ir/disassembler.h b/src/tint/ir/disassembler.h index 9cb8993fec..e24524a005 100644 --- a/src/tint/ir/disassembler.h +++ b/src/tint/ir/disassembler.h @@ -36,9 +36,9 @@ class Disassembler { /// @returns the string representation of the module std::string Disassemble(const Module& mod); - /// Writes the block ops to the stream - /// @param b the block containing the ops - void EmitBlockOps(const Block* b); + /// Writes the block instructions to the stream + /// @param b the block containing the instructions + void EmitBlockInstructions(const Block* b); /// @returns the string representation std::string AsString() const { return out_.str(); } diff --git a/src/tint/ir/if.h b/src/tint/ir/if.h index 109b990dce..4b2969ddac 100644 --- a/src/tint/ir/if.h +++ b/src/tint/ir/if.h @@ -17,7 +17,7 @@ #include "src/tint/ast/if_statement.h" #include "src/tint/ir/flow_node.h" -#include "src/tint/ir/register.h" +#include "src/tint/ir/value.h" // Forward declarations namespace tint::ir { @@ -44,8 +44,8 @@ class If : public Castable { /// An block to reconvert the true/false barnches. The block always exists, but there maybe no /// branches into it. (e.g. if both branches `return`) Block* merge_target = nullptr; - /// Register holding the condition result - Register condition; + /// Value holding the condition result + Value condition; }; } // namespace tint::ir diff --git a/src/tint/ir/op.cc b/src/tint/ir/instruction.cc similarity index 51% rename from src/tint/ir/op.cc rename to src/tint/ir/instruction.cc index 3e6d9936ee..9460f39f95 100644 --- a/src/tint/ir/op.cc +++ b/src/tint/ir/instruction.cc @@ -12,91 +12,91 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "src/tint/ir/op.h" +#include "src/tint/ir/instruction.h" namespace tint::ir { -Op::Op() {} +Instruction::Instruction() {} -Op::Op(Kind kind, Register result, Register lhs, Register rhs) +Instruction::Instruction(Kind kind, Value result, Value lhs, Value rhs) : kind_(kind), result_(result), args_({lhs, rhs}) {} -Op::Op(const Op&) = default; +Instruction::Instruction(const Instruction&) = default; -Op::Op(Op&& o) = default; +Instruction::Instruction(Instruction&& instr) = default; -Op::~Op() = default; +Instruction::~Instruction() = default; -Op& Op::operator=(const Op& o) = default; +Instruction& Instruction::operator=(const Instruction& instr) = default; -Op& Op::operator=(Op&& o) = default; +Instruction& Instruction::operator=(Instruction&& instr) = default; -std::ostream& operator<<(std::ostream& out, const Op& op) { - out << op.Result() << " = "; - if (op.HasLHS()) { - out << op.LHS(); +std::ostream& operator<<(std::ostream& out, const Instruction& instr) { + out << instr.Result() << " = "; + if (instr.HasLHS()) { + out << instr.LHS(); } out << " "; - switch (op.GetKind()) { - case Op::Kind::kAdd: + switch (instr.GetKind()) { + case Instruction::Kind::kAdd: out << "+"; break; - case Op::Kind::kSubtract: + case Instruction::Kind::kSubtract: out << "-"; break; - case Op::Kind::kMultiply: + case Instruction::Kind::kMultiply: out << "*"; break; - case Op::Kind::kDivide: + case Instruction::Kind::kDivide: out << "/"; break; - case Op::Kind::kModulo: + case Instruction::Kind::kModulo: out << "%"; break; - case Op::Kind::kAnd: + case Instruction::Kind::kAnd: out << "&"; break; - case Op::Kind::kOr: + case Instruction::Kind::kOr: out << "|"; break; - case Op::Kind::kXor: + case Instruction::Kind::kXor: out << "^"; break; - case Op::Kind::kLogicalAnd: + case Instruction::Kind::kLogicalAnd: out << "&&"; break; - case Op::Kind::kLogicalOr: + case Instruction::Kind::kLogicalOr: out << "||"; break; - case Op::Kind::kEqual: + case Instruction::Kind::kEqual: out << "=="; break; - case Op::Kind::kNotEqual: + case Instruction::Kind::kNotEqual: out << "!="; break; - case Op::Kind::kLessThan: + case Instruction::Kind::kLessThan: out << "<"; break; - case Op::Kind::kGreaterThan: + case Instruction::Kind::kGreaterThan: out << ">"; break; - case Op::Kind::kLessThanEqual: + case Instruction::Kind::kLessThanEqual: out << "<="; break; - case Op::Kind::kGreaterThanEqual: + case Instruction::Kind::kGreaterThanEqual: out << ">="; break; - case Op::Kind::kShiftLeft: + case Instruction::Kind::kShiftLeft: out << "<<"; break; - case Op::Kind::kShiftRight: + case Instruction::Kind::kShiftRight: out << ">>"; break; } - if (op.HasRHS()) { - out << " " << op.RHS(); + if (instr.HasRHS()) { + out << " " << instr.RHS(); } return out; diff --git a/src/tint/ir/op.h b/src/tint/ir/instruction.h similarity index 53% rename from src/tint/ir/op.h rename to src/tint/ir/instruction.h index a9fc78ffd4..b62300c0cc 100644 --- a/src/tint/ir/op.h +++ b/src/tint/ir/instruction.h @@ -12,20 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef SRC_TINT_IR_OP_H_ -#define SRC_TINT_IR_OP_H_ +#ifndef SRC_TINT_IR_INSTRUCTION_H_ +#define SRC_TINT_IR_INSTRUCTION_H_ #include -#include "src/tint/ir/register.h" +#include "src/tint/ir/value.h" #include "src/tint/utils/vector.h" namespace tint::ir { -/// An operation in the IR. -class Op { +/// An instruction in the IR. +class Instruction { public: - /// The kind of operation. + /// The kind of instruction. enum class Kind { kAdd, kSubtract, @@ -52,49 +52,49 @@ class Op { }; /// Constructor - Op(); + Instruction(); /// Constructor - /// @param kind the kind of operation - /// @param result the result register - /// @param lhs the lhs of the operation - /// @param rhs the rhs of the operation - Op(Kind kind, Register result, Register lhs, Register rhs); + /// @param kind the kind of instruction + /// @param result the result value + /// @param lhs the lhs of the instruction + /// @param rhs the rhs of the instruction + Instruction(Kind kind, Value result, Value lhs, Value rhs); /// Copy constructor - /// @param o the op to copy from - Op(const Op& o); + /// @param instr the instruction to copy from + Instruction(const Instruction& instr); /// Move constructor - /// @param o the op to move from - Op(Op&& o); + /// @param instr the instruction to move from + Instruction(Instruction&& instr); /// Destructor - ~Op(); + ~Instruction(); /// Copy assign - /// @param o the op to copy from + /// @param instr the instruction to copy from /// @returns a reference to this - Op& operator=(const Op& o); + Instruction& operator=(const Instruction& instr); /// Move assign - /// @param o the op to move from + /// @param instr the instruction to move from /// @returns a reference to this - Op& operator=(Op&& o); + Instruction& operator=(Instruction&& instr); - /// @returns the kind of operation + /// @returns the kind of instruction Kind GetKind() const { return kind_; } - /// @returns the result register for the operation - const Register& Result() const { return result_; } + /// @returns the result value for the instruction + const Value& Result() const { return result_; } - /// @returns true if the op has a LHS + /// @returns true if the instruction has a LHS bool HasLHS() const { return args_.Length() >= 1; } - /// @returns the left-hand-side register for the operation - const Register& LHS() const { + /// @returns the left-hand-side value for the instruction + const Value& LHS() const { TINT_ASSERT(IR, HasLHS()); return args_[0]; } - /// @returns true if the op has a RHS + /// @returns true if the instruction has a RHS bool HasRHS() const { return args_.Length() >= 2; } - /// @returns the right-hand-side register for the operation - const Register& RHS() const { + /// @returns the right-hand-side value for the instruction + const Value& RHS() const { TINT_ASSERT(IR, HasRHS()); return args_[1]; } @@ -102,12 +102,12 @@ class Op { private: Kind kind_; - Register result_; - utils::Vector args_; + Value result_; + utils::Vector args_; }; -std::ostream& operator<<(std::ostream& out, const Op&); +std::ostream& operator<<(std::ostream& out, const Instruction&); } // namespace tint::ir -#endif // SRC_TINT_IR_OP_H_ +#endif // SRC_TINT_IR_INSTRUCTION_H_ diff --git a/src/tint/ir/instruction_test.cc b/src/tint/ir/instruction_test.cc new file mode 100644 index 0000000000..8fdd541ae2 --- /dev/null +++ b/src/tint/ir/instruction_test.cc @@ -0,0 +1,494 @@ +// Copyright 2022 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "src/tint/ir/instruction.h" +#include "src/tint/ir/test_helper.h" + +namespace tint::ir { +namespace { + +using IR_InstructionTest = TestHelper; + +TEST_F(IR_InstructionTest, CreateAnd) { + auto& b = CreateEmptyBuilder(); + + b.builder.next_value_id = Value::Id(42); + auto instr = b.builder.And(Value(i32(4)), Value(i32(2))); + + EXPECT_EQ(instr.GetKind(), Instruction::Kind::kAnd); + + ASSERT_TRUE(instr.Result().IsTemp()); + EXPECT_EQ(Value::Id(42), instr.Result().AsId()); + + ASSERT_TRUE(instr.HasLHS()); + auto& lhs = instr.LHS(); + ASSERT_TRUE(lhs.IsI32()); + EXPECT_EQ(i32(4), lhs.AsI32()); + + ASSERT_TRUE(instr.HasRHS()); + auto& rhs = instr.RHS(); + ASSERT_TRUE(rhs.IsI32()); + EXPECT_EQ(i32(2), rhs.AsI32()); + + std::stringstream str; + str << instr; + EXPECT_EQ(str.str(), "%42 = 4 & 2"); +} + +TEST_F(IR_InstructionTest, CreateOr) { + auto& b = CreateEmptyBuilder(); + + b.builder.next_value_id = Value::Id(42); + auto instr = b.builder.Or(Value(i32(4)), Value(i32(2))); + + EXPECT_EQ(instr.GetKind(), Instruction::Kind::kOr); + + ASSERT_TRUE(instr.Result().IsTemp()); + EXPECT_EQ(Value::Id(42), instr.Result().AsId()); + + ASSERT_TRUE(instr.HasLHS()); + auto& lhs = instr.LHS(); + ASSERT_TRUE(lhs.IsI32()); + EXPECT_EQ(i32(4), lhs.AsI32()); + + ASSERT_TRUE(instr.HasRHS()); + auto& rhs = instr.RHS(); + ASSERT_TRUE(rhs.IsI32()); + EXPECT_EQ(i32(2), rhs.AsI32()); + + std::stringstream str; + str << instr; + EXPECT_EQ(str.str(), "%42 = 4 | 2"); +} + +TEST_F(IR_InstructionTest, CreateXor) { + auto& b = CreateEmptyBuilder(); + + b.builder.next_value_id = Value::Id(42); + auto instr = b.builder.Xor(Value(i32(4)), Value(i32(2))); + + EXPECT_EQ(instr.GetKind(), Instruction::Kind::kXor); + + ASSERT_TRUE(instr.Result().IsTemp()); + EXPECT_EQ(Value::Id(42), instr.Result().AsId()); + + ASSERT_TRUE(instr.HasLHS()); + auto& lhs = instr.LHS(); + ASSERT_TRUE(lhs.IsI32()); + EXPECT_EQ(i32(4), lhs.AsI32()); + + ASSERT_TRUE(instr.HasRHS()); + auto& rhs = instr.RHS(); + ASSERT_TRUE(rhs.IsI32()); + EXPECT_EQ(i32(2), rhs.AsI32()); + + std::stringstream str; + str << instr; + EXPECT_EQ(str.str(), "%42 = 4 ^ 2"); +} + +TEST_F(IR_InstructionTest, CreateLogicalAnd) { + auto& b = CreateEmptyBuilder(); + + b.builder.next_value_id = Value::Id(42); + auto instr = b.builder.LogicalAnd(Value(i32(4)), Value(i32(2))); + + EXPECT_EQ(instr.GetKind(), Instruction::Kind::kLogicalAnd); + + ASSERT_TRUE(instr.Result().IsTemp()); + EXPECT_EQ(Value::Id(42), instr.Result().AsId()); + + ASSERT_TRUE(instr.HasLHS()); + auto& lhs = instr.LHS(); + ASSERT_TRUE(lhs.IsI32()); + EXPECT_EQ(i32(4), lhs.AsI32()); + + ASSERT_TRUE(instr.HasRHS()); + auto& rhs = instr.RHS(); + ASSERT_TRUE(rhs.IsI32()); + EXPECT_EQ(i32(2), rhs.AsI32()); + + std::stringstream str; + str << instr; + EXPECT_EQ(str.str(), "%42 = 4 && 2"); +} + +TEST_F(IR_InstructionTest, CreateLogicalOr) { + auto& b = CreateEmptyBuilder(); + + b.builder.next_value_id = Value::Id(42); + auto instr = b.builder.LogicalOr(Value(i32(4)), Value(i32(2))); + + EXPECT_EQ(instr.GetKind(), Instruction::Kind::kLogicalOr); + + ASSERT_TRUE(instr.Result().IsTemp()); + EXPECT_EQ(Value::Id(42), instr.Result().AsId()); + + ASSERT_TRUE(instr.HasLHS()); + auto& lhs = instr.LHS(); + ASSERT_TRUE(lhs.IsI32()); + EXPECT_EQ(i32(4), lhs.AsI32()); + + ASSERT_TRUE(instr.HasRHS()); + auto& rhs = instr.RHS(); + ASSERT_TRUE(rhs.IsI32()); + EXPECT_EQ(i32(2), rhs.AsI32()); + + std::stringstream str; + str << instr; + EXPECT_EQ(str.str(), "%42 = 4 || 2"); +} + +TEST_F(IR_InstructionTest, CreateEqual) { + auto& b = CreateEmptyBuilder(); + + b.builder.next_value_id = Value::Id(42); + auto instr = b.builder.Equal(Value(i32(4)), Value(i32(2))); + + EXPECT_EQ(instr.GetKind(), Instruction::Kind::kEqual); + + ASSERT_TRUE(instr.Result().IsTemp()); + EXPECT_EQ(Value::Id(42), instr.Result().AsId()); + + ASSERT_TRUE(instr.HasLHS()); + auto& lhs = instr.LHS(); + ASSERT_TRUE(lhs.IsI32()); + EXPECT_EQ(i32(4), lhs.AsI32()); + + ASSERT_TRUE(instr.HasRHS()); + auto& rhs = instr.RHS(); + ASSERT_TRUE(rhs.IsI32()); + EXPECT_EQ(i32(2), rhs.AsI32()); + + std::stringstream str; + str << instr; + EXPECT_EQ(str.str(), "%42 = 4 == 2"); +} + +TEST_F(IR_InstructionTest, CreateNotEqual) { + auto& b = CreateEmptyBuilder(); + + b.builder.next_value_id = Value::Id(42); + auto instr = b.builder.NotEqual(Value(i32(4)), Value(i32(2))); + + EXPECT_EQ(instr.GetKind(), Instruction::Kind::kNotEqual); + + ASSERT_TRUE(instr.Result().IsTemp()); + EXPECT_EQ(Value::Id(42), instr.Result().AsId()); + + ASSERT_TRUE(instr.HasLHS()); + auto& lhs = instr.LHS(); + ASSERT_TRUE(lhs.IsI32()); + EXPECT_EQ(i32(4), lhs.AsI32()); + + ASSERT_TRUE(instr.HasRHS()); + auto& rhs = instr.RHS(); + ASSERT_TRUE(rhs.IsI32()); + EXPECT_EQ(i32(2), rhs.AsI32()); + + std::stringstream str; + str << instr; + EXPECT_EQ(str.str(), "%42 = 4 != 2"); +} + +TEST_F(IR_InstructionTest, CreateLessThan) { + auto& b = CreateEmptyBuilder(); + + b.builder.next_value_id = Value::Id(42); + auto instr = b.builder.LessThan(Value(i32(4)), Value(i32(2))); + + EXPECT_EQ(instr.GetKind(), Instruction::Kind::kLessThan); + + ASSERT_TRUE(instr.Result().IsTemp()); + EXPECT_EQ(Value::Id(42), instr.Result().AsId()); + + ASSERT_TRUE(instr.HasLHS()); + auto& lhs = instr.LHS(); + ASSERT_TRUE(lhs.IsI32()); + EXPECT_EQ(i32(4), lhs.AsI32()); + + ASSERT_TRUE(instr.HasRHS()); + auto& rhs = instr.RHS(); + ASSERT_TRUE(rhs.IsI32()); + EXPECT_EQ(i32(2), rhs.AsI32()); + + std::stringstream str; + str << instr; + EXPECT_EQ(str.str(), "%42 = 4 < 2"); +} + +TEST_F(IR_InstructionTest, CreateGreaterThan) { + auto& b = CreateEmptyBuilder(); + + b.builder.next_value_id = Value::Id(42); + auto instr = b.builder.GreaterThan(Value(i32(4)), Value(i32(2))); + + EXPECT_EQ(instr.GetKind(), Instruction::Kind::kGreaterThan); + + ASSERT_TRUE(instr.Result().IsTemp()); + EXPECT_EQ(Value::Id(42), instr.Result().AsId()); + + ASSERT_TRUE(instr.HasLHS()); + auto& lhs = instr.LHS(); + ASSERT_TRUE(lhs.IsI32()); + EXPECT_EQ(i32(4), lhs.AsI32()); + + ASSERT_TRUE(instr.HasRHS()); + auto& rhs = instr.RHS(); + ASSERT_TRUE(rhs.IsI32()); + EXPECT_EQ(i32(2), rhs.AsI32()); + + std::stringstream str; + str << instr; + EXPECT_EQ(str.str(), "%42 = 4 > 2"); +} + +TEST_F(IR_InstructionTest, CreateLessThanEqual) { + auto& b = CreateEmptyBuilder(); + + b.builder.next_value_id = Value::Id(42); + auto instr = b.builder.LessThanEqual(Value(i32(4)), Value(i32(2))); + + EXPECT_EQ(instr.GetKind(), Instruction::Kind::kLessThanEqual); + + ASSERT_TRUE(instr.Result().IsTemp()); + EXPECT_EQ(Value::Id(42), instr.Result().AsId()); + + ASSERT_TRUE(instr.HasLHS()); + auto& lhs = instr.LHS(); + ASSERT_TRUE(lhs.IsI32()); + EXPECT_EQ(i32(4), lhs.AsI32()); + + ASSERT_TRUE(instr.HasRHS()); + auto& rhs = instr.RHS(); + ASSERT_TRUE(rhs.IsI32()); + EXPECT_EQ(i32(2), rhs.AsI32()); + + std::stringstream str; + str << instr; + EXPECT_EQ(str.str(), "%42 = 4 <= 2"); +} + +TEST_F(IR_InstructionTest, CreateGreaterThanEqual) { + auto& b = CreateEmptyBuilder(); + + b.builder.next_value_id = Value::Id(42); + auto instr = b.builder.GreaterThanEqual(Value(i32(4)), Value(i32(2))); + + EXPECT_EQ(instr.GetKind(), Instruction::Kind::kGreaterThanEqual); + + ASSERT_TRUE(instr.Result().IsTemp()); + EXPECT_EQ(Value::Id(42), instr.Result().AsId()); + + ASSERT_TRUE(instr.HasLHS()); + auto& lhs = instr.LHS(); + ASSERT_TRUE(lhs.IsI32()); + EXPECT_EQ(i32(4), lhs.AsI32()); + + ASSERT_TRUE(instr.HasRHS()); + auto& rhs = instr.RHS(); + ASSERT_TRUE(rhs.IsI32()); + EXPECT_EQ(i32(2), rhs.AsI32()); + + std::stringstream str; + str << instr; + EXPECT_EQ(str.str(), "%42 = 4 >= 2"); +} + +TEST_F(IR_InstructionTest, CreateShiftLeft) { + auto& b = CreateEmptyBuilder(); + + b.builder.next_value_id = Value::Id(42); + auto instr = b.builder.ShiftLeft(Value(i32(4)), Value(i32(2))); + + EXPECT_EQ(instr.GetKind(), Instruction::Kind::kShiftLeft); + + ASSERT_TRUE(instr.Result().IsTemp()); + EXPECT_EQ(Value::Id(42), instr.Result().AsId()); + + ASSERT_TRUE(instr.HasLHS()); + auto& lhs = instr.LHS(); + ASSERT_TRUE(lhs.IsI32()); + EXPECT_EQ(i32(4), lhs.AsI32()); + + ASSERT_TRUE(instr.HasRHS()); + auto& rhs = instr.RHS(); + ASSERT_TRUE(rhs.IsI32()); + EXPECT_EQ(i32(2), rhs.AsI32()); + + std::stringstream str; + str << instr; + EXPECT_EQ(str.str(), "%42 = 4 << 2"); +} + +TEST_F(IR_InstructionTest, CreateShiftRight) { + auto& b = CreateEmptyBuilder(); + + b.builder.next_value_id = Value::Id(42); + auto instr = b.builder.ShiftRight(Value(i32(4)), Value(i32(2))); + + EXPECT_EQ(instr.GetKind(), Instruction::Kind::kShiftRight); + + ASSERT_TRUE(instr.Result().IsTemp()); + EXPECT_EQ(Value::Id(42), instr.Result().AsId()); + + ASSERT_TRUE(instr.HasLHS()); + auto& lhs = instr.LHS(); + ASSERT_TRUE(lhs.IsI32()); + EXPECT_EQ(i32(4), lhs.AsI32()); + + ASSERT_TRUE(instr.HasRHS()); + auto& rhs = instr.RHS(); + ASSERT_TRUE(rhs.IsI32()); + EXPECT_EQ(i32(2), rhs.AsI32()); + + std::stringstream str; + str << instr; + EXPECT_EQ(str.str(), "%42 = 4 >> 2"); +} + +TEST_F(IR_InstructionTest, CreateAdd) { + auto& b = CreateEmptyBuilder(); + + b.builder.next_value_id = Value::Id(42); + auto instr = b.builder.Add(Value(i32(4)), Value(i32(2))); + + EXPECT_EQ(instr.GetKind(), Instruction::Kind::kAdd); + + ASSERT_TRUE(instr.Result().IsTemp()); + EXPECT_EQ(Value::Id(42), instr.Result().AsId()); + + ASSERT_TRUE(instr.HasLHS()); + auto& lhs = instr.LHS(); + ASSERT_TRUE(lhs.IsI32()); + EXPECT_EQ(i32(4), lhs.AsI32()); + + ASSERT_TRUE(instr.HasRHS()); + auto& rhs = instr.RHS(); + ASSERT_TRUE(rhs.IsI32()); + EXPECT_EQ(i32(2), rhs.AsI32()); + + std::stringstream str; + str << instr; + EXPECT_EQ(str.str(), "%42 = 4 + 2"); +} + +TEST_F(IR_InstructionTest, CreateSubtract) { + auto& b = CreateEmptyBuilder(); + + b.builder.next_value_id = Value::Id(42); + auto instr = b.builder.Subtract(Value(i32(4)), Value(i32(2))); + + EXPECT_EQ(instr.GetKind(), Instruction::Kind::kSubtract); + + ASSERT_TRUE(instr.Result().IsTemp()); + EXPECT_EQ(Value::Id(42), instr.Result().AsId()); + + ASSERT_TRUE(instr.HasLHS()); + auto& lhs = instr.LHS(); + ASSERT_TRUE(lhs.IsI32()); + EXPECT_EQ(i32(4), lhs.AsI32()); + + ASSERT_TRUE(instr.HasRHS()); + auto& rhs = instr.RHS(); + ASSERT_TRUE(rhs.IsI32()); + EXPECT_EQ(i32(2), rhs.AsI32()); + + std::stringstream str; + str << instr; + EXPECT_EQ(str.str(), "%42 = 4 - 2"); +} + +TEST_F(IR_InstructionTest, CreateMultiply) { + auto& b = CreateEmptyBuilder(); + + b.builder.next_value_id = Value::Id(42); + auto instr = b.builder.Multiply(Value(i32(4)), Value(i32(2))); + + EXPECT_EQ(instr.GetKind(), Instruction::Kind::kMultiply); + + ASSERT_TRUE(instr.Result().IsTemp()); + EXPECT_EQ(Value::Id(42), instr.Result().AsId()); + + ASSERT_TRUE(instr.HasLHS()); + auto& lhs = instr.LHS(); + ASSERT_TRUE(lhs.IsI32()); + EXPECT_EQ(i32(4), lhs.AsI32()); + + ASSERT_TRUE(instr.HasRHS()); + auto& rhs = instr.RHS(); + ASSERT_TRUE(rhs.IsI32()); + EXPECT_EQ(i32(2), rhs.AsI32()); + + std::stringstream str; + str << instr; + EXPECT_EQ(str.str(), "%42 = 4 * 2"); +} + +TEST_F(IR_InstructionTest, CreateDivide) { + auto& b = CreateEmptyBuilder(); + + b.builder.next_value_id = Value::Id(42); + auto instr = b.builder.Divide(Value(i32(4)), Value(i32(2))); + + EXPECT_EQ(instr.GetKind(), Instruction::Kind::kDivide); + + ASSERT_TRUE(instr.Result().IsTemp()); + EXPECT_EQ(Value::Id(42), instr.Result().AsId()); + + ASSERT_TRUE(instr.HasLHS()); + auto& lhs = instr.LHS(); + ASSERT_TRUE(lhs.IsI32()); + EXPECT_EQ(i32(4), lhs.AsI32()); + + ASSERT_TRUE(instr.HasRHS()); + auto& rhs = instr.RHS(); + ASSERT_TRUE(rhs.IsI32()); + EXPECT_EQ(i32(2), rhs.AsI32()); + + std::stringstream str; + str << instr; + EXPECT_EQ(str.str(), "%42 = 4 / 2"); +} + +TEST_F(IR_InstructionTest, CreateModulo) { + auto& b = CreateEmptyBuilder(); + + b.builder.next_value_id = Value::Id(42); + auto instr = b.builder.Modulo(Value(i32(4)), Value(i32(2))); + + EXPECT_EQ(instr.GetKind(), Instruction::Kind::kModulo); + + ASSERT_TRUE(instr.Result().IsTemp()); + EXPECT_EQ(Value::Id(42), instr.Result().AsId()); + + ASSERT_TRUE(instr.HasLHS()); + auto& lhs = instr.LHS(); + ASSERT_TRUE(lhs.IsI32()); + EXPECT_EQ(i32(4), lhs.AsI32()); + + ASSERT_TRUE(instr.HasRHS()); + auto& rhs = instr.RHS(); + ASSERT_TRUE(rhs.IsI32()); + EXPECT_EQ(i32(2), rhs.AsI32()); + + std::stringstream str; + str << instr; + EXPECT_EQ(str.str(), "%42 = 4 % 2"); +} + +} // namespace +} // namespace tint::ir diff --git a/src/tint/ir/op_test.cc b/src/tint/ir/op_test.cc deleted file mode 100644 index 01604d12c0..0000000000 --- a/src/tint/ir/op_test.cc +++ /dev/null @@ -1,494 +0,0 @@ -// Copyright 2022 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include - -#include "src/tint/ir/op.h" -#include "src/tint/ir/test_helper.h" - -namespace tint::ir { -namespace { - -using IR_OpTest = TestHelper; - -TEST_F(IR_OpTest, CreateAnd) { - auto& b = CreateEmptyBuilder(); - - b.builder.next_register_id = Register::Id(42); - auto o = b.builder.And(Register(i32(4)), Register(i32(2))); - - EXPECT_EQ(o.GetKind(), Op::Kind::kAnd); - - ASSERT_TRUE(o.Result().IsTemp()); - EXPECT_EQ(Register::Id(42), o.Result().AsId()); - - ASSERT_TRUE(o.HasLHS()); - auto& lhs = o.LHS(); - ASSERT_TRUE(lhs.IsI32()); - EXPECT_EQ(i32(4), lhs.AsI32()); - - ASSERT_TRUE(o.HasRHS()); - auto& rhs = o.RHS(); - ASSERT_TRUE(rhs.IsI32()); - EXPECT_EQ(i32(2), rhs.AsI32()); - - std::stringstream str; - str << o; - EXPECT_EQ(str.str(), "%42 = 4 & 2"); -} - -TEST_F(IR_OpTest, CreateOr) { - auto& b = CreateEmptyBuilder(); - - b.builder.next_register_id = Register::Id(42); - auto o = b.builder.Or(Register(i32(4)), Register(i32(2))); - - EXPECT_EQ(o.GetKind(), Op::Kind::kOr); - - ASSERT_TRUE(o.Result().IsTemp()); - EXPECT_EQ(Register::Id(42), o.Result().AsId()); - - ASSERT_TRUE(o.HasLHS()); - auto& lhs = o.LHS(); - ASSERT_TRUE(lhs.IsI32()); - EXPECT_EQ(i32(4), lhs.AsI32()); - - ASSERT_TRUE(o.HasRHS()); - auto& rhs = o.RHS(); - ASSERT_TRUE(rhs.IsI32()); - EXPECT_EQ(i32(2), rhs.AsI32()); - - std::stringstream str; - str << o; - EXPECT_EQ(str.str(), "%42 = 4 | 2"); -} - -TEST_F(IR_OpTest, CreateXor) { - auto& b = CreateEmptyBuilder(); - - b.builder.next_register_id = Register::Id(42); - auto o = b.builder.Xor(Register(i32(4)), Register(i32(2))); - - EXPECT_EQ(o.GetKind(), Op::Kind::kXor); - - ASSERT_TRUE(o.Result().IsTemp()); - EXPECT_EQ(Register::Id(42), o.Result().AsId()); - - ASSERT_TRUE(o.HasLHS()); - auto& lhs = o.LHS(); - ASSERT_TRUE(lhs.IsI32()); - EXPECT_EQ(i32(4), lhs.AsI32()); - - ASSERT_TRUE(o.HasRHS()); - auto& rhs = o.RHS(); - ASSERT_TRUE(rhs.IsI32()); - EXPECT_EQ(i32(2), rhs.AsI32()); - - std::stringstream str; - str << o; - EXPECT_EQ(str.str(), "%42 = 4 ^ 2"); -} - -TEST_F(IR_OpTest, CreateLogicalAnd) { - auto& b = CreateEmptyBuilder(); - - b.builder.next_register_id = Register::Id(42); - auto o = b.builder.LogicalAnd(Register(i32(4)), Register(i32(2))); - - EXPECT_EQ(o.GetKind(), Op::Kind::kLogicalAnd); - - ASSERT_TRUE(o.Result().IsTemp()); - EXPECT_EQ(Register::Id(42), o.Result().AsId()); - - ASSERT_TRUE(o.HasLHS()); - auto& lhs = o.LHS(); - ASSERT_TRUE(lhs.IsI32()); - EXPECT_EQ(i32(4), lhs.AsI32()); - - ASSERT_TRUE(o.HasRHS()); - auto& rhs = o.RHS(); - ASSERT_TRUE(rhs.IsI32()); - EXPECT_EQ(i32(2), rhs.AsI32()); - - std::stringstream str; - str << o; - EXPECT_EQ(str.str(), "%42 = 4 && 2"); -} - -TEST_F(IR_OpTest, CreateLogicalOr) { - auto& b = CreateEmptyBuilder(); - - b.builder.next_register_id = Register::Id(42); - auto o = b.builder.LogicalOr(Register(i32(4)), Register(i32(2))); - - EXPECT_EQ(o.GetKind(), Op::Kind::kLogicalOr); - - ASSERT_TRUE(o.Result().IsTemp()); - EXPECT_EQ(Register::Id(42), o.Result().AsId()); - - ASSERT_TRUE(o.HasLHS()); - auto& lhs = o.LHS(); - ASSERT_TRUE(lhs.IsI32()); - EXPECT_EQ(i32(4), lhs.AsI32()); - - ASSERT_TRUE(o.HasRHS()); - auto& rhs = o.RHS(); - ASSERT_TRUE(rhs.IsI32()); - EXPECT_EQ(i32(2), rhs.AsI32()); - - std::stringstream str; - str << o; - EXPECT_EQ(str.str(), "%42 = 4 || 2"); -} - -TEST_F(IR_OpTest, CreateEqual) { - auto& b = CreateEmptyBuilder(); - - b.builder.next_register_id = Register::Id(42); - auto o = b.builder.Equal(Register(i32(4)), Register(i32(2))); - - EXPECT_EQ(o.GetKind(), Op::Kind::kEqual); - - ASSERT_TRUE(o.Result().IsTemp()); - EXPECT_EQ(Register::Id(42), o.Result().AsId()); - - ASSERT_TRUE(o.HasLHS()); - auto& lhs = o.LHS(); - ASSERT_TRUE(lhs.IsI32()); - EXPECT_EQ(i32(4), lhs.AsI32()); - - ASSERT_TRUE(o.HasRHS()); - auto& rhs = o.RHS(); - ASSERT_TRUE(rhs.IsI32()); - EXPECT_EQ(i32(2), rhs.AsI32()); - - std::stringstream str; - str << o; - EXPECT_EQ(str.str(), "%42 = 4 == 2"); -} - -TEST_F(IR_OpTest, CreateNotEqual) { - auto& b = CreateEmptyBuilder(); - - b.builder.next_register_id = Register::Id(42); - auto o = b.builder.NotEqual(Register(i32(4)), Register(i32(2))); - - EXPECT_EQ(o.GetKind(), Op::Kind::kNotEqual); - - ASSERT_TRUE(o.Result().IsTemp()); - EXPECT_EQ(Register::Id(42), o.Result().AsId()); - - ASSERT_TRUE(o.HasLHS()); - auto& lhs = o.LHS(); - ASSERT_TRUE(lhs.IsI32()); - EXPECT_EQ(i32(4), lhs.AsI32()); - - ASSERT_TRUE(o.HasRHS()); - auto& rhs = o.RHS(); - ASSERT_TRUE(rhs.IsI32()); - EXPECT_EQ(i32(2), rhs.AsI32()); - - std::stringstream str; - str << o; - EXPECT_EQ(str.str(), "%42 = 4 != 2"); -} - -TEST_F(IR_OpTest, CreateLessThan) { - auto& b = CreateEmptyBuilder(); - - b.builder.next_register_id = Register::Id(42); - auto o = b.builder.LessThan(Register(i32(4)), Register(i32(2))); - - EXPECT_EQ(o.GetKind(), Op::Kind::kLessThan); - - ASSERT_TRUE(o.Result().IsTemp()); - EXPECT_EQ(Register::Id(42), o.Result().AsId()); - - ASSERT_TRUE(o.HasLHS()); - auto& lhs = o.LHS(); - ASSERT_TRUE(lhs.IsI32()); - EXPECT_EQ(i32(4), lhs.AsI32()); - - ASSERT_TRUE(o.HasRHS()); - auto& rhs = o.RHS(); - ASSERT_TRUE(rhs.IsI32()); - EXPECT_EQ(i32(2), rhs.AsI32()); - - std::stringstream str; - str << o; - EXPECT_EQ(str.str(), "%42 = 4 < 2"); -} - -TEST_F(IR_OpTest, CreateGreaterThan) { - auto& b = CreateEmptyBuilder(); - - b.builder.next_register_id = Register::Id(42); - auto o = b.builder.GreaterThan(Register(i32(4)), Register(i32(2))); - - EXPECT_EQ(o.GetKind(), Op::Kind::kGreaterThan); - - ASSERT_TRUE(o.Result().IsTemp()); - EXPECT_EQ(Register::Id(42), o.Result().AsId()); - - ASSERT_TRUE(o.HasLHS()); - auto& lhs = o.LHS(); - ASSERT_TRUE(lhs.IsI32()); - EXPECT_EQ(i32(4), lhs.AsI32()); - - ASSERT_TRUE(o.HasRHS()); - auto& rhs = o.RHS(); - ASSERT_TRUE(rhs.IsI32()); - EXPECT_EQ(i32(2), rhs.AsI32()); - - std::stringstream str; - str << o; - EXPECT_EQ(str.str(), "%42 = 4 > 2"); -} - -TEST_F(IR_OpTest, CreateLessThanEqual) { - auto& b = CreateEmptyBuilder(); - - b.builder.next_register_id = Register::Id(42); - auto o = b.builder.LessThanEqual(Register(i32(4)), Register(i32(2))); - - EXPECT_EQ(o.GetKind(), Op::Kind::kLessThanEqual); - - ASSERT_TRUE(o.Result().IsTemp()); - EXPECT_EQ(Register::Id(42), o.Result().AsId()); - - ASSERT_TRUE(o.HasLHS()); - auto& lhs = o.LHS(); - ASSERT_TRUE(lhs.IsI32()); - EXPECT_EQ(i32(4), lhs.AsI32()); - - ASSERT_TRUE(o.HasRHS()); - auto& rhs = o.RHS(); - ASSERT_TRUE(rhs.IsI32()); - EXPECT_EQ(i32(2), rhs.AsI32()); - - std::stringstream str; - str << o; - EXPECT_EQ(str.str(), "%42 = 4 <= 2"); -} - -TEST_F(IR_OpTest, CreateGreaterThanEqual) { - auto& b = CreateEmptyBuilder(); - - b.builder.next_register_id = Register::Id(42); - auto o = b.builder.GreaterThanEqual(Register(i32(4)), Register(i32(2))); - - EXPECT_EQ(o.GetKind(), Op::Kind::kGreaterThanEqual); - - ASSERT_TRUE(o.Result().IsTemp()); - EXPECT_EQ(Register::Id(42), o.Result().AsId()); - - ASSERT_TRUE(o.HasLHS()); - auto& lhs = o.LHS(); - ASSERT_TRUE(lhs.IsI32()); - EXPECT_EQ(i32(4), lhs.AsI32()); - - ASSERT_TRUE(o.HasRHS()); - auto& rhs = o.RHS(); - ASSERT_TRUE(rhs.IsI32()); - EXPECT_EQ(i32(2), rhs.AsI32()); - - std::stringstream str; - str << o; - EXPECT_EQ(str.str(), "%42 = 4 >= 2"); -} - -TEST_F(IR_OpTest, CreateShiftLeft) { - auto& b = CreateEmptyBuilder(); - - b.builder.next_register_id = Register::Id(42); - auto o = b.builder.ShiftLeft(Register(i32(4)), Register(i32(2))); - - EXPECT_EQ(o.GetKind(), Op::Kind::kShiftLeft); - - ASSERT_TRUE(o.Result().IsTemp()); - EXPECT_EQ(Register::Id(42), o.Result().AsId()); - - ASSERT_TRUE(o.HasLHS()); - auto& lhs = o.LHS(); - ASSERT_TRUE(lhs.IsI32()); - EXPECT_EQ(i32(4), lhs.AsI32()); - - ASSERT_TRUE(o.HasRHS()); - auto& rhs = o.RHS(); - ASSERT_TRUE(rhs.IsI32()); - EXPECT_EQ(i32(2), rhs.AsI32()); - - std::stringstream str; - str << o; - EXPECT_EQ(str.str(), "%42 = 4 << 2"); -} - -TEST_F(IR_OpTest, CreateShiftRight) { - auto& b = CreateEmptyBuilder(); - - b.builder.next_register_id = Register::Id(42); - auto o = b.builder.ShiftRight(Register(i32(4)), Register(i32(2))); - - EXPECT_EQ(o.GetKind(), Op::Kind::kShiftRight); - - ASSERT_TRUE(o.Result().IsTemp()); - EXPECT_EQ(Register::Id(42), o.Result().AsId()); - - ASSERT_TRUE(o.HasLHS()); - auto& lhs = o.LHS(); - ASSERT_TRUE(lhs.IsI32()); - EXPECT_EQ(i32(4), lhs.AsI32()); - - ASSERT_TRUE(o.HasRHS()); - auto& rhs = o.RHS(); - ASSERT_TRUE(rhs.IsI32()); - EXPECT_EQ(i32(2), rhs.AsI32()); - - std::stringstream str; - str << o; - EXPECT_EQ(str.str(), "%42 = 4 >> 2"); -} - -TEST_F(IR_OpTest, CreateAdd) { - auto& b = CreateEmptyBuilder(); - - b.builder.next_register_id = Register::Id(42); - auto o = b.builder.Add(Register(i32(4)), Register(i32(2))); - - EXPECT_EQ(o.GetKind(), Op::Kind::kAdd); - - ASSERT_TRUE(o.Result().IsTemp()); - EXPECT_EQ(Register::Id(42), o.Result().AsId()); - - ASSERT_TRUE(o.HasLHS()); - auto& lhs = o.LHS(); - ASSERT_TRUE(lhs.IsI32()); - EXPECT_EQ(i32(4), lhs.AsI32()); - - ASSERT_TRUE(o.HasRHS()); - auto& rhs = o.RHS(); - ASSERT_TRUE(rhs.IsI32()); - EXPECT_EQ(i32(2), rhs.AsI32()); - - std::stringstream str; - str << o; - EXPECT_EQ(str.str(), "%42 = 4 + 2"); -} - -TEST_F(IR_OpTest, CreateSubtract) { - auto& b = CreateEmptyBuilder(); - - b.builder.next_register_id = Register::Id(42); - auto o = b.builder.Subtract(Register(i32(4)), Register(i32(2))); - - EXPECT_EQ(o.GetKind(), Op::Kind::kSubtract); - - ASSERT_TRUE(o.Result().IsTemp()); - EXPECT_EQ(Register::Id(42), o.Result().AsId()); - - ASSERT_TRUE(o.HasLHS()); - auto& lhs = o.LHS(); - ASSERT_TRUE(lhs.IsI32()); - EXPECT_EQ(i32(4), lhs.AsI32()); - - ASSERT_TRUE(o.HasRHS()); - auto& rhs = o.RHS(); - ASSERT_TRUE(rhs.IsI32()); - EXPECT_EQ(i32(2), rhs.AsI32()); - - std::stringstream str; - str << o; - EXPECT_EQ(str.str(), "%42 = 4 - 2"); -} - -TEST_F(IR_OpTest, CreateMultiply) { - auto& b = CreateEmptyBuilder(); - - b.builder.next_register_id = Register::Id(42); - auto o = b.builder.Multiply(Register(i32(4)), Register(i32(2))); - - EXPECT_EQ(o.GetKind(), Op::Kind::kMultiply); - - ASSERT_TRUE(o.Result().IsTemp()); - EXPECT_EQ(Register::Id(42), o.Result().AsId()); - - ASSERT_TRUE(o.HasLHS()); - auto& lhs = o.LHS(); - ASSERT_TRUE(lhs.IsI32()); - EXPECT_EQ(i32(4), lhs.AsI32()); - - ASSERT_TRUE(o.HasRHS()); - auto& rhs = o.RHS(); - ASSERT_TRUE(rhs.IsI32()); - EXPECT_EQ(i32(2), rhs.AsI32()); - - std::stringstream str; - str << o; - EXPECT_EQ(str.str(), "%42 = 4 * 2"); -} - -TEST_F(IR_OpTest, CreateDivide) { - auto& b = CreateEmptyBuilder(); - - b.builder.next_register_id = Register::Id(42); - auto o = b.builder.Divide(Register(i32(4)), Register(i32(2))); - - EXPECT_EQ(o.GetKind(), Op::Kind::kDivide); - - ASSERT_TRUE(o.Result().IsTemp()); - EXPECT_EQ(Register::Id(42), o.Result().AsId()); - - ASSERT_TRUE(o.HasLHS()); - auto& lhs = o.LHS(); - ASSERT_TRUE(lhs.IsI32()); - EXPECT_EQ(i32(4), lhs.AsI32()); - - ASSERT_TRUE(o.HasRHS()); - auto& rhs = o.RHS(); - ASSERT_TRUE(rhs.IsI32()); - EXPECT_EQ(i32(2), rhs.AsI32()); - - std::stringstream str; - str << o; - EXPECT_EQ(str.str(), "%42 = 4 / 2"); -} - -TEST_F(IR_OpTest, CreateModulo) { - auto& b = CreateEmptyBuilder(); - - b.builder.next_register_id = Register::Id(42); - auto o = b.builder.Modulo(Register(i32(4)), Register(i32(2))); - - EXPECT_EQ(o.GetKind(), Op::Kind::kModulo); - - ASSERT_TRUE(o.Result().IsTemp()); - EXPECT_EQ(Register::Id(42), o.Result().AsId()); - - ASSERT_TRUE(o.HasLHS()); - auto& lhs = o.LHS(); - ASSERT_TRUE(lhs.IsI32()); - EXPECT_EQ(i32(4), lhs.AsI32()); - - ASSERT_TRUE(o.HasRHS()); - auto& rhs = o.RHS(); - ASSERT_TRUE(rhs.IsI32()); - EXPECT_EQ(i32(2), rhs.AsI32()); - - std::stringstream str; - str << o; - EXPECT_EQ(str.str(), "%42 = 4 % 2"); -} - -} // namespace -} // namespace tint::ir diff --git a/src/tint/ir/register_test.cc b/src/tint/ir/register_test.cc deleted file mode 100644 index fb0194f89d..0000000000 --- a/src/tint/ir/register_test.cc +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright 2022 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include - -#include "src/tint/ir/register.h" -#include "src/tint/ir/test_helper.h" - -namespace tint::ir { -namespace { - -using namespace tint::number_suffixes; // NOLINT - -using IR_RegisterTest = TestHelper; - -TEST_F(IR_RegisterTest, f32) { - std::stringstream str; - - Register r(1.2_f); - EXPECT_EQ(1.2_f, r.AsF32()); - - str << r; - EXPECT_EQ("1.200000", str.str()); - - EXPECT_TRUE(r.IsF32()); - EXPECT_FALSE(r.IsF16()); - EXPECT_FALSE(r.IsI32()); - EXPECT_FALSE(r.IsU32()); - EXPECT_FALSE(r.IsTemp()); - EXPECT_FALSE(r.IsVar()); - EXPECT_FALSE(r.IsBool()); -} - -TEST_F(IR_RegisterTest, f16) { - std::stringstream str; - - Register r(1.1_h); - EXPECT_EQ(1.1_h, r.AsF16()); - - str << r; - EXPECT_EQ("1.099609", str.str()); - - EXPECT_FALSE(r.IsF32()); - EXPECT_TRUE(r.IsF16()); - EXPECT_FALSE(r.IsI32()); - EXPECT_FALSE(r.IsU32()); - EXPECT_FALSE(r.IsTemp()); - EXPECT_FALSE(r.IsVar()); - EXPECT_FALSE(r.IsBool()); -} - -TEST_F(IR_RegisterTest, i32) { - std::stringstream str; - - Register r(1_i); - EXPECT_EQ(1_i, r.AsI32()); - - str << r; - EXPECT_EQ("1", str.str()); - - EXPECT_FALSE(r.IsF32()); - EXPECT_FALSE(r.IsF16()); - EXPECT_TRUE(r.IsI32()); - EXPECT_FALSE(r.IsU32()); - EXPECT_FALSE(r.IsTemp()); - EXPECT_FALSE(r.IsVar()); - EXPECT_FALSE(r.IsBool()); -} - -TEST_F(IR_RegisterTest, u32) { - std::stringstream str; - - Register r(2_u); - EXPECT_EQ(2_u, r.AsU32()); - - str << r; - EXPECT_EQ("2", str.str()); - - EXPECT_FALSE(r.IsF32()); - EXPECT_FALSE(r.IsF16()); - EXPECT_FALSE(r.IsI32()); - EXPECT_TRUE(r.IsU32()); - EXPECT_FALSE(r.IsTemp()); - EXPECT_FALSE(r.IsVar()); - EXPECT_FALSE(r.IsBool()); -} - -TEST_F(IR_RegisterTest, id) { - std::stringstream str; - - Register r(Register::Id(4)); - EXPECT_EQ(4u, r.AsId()); - - str << r; - EXPECT_EQ("%4", str.str()); - - EXPECT_FALSE(r.IsF32()); - EXPECT_FALSE(r.IsF16()); - EXPECT_FALSE(r.IsI32()); - EXPECT_FALSE(r.IsU32()); - EXPECT_TRUE(r.IsTemp()); - EXPECT_FALSE(r.IsVar()); - EXPECT_FALSE(r.IsBool()); -} - -TEST_F(IR_RegisterTest, bool) { - std::stringstream str; - - Register r(false); - EXPECT_FALSE(r.AsBool()); - - str << r; - EXPECT_EQ("false", str.str()); - - str.str(""); - r = Register(true); - EXPECT_TRUE(r.AsBool()); - - str << r; - EXPECT_EQ("true", str.str()); - - EXPECT_FALSE(r.IsF32()); - EXPECT_FALSE(r.IsF16()); - EXPECT_FALSE(r.IsI32()); - EXPECT_FALSE(r.IsU32()); - EXPECT_FALSE(r.IsTemp()); - EXPECT_FALSE(r.IsVar()); - EXPECT_TRUE(r.IsBool()); -} - -TEST_F(IR_RegisterTest, var) { - std::stringstream str; - - Symbol s; - Register r(s, 2); - EXPECT_EQ(2u, r.AsVarData().id); - EXPECT_EQ(s, r.AsVarData().sym); - - str << r; - EXPECT_EQ("%v2", str.str()); - str.str(""); - - r = Register(s, 4); - EXPECT_EQ(4u, r.AsVarData().id); - EXPECT_EQ(s, r.AsVarData().sym); - - str << r; - EXPECT_EQ("%v4", str.str()); - - EXPECT_FALSE(r.IsF32()); - EXPECT_FALSE(r.IsF16()); - EXPECT_FALSE(r.IsI32()); - EXPECT_FALSE(r.IsU32()); - EXPECT_FALSE(r.IsTemp()); - EXPECT_TRUE(r.IsVar()); - EXPECT_FALSE(r.IsBool()); -} - -TEST_F(IR_RegisterTest, uninitialized) { - Register r; - - EXPECT_FALSE(r.IsF32()); - EXPECT_FALSE(r.IsF16()); - EXPECT_FALSE(r.IsI32()); - EXPECT_FALSE(r.IsU32()); - EXPECT_FALSE(r.IsTemp()); - EXPECT_FALSE(r.IsVar()); - EXPECT_FALSE(r.IsBool()); -} - -} // namespace -} // namespace tint::ir diff --git a/src/tint/ir/switch.h b/src/tint/ir/switch.h index 73284cf81b..e526fe84dd 100644 --- a/src/tint/ir/switch.h +++ b/src/tint/ir/switch.h @@ -17,7 +17,7 @@ #include "src/tint/ir/block.h" #include "src/tint/ir/flow_node.h" -#include "src/tint/ir/register.h" +#include "src/tint/ir/value.h" // Forward declarations namespace tint::ast { @@ -52,8 +52,8 @@ class Switch : public Castable { /// The switch case statements utils::Vector cases; - /// Register holding the condition result - Register condition; + /// Value holding the condition result + Value condition; }; } // namespace tint::ir diff --git a/src/tint/ir/register.cc b/src/tint/ir/value.cc similarity index 52% rename from src/tint/ir/register.cc rename to src/tint/ir/value.cc index f3caa76116..bd45a98f20 100644 --- a/src/tint/ir/register.cc +++ b/src/tint/ir/value.cc @@ -12,62 +12,62 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "src/tint/ir/register.h" +#include "src/tint/ir/value.h" namespace tint::ir { -Register::Register() : kind_(Kind::kUninitialized), data_(Id(0)) {} +Value::Value() : kind_(Kind::kUninitialized), data_(Id(0)) {} -Register::Register(Id id) : kind_(Kind::kTemp), data_(id) {} +Value::Value(Id id) : kind_(Kind::kTemp), data_(id) {} -Register::Register(f32 f) : kind_(Kind::kF32), data_(f) {} +Value::Value(f32 f) : kind_(Kind::kF32), data_(f) {} -Register::Register(f16 f) : kind_(Kind::kF16), data_(f) {} +Value::Value(f16 f) : kind_(Kind::kF16), data_(f) {} -Register::Register(u32 u) : kind_(Kind::kU32), data_(u) {} +Value::Value(u32 u) : kind_(Kind::kU32), data_(u) {} -Register::Register(i32 i) : kind_(Kind::kI32), data_(i) {} +Value::Value(i32 i) : kind_(Kind::kI32), data_(i) {} -Register::Register(bool b) : kind_(Kind::kBool), data_(b) {} +Value::Value(bool b) : kind_(Kind::kBool), data_(b) {} -Register::Register(Symbol s, Id id) : kind_(Kind::kVar), data_(VarData{s, id}) {} +Value::Value(Symbol s, Id id) : kind_(Kind::kVar), data_(VarData{s, id}) {} -Register::~Register() = default; +Value::~Value() = default; -Register::Register(const Register& o) = default; +Value::Value(const Value& o) = default; -Register::Register(Register&& o) = default; +Value::Value(Value&& o) = default; -Register& Register::operator=(const Register& o) = default; +Value& Value::operator=(const Value& o) = default; -Register& Register::operator=(Register&& o) = default; +Value& Value::operator=(Value&& o) = default; -std::ostream& operator<<(std::ostream& out, const Register& r) { +std::ostream& operator<<(std::ostream& out, const Value& r) { switch (r.GetKind()) { - case Register::Kind::kTemp: + case Value::Kind::kTemp: out << "%" << std::to_string(r.AsId()); break; - case Register::Kind::kF32: + case Value::Kind::kF32: out << std::to_string(r.AsF32().value); break; - case Register::Kind::kF16: + case Value::Kind::kF16: out << std::to_string(r.AsF16().value); break; - case Register::Kind::kI32: + case Value::Kind::kI32: out << std::to_string(r.AsI32().value); break; - case Register::Kind::kU32: + case Value::Kind::kU32: out << std::to_string(r.AsU32().value); break; // TODO(dsinclair): Emit the symbol instead of v - case Register::Kind::kVar: + case Value::Kind::kVar: out << "%v" << std::to_string(r.AsVarData().id); break; - case Register::Kind::kBool: + case Value::Kind::kBool: out << (r.AsBool() ? "true" : "false"); break; - case Register::Kind::kUninitialized: - out << "unknown register"; + case Value::Kind::kUninitialized: + out << "unknown value"; break; } return out; diff --git a/src/tint/ir/register.h b/src/tint/ir/value.h similarity index 53% rename from src/tint/ir/register.h rename to src/tint/ir/value.h index d1c41eba15..7c9f8b5248 100644 --- a/src/tint/ir/register.h +++ b/src/tint/ir/value.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef SRC_TINT_IR_REGISTER_H_ -#define SRC_TINT_IR_REGISTER_H_ +#ifndef SRC_TINT_IR_VALUE_H_ +#define SRC_TINT_IR_VALUE_H_ #include #include @@ -23,37 +23,37 @@ namespace tint::ir { -/// Register in the IR. The register can be one of several types these include, but aren't limited -/// to, `f32`, `u32`, `temp`, `var`. The type of the register determines the type of data stored -/// in the register. -class Register { +/// Value in the IR. The value can be one of several types these include, but aren't limited +/// to, `f32`, `u32`, `temp`, `var`. The type of the value determines the type of data stored +/// in the value. +class Value { public: - /// A register id. + /// A value id. using Id = uint32_t; - /// The type of the register + /// The type of the value enum class Kind { - /// A uninitialized register + /// A uninitialized value kUninitialized, - /// A temporary allocated register + /// A temporary allocated value kTemp, - /// A f32 register + /// A f32 value kF32, - /// A f16 register + /// A f16 value kF16, - /// An i32 register + /// An i32 value kI32, - /// A u32 register + /// A u32 value kU32, - /// A variable register + /// A variable value kVar, - /// A boolean register + /// A boolean value kBool, }; /// Stores data for a given variable. There will be multiple `VarData` entries for a given `id`. /// The `id` acts like a generation number (although they aren't sequential, they are - /// increasing). As the variable is stored too a new register will be created and the the `id` + /// increasing). As the variable is stored too a new value will be created and the the `id` /// will be incremented. struct VarData { /// The symbol for the variable @@ -64,106 +64,106 @@ class Register { }; /// Constructor - /// Creates a uninitialized register - Register(); + /// Creates a uninitialized value + Value(); /// Constructor - /// @param id the id for the register - explicit Register(Id id); + /// @param id the id for the value + explicit Value(Id id); /// Constructor - /// @param s the symbol for the register - /// @param id the id for the register - Register(Symbol s, Id id); + /// @param s the symbol for the value + /// @param id the id for the value + Value(Symbol s, Id id); /// Constructor - /// @param b the `bool` value to store in the register - explicit Register(bool b); + /// @param b the `bool` value to store in the value + explicit Value(bool b); /// Constructor - /// @param f the `f32` value to store in the register - explicit Register(f32 f); + /// @param f the `f32` value to store in the value + explicit Value(f32 f); /// Constructor - /// @param f the `f16` value to store in the register - explicit Register(f16 f); + /// @param f the `f16` value to store in the value + explicit Value(f16 f); /// Constructor - /// @param u the `u32` value to store in the register - explicit Register(u32 u); + /// @param u the `u32` value to store in the value + explicit Value(u32 u); /// Constructor - /// @param i the `i32` value to store in the register - explicit Register(i32 i); + /// @param i the `i32` value to store in the value + explicit Value(i32 i); /// Destructor - ~Register(); + ~Value(); /// Copy constructor - /// @param o the register to copy from - Register(const Register& o); + /// @param o the value to copy from + Value(const Value& o); /// Move constructor - /// @param o the register to move from - Register(Register&& o); + /// @param o the value to move from + Value(Value&& o); /// Copy assign - /// @param o the register to copy from + /// @param o the value to copy from /// @returns this - Register& operator=(const Register& o); + Value& operator=(const Value& o); /// Move assign - /// @param o the register to move from + /// @param o the value to move from /// @returns this - Register& operator=(Register&& o); + Value& operator=(Value&& o); - /// @returns true if this is a temporary register + /// @returns true if this is a temporary value bool IsTemp() const { return kind_ == Kind::kTemp; } - /// @returns true if this is a f32 register + /// @returns true if this is a f32 value bool IsF32() const { return kind_ == Kind::kF32; } - /// @returns true if this is a f16 register + /// @returns true if this is a f16 value bool IsF16() const { return kind_ == Kind::kF16; } - /// @returns true if this is an i32 register + /// @returns true if this is an i32 value bool IsI32() const { return kind_ == Kind::kI32; } - /// @returns true if this is a u32 register + /// @returns true if this is a u32 value bool IsU32() const { return kind_ == Kind::kU32; } - /// @returns true if this is a var register + /// @returns true if this is a var value bool IsVar() const { return kind_ == Kind::kVar; } - /// @returns true if this is a bool register + /// @returns true if this is a bool value bool IsBool() const { return kind_ == Kind::kBool; } - /// @returns the kind of register + /// @returns the kind of value Kind GetKind() const { return kind_; } - /// @returns the register data as a `f32`. + /// @returns the value data as a `f32`. /// @note, must only be called if `IsF32()` is true f32 AsF32() const { return std::get(data_); } - /// @returns the register data as a `f16`. + /// @returns the value data as a `f16`. /// @note, must only be called if `IsF16()` is true f16 AsF16() const { return std::get(data_); } - /// @returns the register data as an `i32`. + /// @returns the value data as an `i32`. /// @note, must only be called if `IsI32()` is true i32 AsI32() const { return std::get(data_); } - /// @returns the register data as a `u32`. + /// @returns the value data as a `u32`. /// @note, must only be called if `IsU32()` is true u32 AsU32() const { return std::get(data_); } - /// @returns the register data as an `Id`. + /// @returns the value data as an `Id`. /// @note, must only be called if `IsTemp()` is true Id AsId() const { return std::get(data_); } - /// @returns the register data as a `VarData` structure. + /// @returns the value data as a `VarData` structure. /// @note, must only be called if `IsVar()` is true VarData AsVarData() const { return std::get(data_); } - /// @returns the register data as a `bool`. + /// @returns the value data as a `bool`. /// @note, must only be called if `IsBool()` is true bool AsBool() const { return std::get(data_); } private: - /// The type of data stored in this register + /// The type of data stored in this value Kind kind_; - /// The data stored in the register + /// The data stored in the value std::variant data_; }; -std::ostream& operator<<(std::ostream& out, const Register& r); +std::ostream& operator<<(std::ostream& out, const Value& r); } // namespace tint::ir -#endif // SRC_TINT_IR_REGISTER_H_ +#endif // SRC_TINT_IR_VALUE_H_ diff --git a/src/tint/ir/value_test.cc b/src/tint/ir/value_test.cc new file mode 100644 index 0000000000..77ee3e4244 --- /dev/null +++ b/src/tint/ir/value_test.cc @@ -0,0 +1,183 @@ +// Copyright 2022 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "src/tint/ir/test_helper.h" +#include "src/tint/ir/value.h" + +namespace tint::ir { +namespace { + +using namespace tint::number_suffixes; // NOLINT + +using IR_ValueTest = TestHelper; + +TEST_F(IR_ValueTest, f32) { + std::stringstream str; + + Value val(1.2_f); + EXPECT_EQ(1.2_f, val.AsF32()); + + str << val; + EXPECT_EQ("1.200000", str.str()); + + EXPECT_TRUE(val.IsF32()); + EXPECT_FALSE(val.IsF16()); + EXPECT_FALSE(val.IsI32()); + EXPECT_FALSE(val.IsU32()); + EXPECT_FALSE(val.IsTemp()); + EXPECT_FALSE(val.IsVar()); + EXPECT_FALSE(val.IsBool()); +} + +TEST_F(IR_ValueTest, f16) { + std::stringstream str; + + Value val(1.1_h); + EXPECT_EQ(1.1_h, val.AsF16()); + + str << val; + EXPECT_EQ("1.099609", str.str()); + + EXPECT_FALSE(val.IsF32()); + EXPECT_TRUE(val.IsF16()); + EXPECT_FALSE(val.IsI32()); + EXPECT_FALSE(val.IsU32()); + EXPECT_FALSE(val.IsTemp()); + EXPECT_FALSE(val.IsVar()); + EXPECT_FALSE(val.IsBool()); +} + +TEST_F(IR_ValueTest, i32) { + std::stringstream str; + + Value val(1_i); + EXPECT_EQ(1_i, val.AsI32()); + + str << val; + EXPECT_EQ("1", str.str()); + + EXPECT_FALSE(val.IsF32()); + EXPECT_FALSE(val.IsF16()); + EXPECT_TRUE(val.IsI32()); + EXPECT_FALSE(val.IsU32()); + EXPECT_FALSE(val.IsTemp()); + EXPECT_FALSE(val.IsVar()); + EXPECT_FALSE(val.IsBool()); +} + +TEST_F(IR_ValueTest, u32) { + std::stringstream str; + + Value val(2_u); + EXPECT_EQ(2_u, val.AsU32()); + + str << val; + EXPECT_EQ("2", str.str()); + + EXPECT_FALSE(val.IsF32()); + EXPECT_FALSE(val.IsF16()); + EXPECT_FALSE(val.IsI32()); + EXPECT_TRUE(val.IsU32()); + EXPECT_FALSE(val.IsTemp()); + EXPECT_FALSE(val.IsVar()); + EXPECT_FALSE(val.IsBool()); +} + +TEST_F(IR_ValueTest, id) { + std::stringstream str; + + Value val(Value::Id(4)); + EXPECT_EQ(4u, val.AsId()); + + str << val; + EXPECT_EQ("%4", str.str()); + + EXPECT_FALSE(val.IsF32()); + EXPECT_FALSE(val.IsF16()); + EXPECT_FALSE(val.IsI32()); + EXPECT_FALSE(val.IsU32()); + EXPECT_TRUE(val.IsTemp()); + EXPECT_FALSE(val.IsVar()); + EXPECT_FALSE(val.IsBool()); +} + +TEST_F(IR_ValueTest, bool) { + std::stringstream str; + + Value val(false); + EXPECT_FALSE(val.AsBool()); + + str << val; + EXPECT_EQ("false", str.str()); + + str.str(""); + val = Value(true); + EXPECT_TRUE(val.AsBool()); + + str << val; + EXPECT_EQ("true", str.str()); + + EXPECT_FALSE(val.IsF32()); + EXPECT_FALSE(val.IsF16()); + EXPECT_FALSE(val.IsI32()); + EXPECT_FALSE(val.IsU32()); + EXPECT_FALSE(val.IsTemp()); + EXPECT_FALSE(val.IsVar()); + EXPECT_TRUE(val.IsBool()); +} + +TEST_F(IR_ValueTest, var) { + std::stringstream str; + + Symbol s; + Value val(s, 2); + EXPECT_EQ(2u, val.AsVarData().id); + EXPECT_EQ(s, val.AsVarData().sym); + + str << val; + EXPECT_EQ("%v2", str.str()); + str.str(""); + + val = Value(s, 4); + EXPECT_EQ(4u, val.AsVarData().id); + EXPECT_EQ(s, val.AsVarData().sym); + + str << val; + EXPECT_EQ("%v4", str.str()); + + EXPECT_FALSE(val.IsF32()); + EXPECT_FALSE(val.IsF16()); + EXPECT_FALSE(val.IsI32()); + EXPECT_FALSE(val.IsU32()); + EXPECT_FALSE(val.IsTemp()); + EXPECT_TRUE(val.IsVar()); + EXPECT_FALSE(val.IsBool()); +} + +TEST_F(IR_ValueTest, uninitialized) { + Value val; + + EXPECT_FALSE(val.IsF32()); + EXPECT_FALSE(val.IsF16()); + EXPECT_FALSE(val.IsI32()); + EXPECT_FALSE(val.IsU32()); + EXPECT_FALSE(val.IsTemp()); + EXPECT_FALSE(val.IsVar()); + EXPECT_FALSE(val.IsBool()); +} + +} // namespace +} // namespace tint::ir