[ir] Split Value into Temp and Constant.
This CL pulls the Temp and Constant classes out of the Value base class. Bug: tint:1718 Change-Id: Ib7bccc7d3190ddd1c5cf493704e778dd23b5c008 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/112044 Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: Dan Sinclair <dsinclair@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
0982dcea69
commit
e272eaf30f
|
@ -656,6 +656,8 @@ if(${TINT_BUILD_IR})
|
|||
ir/builder.h
|
||||
ir/builder_impl.cc
|
||||
ir/builder_impl.h
|
||||
ir/constant.cc
|
||||
ir/constant.h
|
||||
ir/debug.cc
|
||||
ir/debug.h
|
||||
ir/disassembler.cc
|
||||
|
@ -674,6 +676,8 @@ if(${TINT_BUILD_IR})
|
|||
ir/module.h
|
||||
ir/switch.cc
|
||||
ir/switch.h
|
||||
ir/temp.cc
|
||||
ir/temp.h
|
||||
ir/terminator.cc
|
||||
ir/terminator.h
|
||||
ir/value.cc
|
||||
|
@ -1341,9 +1345,10 @@ if(TINT_BUILD_TESTS)
|
|||
if (${TINT_BUILD_IR})
|
||||
list(APPEND TINT_TEST_SRCS
|
||||
ir/builder_impl_test.cc
|
||||
ir/constant_test.cc
|
||||
ir/instruction_test.cc
|
||||
ir/temp_test.cc
|
||||
ir/test_helper.h
|
||||
ir/value_test.cc
|
||||
)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -93,12 +93,12 @@ void Builder::Branch(Block* from, FlowNode* to) {
|
|||
to->inbound_branches.Push(from);
|
||||
}
|
||||
|
||||
Value::Id Builder::AllocateValue() {
|
||||
return next_value_id++;
|
||||
Temp::Id Builder::AllocateTempId() {
|
||||
return next_temp_id++;
|
||||
}
|
||||
|
||||
Instruction Builder::CreateInstruction(Instruction::Kind kind, const Value* lhs, const Value* rhs) {
|
||||
return Instruction(kind, MkValue(AllocateValue()), lhs, rhs);
|
||||
return Instruction(kind, Temp(), lhs, rhs);
|
||||
}
|
||||
|
||||
Instruction Builder::And(const Value* lhs, const Value* rhs) {
|
||||
|
|
|
@ -15,12 +15,14 @@
|
|||
#ifndef SRC_TINT_IR_BUILDER_H_
|
||||
#define SRC_TINT_IR_BUILDER_H_
|
||||
|
||||
#include "src/tint/ir/constant.h"
|
||||
#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/switch.h"
|
||||
#include "src/tint/ir/temp.h"
|
||||
#include "src/tint/ir/terminator.h"
|
||||
#include "src/tint/ir/value.h"
|
||||
|
||||
|
@ -83,14 +85,18 @@ class Builder {
|
|||
/// @param to the node to branch too
|
||||
void Branch(Block* from, FlowNode* to);
|
||||
|
||||
/// Creates a new Value
|
||||
/// @param val the value
|
||||
/// @returns the new Value
|
||||
/// Creates a new Constant
|
||||
/// @param val the constant value
|
||||
/// @returns the new constant
|
||||
template <typename T>
|
||||
const Value* MkValue(T val) {
|
||||
return ir.values.Create<Value>(val);
|
||||
const ir::Constant* Constant(T val) {
|
||||
return ir.values.Create<ir::Constant>(val);
|
||||
}
|
||||
|
||||
/// Creates a new Temporary
|
||||
/// @returns the new temporary
|
||||
const ir::Temp* Temp() { return ir.values.Create<ir::Temp>(AllocateTempId()); }
|
||||
|
||||
/// Creates an op for `lhs kind rhs`
|
||||
/// @param kind the kind of operation
|
||||
/// @param lhs the left-hand-side of the operation
|
||||
|
@ -206,14 +212,14 @@ class Builder {
|
|||
/// @returns the operation
|
||||
Instruction Modulo(const Value* lhs, const Value* rhs);
|
||||
|
||||
/// @returns a unique Value id
|
||||
Value::Id AllocateValue();
|
||||
/// @returns a unique temp id
|
||||
Temp::Id AllocateTempId();
|
||||
|
||||
/// The IR module.
|
||||
Module ir;
|
||||
|
||||
/// The next Value number to allocate
|
||||
Value::Id next_value_id = 1;
|
||||
/// The next temporary number to allocate
|
||||
Temp::Id next_temp_id = 1;
|
||||
};
|
||||
|
||||
} // namespace tint::ir
|
||||
|
|
|
@ -632,20 +632,20 @@ utils::Result<const Value*> BuilderImpl::EmitLiteral(const ast::LiteralExpressio
|
|||
return tint::Switch( //
|
||||
lit,
|
||||
[&](const ast::BoolLiteralExpression* l) {
|
||||
return utils::Result<const Value*>(builder.MkValue(l->value));
|
||||
return utils::Result<const Value*>(builder.Constant(l->value));
|
||||
},
|
||||
[&](const ast::FloatLiteralExpression* l) {
|
||||
if (l->suffix == ast::FloatLiteralExpression::Suffix::kF) {
|
||||
return utils::Result<const Value*>(
|
||||
builder.MkValue(f32(static_cast<float>(l->value))));
|
||||
builder.Constant(f32(static_cast<float>(l->value))));
|
||||
}
|
||||
return utils::Result<const Value*>(builder.MkValue(f16(static_cast<float>(l->value))));
|
||||
return utils::Result<const Value*>(builder.Constant(f16(static_cast<float>(l->value))));
|
||||
},
|
||||
[&](const ast::IntLiteralExpression* l) {
|
||||
if (l->suffix == ast::IntLiteralExpression::Suffix::kI) {
|
||||
return utils::Result<const Value*>(builder.MkValue(i32(l->value)));
|
||||
return utils::Result<const Value*>(builder.Constant(i32(l->value)));
|
||||
}
|
||||
return utils::Result<const Value*>(builder.MkValue(u32(l->value)));
|
||||
return utils::Result<const Value*>(builder.Constant(u32(l->value)));
|
||||
},
|
||||
[&](Default) {
|
||||
diagnostics_.add_warning(tint::diag::System::IR,
|
||||
|
|
|
@ -101,7 +101,8 @@ TEST_F(IR_BuilderImplTest, IfStatement) {
|
|||
EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
|
||||
|
||||
// Check condition
|
||||
auto* instr = flow->condition;
|
||||
ASSERT_TRUE(flow->condition->Is<Constant>());
|
||||
auto* instr = flow->condition->As<Constant>();
|
||||
ASSERT_TRUE(instr->IsBool());
|
||||
EXPECT_TRUE(instr->AsBool());
|
||||
}
|
||||
|
@ -502,7 +503,8 @@ TEST_F(IR_BuilderImplTest, Loop_WithReturn) {
|
|||
EXPECT_EQ(loop_flow->merge_target->branch_target, nullptr);
|
||||
|
||||
// Check condition
|
||||
auto* instr = if_flow->condition;
|
||||
ASSERT_TRUE(if_flow->condition->Is<Constant>());
|
||||
auto* instr = if_flow->condition->As<Constant>();
|
||||
ASSERT_TRUE(instr->IsBool());
|
||||
EXPECT_TRUE(instr->AsBool());
|
||||
}
|
||||
|
@ -947,7 +949,8 @@ TEST_F(IR_BuilderImplTest, While) {
|
|||
EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
|
||||
|
||||
// Check condition
|
||||
auto* instr = if_flow->condition;
|
||||
ASSERT_TRUE(if_flow->condition->Is<Constant>());
|
||||
auto* instr = if_flow->condition->As<Constant>();
|
||||
ASSERT_TRUE(instr->IsBool());
|
||||
EXPECT_FALSE(instr->AsBool());
|
||||
}
|
||||
|
@ -1071,7 +1074,8 @@ TEST_F(IR_BuilderImplTest, DISABLED_For) {
|
|||
EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
|
||||
|
||||
// Check condition
|
||||
auto* instr = if_flow->condition;
|
||||
ASSERT_TRUE(if_flow->condition->Is<Constant>());
|
||||
auto* instr = if_flow->condition->As<Constant>();
|
||||
ASSERT_TRUE(instr->IsBool());
|
||||
EXPECT_FALSE(instr->AsBool());
|
||||
}
|
||||
|
@ -1171,7 +1175,8 @@ TEST_F(IR_BuilderImplTest, Switch) {
|
|||
EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
|
||||
|
||||
// Check condition
|
||||
auto* instr = flow->condition;
|
||||
ASSERT_TRUE(flow->condition->Is<Constant>());
|
||||
auto* instr = flow->condition->As<Constant>();
|
||||
ASSERT_TRUE(instr->IsI32());
|
||||
EXPECT_EQ(1_i, instr->AsI32());
|
||||
}
|
||||
|
@ -1341,7 +1346,8 @@ TEST_F(IR_BuilderImplTest, EmitLiteral_Bool_True) {
|
|||
auto r = b.EmitLiteral(Expr(true));
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
auto* val = r.Get();
|
||||
ASSERT_TRUE(r.Get()->Is<Constant>());
|
||||
auto* val = r.Get()->As<Constant>();
|
||||
EXPECT_TRUE(val->IsBool());
|
||||
EXPECT_TRUE(val->AsBool());
|
||||
}
|
||||
|
@ -1351,7 +1357,8 @@ TEST_F(IR_BuilderImplTest, EmitLiteral_Bool_False) {
|
|||
auto r = b.EmitLiteral(Expr(false));
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
auto val = r.Get();
|
||||
ASSERT_TRUE(r.Get()->Is<Constant>());
|
||||
auto* val = r.Get()->As<Constant>();
|
||||
EXPECT_TRUE(val->IsBool());
|
||||
EXPECT_FALSE(val->AsBool());
|
||||
}
|
||||
|
@ -1361,7 +1368,8 @@ TEST_F(IR_BuilderImplTest, EmitLiteral_F32) {
|
|||
auto r = b.EmitLiteral(Expr(1.2_f));
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
auto val = r.Get();
|
||||
ASSERT_TRUE(r.Get()->Is<Constant>());
|
||||
auto* val = r.Get()->As<Constant>();
|
||||
EXPECT_TRUE(val->IsF32());
|
||||
EXPECT_EQ(1.2_f, val->AsF32());
|
||||
}
|
||||
|
@ -1371,7 +1379,8 @@ TEST_F(IR_BuilderImplTest, EmitLiteral_F16) {
|
|||
auto r = b.EmitLiteral(Expr(1.2_h));
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
auto val = r.Get();
|
||||
ASSERT_TRUE(r.Get()->Is<Constant>());
|
||||
auto* val = r.Get()->As<Constant>();
|
||||
EXPECT_TRUE(val->IsF16());
|
||||
EXPECT_EQ(1.2_h, val->AsF16());
|
||||
}
|
||||
|
@ -1381,7 +1390,8 @@ TEST_F(IR_BuilderImplTest, EmitLiteral_I32) {
|
|||
auto r = b.EmitLiteral(Expr(-2_i));
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
auto val = r.Get();
|
||||
ASSERT_TRUE(r.Get()->Is<Constant>());
|
||||
auto* val = r.Get()->As<Constant>();
|
||||
EXPECT_TRUE(val->IsI32());
|
||||
EXPECT_EQ(-2_i, val->AsI32());
|
||||
}
|
||||
|
@ -1391,7 +1401,8 @@ TEST_F(IR_BuilderImplTest, EmitLiteral_U32) {
|
|||
auto r = b.EmitLiteral(Expr(2_u));
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
auto val = r.Get();
|
||||
ASSERT_TRUE(r.Get()->Is<Constant>());
|
||||
auto* val = r.Get()->As<Constant>();
|
||||
EXPECT_TRUE(val->IsU32());
|
||||
EXPECT_EQ(2_u, val->AsU32());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
// 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 "src/tint/ir/constant.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ir::Constant);
|
||||
|
||||
namespace tint::ir {
|
||||
|
||||
Constant::Constant(f32 f) : kind_(Kind::kF32), data_(f) {}
|
||||
|
||||
Constant::Constant(f16 f) : kind_(Kind::kF16), data_(f) {}
|
||||
|
||||
Constant::Constant(u32 u) : kind_(Kind::kU32), data_(u) {}
|
||||
|
||||
Constant::Constant(i32 i) : kind_(Kind::kI32), data_(i) {}
|
||||
|
||||
Constant::Constant(bool b) : kind_(Kind::kBool), data_(b) {}
|
||||
|
||||
Constant::~Constant() = default;
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const Constant& r) {
|
||||
switch (r.GetKind()) {
|
||||
case Constant::Kind::kF32:
|
||||
out << std::to_string(r.AsF32().value);
|
||||
break;
|
||||
case Constant::Kind::kF16:
|
||||
out << std::to_string(r.AsF16().value);
|
||||
break;
|
||||
case Constant::Kind::kI32:
|
||||
out << std::to_string(r.AsI32().value);
|
||||
break;
|
||||
case Constant::Kind::kU32:
|
||||
out << std::to_string(r.AsU32().value);
|
||||
break;
|
||||
case Constant::Kind::kBool:
|
||||
out << (r.AsBool() ? "true" : "false");
|
||||
break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace tint::ir
|
|
@ -0,0 +1,114 @@
|
|||
// 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.
|
||||
|
||||
#ifndef SRC_TINT_IR_CONSTANT_H_
|
||||
#define SRC_TINT_IR_CONSTANT_H_
|
||||
|
||||
#include <ostream>
|
||||
#include <variant>
|
||||
|
||||
#include "src/tint/ir/value.h"
|
||||
#include "src/tint/number.h"
|
||||
|
||||
namespace tint::ir {
|
||||
|
||||
/// Constant in the IR. The constant can be one of several types these include, but aren't limited
|
||||
/// to, `f32`, `u32`, `bool`. The type of the constant determines the type of data stored.
|
||||
class Constant : public Castable<Constant, Value> {
|
||||
public:
|
||||
/// The type of the constant
|
||||
enum class Kind {
|
||||
/// A f32 constant
|
||||
kF32,
|
||||
/// A f16 constant
|
||||
kF16,
|
||||
/// An i32 constant
|
||||
kI32,
|
||||
/// A u32 constant
|
||||
kU32,
|
||||
/// A boolean constant
|
||||
kBool,
|
||||
};
|
||||
|
||||
/// Constructor
|
||||
/// @param b the `bool` constant to store in the constant
|
||||
explicit Constant(bool b);
|
||||
|
||||
/// Constructor
|
||||
/// @param f the `f32` constant to store in the constant
|
||||
explicit Constant(f32 f);
|
||||
|
||||
/// Constructor
|
||||
/// @param f the `f16` constant to store in the constant
|
||||
explicit Constant(f16 f);
|
||||
|
||||
/// Constructor
|
||||
/// @param u the `u32` constant to store in the constant
|
||||
explicit Constant(u32 u);
|
||||
|
||||
/// Constructor
|
||||
/// @param i the `i32` constant to store in the constant
|
||||
explicit Constant(i32 i);
|
||||
|
||||
/// Destructor
|
||||
~Constant() override;
|
||||
|
||||
Constant(const Constant&) = delete;
|
||||
Constant(Constant&&) = delete;
|
||||
|
||||
Constant& operator=(const Constant&) = delete;
|
||||
Constant& operator=(Constant&&) = delete;
|
||||
|
||||
/// @returns true if this is a f32 constant
|
||||
bool IsF32() const { return kind_ == Kind::kF32; }
|
||||
/// @returns true if this is a f16 constant
|
||||
bool IsF16() const { return kind_ == Kind::kF16; }
|
||||
/// @returns true if this is an i32 constant
|
||||
bool IsI32() const { return kind_ == Kind::kI32; }
|
||||
/// @returns true if this is a u32 constant
|
||||
bool IsU32() const { return kind_ == Kind::kU32; }
|
||||
/// @returns true if this is a bool constant
|
||||
bool IsBool() const { return kind_ == Kind::kBool; }
|
||||
|
||||
/// @returns the kind of constant
|
||||
Kind GetKind() const { return kind_; }
|
||||
|
||||
/// @returns the constant data as a `f32`.
|
||||
/// @note, must only be called if `IsF32()` is true
|
||||
f32 AsF32() const { return std::get<f32>(data_); }
|
||||
/// @returns the constant data as a `f16`.
|
||||
/// @note, must only be called if `IsF16()` is true
|
||||
f16 AsF16() const { return std::get<f16>(data_); }
|
||||
/// @returns the constant data as an `i32`.
|
||||
/// @note, must only be called if `IsI32()` is true
|
||||
i32 AsI32() const { return std::get<i32>(data_); }
|
||||
/// @returns the constant data as a `u32`.
|
||||
/// @note, must only be called if `IsU32()` is true
|
||||
u32 AsU32() const { return std::get<u32>(data_); }
|
||||
/// @returns the constant data as a `bool`.
|
||||
/// @note, must only be called if `IsBool()` is true
|
||||
bool AsBool() const { return std::get<bool>(data_); }
|
||||
|
||||
private:
|
||||
/// The type of data stored in this constant
|
||||
Kind kind_;
|
||||
/// The data stored in the constant
|
||||
std::variant<f32, f16, u32, i32, bool> data_;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const Constant& r);
|
||||
|
||||
} // namespace tint::ir
|
||||
|
||||
#endif // SRC_TINT_IR_CONSTANT_H_
|
|
@ -0,0 +1,125 @@
|
|||
// 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 <sstream>
|
||||
|
||||
#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_ConstantTest = TestHelper;
|
||||
|
||||
TEST_F(IR_ConstantTest, f32) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
std::stringstream str;
|
||||
|
||||
auto* val = b.builder.Constant(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->IsBool());
|
||||
}
|
||||
|
||||
TEST_F(IR_ConstantTest, f16) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
std::stringstream str;
|
||||
|
||||
auto* val = b.builder.Constant(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->IsBool());
|
||||
}
|
||||
|
||||
TEST_F(IR_ConstantTest, i32) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
std::stringstream str;
|
||||
|
||||
auto* val = b.builder.Constant(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->IsBool());
|
||||
}
|
||||
|
||||
TEST_F(IR_ConstantTest, u32) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
std::stringstream str;
|
||||
|
||||
auto* val = b.builder.Constant(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->IsBool());
|
||||
}
|
||||
|
||||
TEST_F(IR_ConstantTest, bool) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
std::stringstream str;
|
||||
|
||||
auto* val = b.builder.Constant(false);
|
||||
EXPECT_FALSE(val->AsBool());
|
||||
|
||||
str << *val;
|
||||
EXPECT_EQ("false", str.str());
|
||||
|
||||
str.str("");
|
||||
val = b.builder.Constant(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_TRUE(val->IsBool());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::ir
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include <ostream>
|
||||
|
||||
#include "src/tint/debug.h"
|
||||
#include "src/tint/ir/value.h"
|
||||
#include "src/tint/utils/vector.h"
|
||||
|
||||
|
|
|
@ -25,21 +25,23 @@ 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(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
auto instr = b.builder.And(b.builder.Constant(i32(4)), b.builder.Constant(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.Result()->Is<Temp>());
|
||||
EXPECT_EQ(Temp::Id(42), instr.Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr.HasLHS());
|
||||
auto lhs = instr.LHS();
|
||||
ASSERT_TRUE(instr.LHS()->Is<Constant>());
|
||||
auto lhs = instr.LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
|
||||
ASSERT_TRUE(instr.HasRHS());
|
||||
auto rhs = instr.RHS();
|
||||
ASSERT_TRUE(instr.RHS()->Is<Constant>());
|
||||
auto rhs = instr.RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
|
@ -51,21 +53,23 @@ TEST_F(IR_InstructionTest, CreateAnd) {
|
|||
TEST_F(IR_InstructionTest, CreateOr) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_value_id = Value::Id(42);
|
||||
auto instr = b.builder.Or(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
auto instr = b.builder.Or(b.builder.Constant(i32(4)), b.builder.Constant(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.Result()->Is<Temp>());
|
||||
EXPECT_EQ(Temp::Id(42), instr.Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr.HasLHS());
|
||||
auto lhs = instr.LHS();
|
||||
ASSERT_TRUE(instr.LHS()->Is<Constant>());
|
||||
auto lhs = instr.LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
|
||||
ASSERT_TRUE(instr.HasRHS());
|
||||
auto rhs = instr.RHS();
|
||||
ASSERT_TRUE(instr.RHS()->Is<Constant>());
|
||||
auto rhs = instr.RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
|
@ -77,21 +81,23 @@ TEST_F(IR_InstructionTest, CreateOr) {
|
|||
TEST_F(IR_InstructionTest, CreateXor) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_value_id = Value::Id(42);
|
||||
auto instr = b.builder.Xor(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
auto instr = b.builder.Xor(b.builder.Constant(i32(4)), b.builder.Constant(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.Result()->Is<Temp>());
|
||||
EXPECT_EQ(Temp::Id(42), instr.Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr.HasLHS());
|
||||
auto lhs = instr.LHS();
|
||||
ASSERT_TRUE(instr.LHS()->Is<Constant>());
|
||||
auto lhs = instr.LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
|
||||
ASSERT_TRUE(instr.HasRHS());
|
||||
auto rhs = instr.RHS();
|
||||
ASSERT_TRUE(instr.RHS()->Is<Constant>());
|
||||
auto rhs = instr.RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
|
@ -103,21 +109,23 @@ TEST_F(IR_InstructionTest, CreateXor) {
|
|||
TEST_F(IR_InstructionTest, CreateLogicalAnd) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_value_id = Value::Id(42);
|
||||
auto instr = b.builder.LogicalAnd(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
auto instr = b.builder.LogicalAnd(b.builder.Constant(i32(4)), b.builder.Constant(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.Result()->Is<Temp>());
|
||||
EXPECT_EQ(Temp::Id(42), instr.Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr.HasLHS());
|
||||
auto lhs = instr.LHS();
|
||||
ASSERT_TRUE(instr.LHS()->Is<Constant>());
|
||||
auto lhs = instr.LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
|
||||
ASSERT_TRUE(instr.HasRHS());
|
||||
auto rhs = instr.RHS();
|
||||
ASSERT_TRUE(instr.RHS()->Is<Constant>());
|
||||
auto rhs = instr.RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
|
@ -129,21 +137,23 @@ TEST_F(IR_InstructionTest, CreateLogicalAnd) {
|
|||
TEST_F(IR_InstructionTest, CreateLogicalOr) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_value_id = Value::Id(42);
|
||||
auto instr = b.builder.LogicalOr(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
auto instr = b.builder.LogicalOr(b.builder.Constant(i32(4)), b.builder.Constant(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.Result()->Is<Temp>());
|
||||
EXPECT_EQ(Temp::Id(42), instr.Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr.HasLHS());
|
||||
auto lhs = instr.LHS();
|
||||
ASSERT_TRUE(instr.LHS()->Is<Constant>());
|
||||
auto lhs = instr.LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
|
||||
ASSERT_TRUE(instr.HasRHS());
|
||||
auto rhs = instr.RHS();
|
||||
ASSERT_TRUE(instr.RHS()->Is<Constant>());
|
||||
auto rhs = instr.RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
|
@ -155,21 +165,23 @@ TEST_F(IR_InstructionTest, CreateLogicalOr) {
|
|||
TEST_F(IR_InstructionTest, CreateEqual) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_value_id = Value::Id(42);
|
||||
auto instr = b.builder.Equal(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
auto instr = b.builder.Equal(b.builder.Constant(i32(4)), b.builder.Constant(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.Result()->Is<Temp>());
|
||||
EXPECT_EQ(Temp::Id(42), instr.Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr.HasLHS());
|
||||
auto lhs = instr.LHS();
|
||||
ASSERT_TRUE(instr.LHS()->Is<Constant>());
|
||||
auto lhs = instr.LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
|
||||
ASSERT_TRUE(instr.HasRHS());
|
||||
auto rhs = instr.RHS();
|
||||
ASSERT_TRUE(instr.RHS()->Is<Constant>());
|
||||
auto rhs = instr.RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
|
@ -181,21 +193,23 @@ TEST_F(IR_InstructionTest, CreateEqual) {
|
|||
TEST_F(IR_InstructionTest, CreateNotEqual) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_value_id = Value::Id(42);
|
||||
auto instr = b.builder.NotEqual(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
auto instr = b.builder.NotEqual(b.builder.Constant(i32(4)), b.builder.Constant(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.Result()->Is<Temp>());
|
||||
EXPECT_EQ(Temp::Id(42), instr.Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr.HasLHS());
|
||||
auto lhs = instr.LHS();
|
||||
ASSERT_TRUE(instr.LHS()->Is<Constant>());
|
||||
auto lhs = instr.LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
|
||||
ASSERT_TRUE(instr.HasRHS());
|
||||
auto rhs = instr.RHS();
|
||||
ASSERT_TRUE(instr.RHS()->Is<Constant>());
|
||||
auto rhs = instr.RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
|
@ -207,21 +221,23 @@ TEST_F(IR_InstructionTest, CreateNotEqual) {
|
|||
TEST_F(IR_InstructionTest, CreateLessThan) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_value_id = Value::Id(42);
|
||||
auto instr = b.builder.LessThan(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
auto instr = b.builder.LessThan(b.builder.Constant(i32(4)), b.builder.Constant(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.Result()->Is<Temp>());
|
||||
EXPECT_EQ(Temp::Id(42), instr.Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr.HasLHS());
|
||||
auto lhs = instr.LHS();
|
||||
ASSERT_TRUE(instr.LHS()->Is<Constant>());
|
||||
auto lhs = instr.LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
|
||||
ASSERT_TRUE(instr.HasRHS());
|
||||
auto rhs = instr.RHS();
|
||||
ASSERT_TRUE(instr.RHS()->Is<Constant>());
|
||||
auto rhs = instr.RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
|
@ -233,21 +249,23 @@ TEST_F(IR_InstructionTest, CreateLessThan) {
|
|||
TEST_F(IR_InstructionTest, CreateGreaterThan) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_value_id = Value::Id(42);
|
||||
auto instr = b.builder.GreaterThan(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
auto instr = b.builder.GreaterThan(b.builder.Constant(i32(4)), b.builder.Constant(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.Result()->Is<Temp>());
|
||||
EXPECT_EQ(Temp::Id(42), instr.Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr.HasLHS());
|
||||
auto lhs = instr.LHS();
|
||||
ASSERT_TRUE(instr.LHS()->Is<Constant>());
|
||||
auto lhs = instr.LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
|
||||
ASSERT_TRUE(instr.HasRHS());
|
||||
auto rhs = instr.RHS();
|
||||
ASSERT_TRUE(instr.RHS()->Is<Constant>());
|
||||
auto rhs = instr.RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
|
@ -259,21 +277,23 @@ TEST_F(IR_InstructionTest, CreateGreaterThan) {
|
|||
TEST_F(IR_InstructionTest, CreateLessThanEqual) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_value_id = Value::Id(42);
|
||||
auto instr = b.builder.LessThanEqual(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
auto instr = b.builder.LessThanEqual(b.builder.Constant(i32(4)), b.builder.Constant(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.Result()->Is<Temp>());
|
||||
EXPECT_EQ(Temp::Id(42), instr.Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr.HasLHS());
|
||||
auto lhs = instr.LHS();
|
||||
ASSERT_TRUE(instr.LHS()->Is<Constant>());
|
||||
auto lhs = instr.LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
|
||||
ASSERT_TRUE(instr.HasRHS());
|
||||
auto rhs = instr.RHS();
|
||||
ASSERT_TRUE(instr.RHS()->Is<Constant>());
|
||||
auto rhs = instr.RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
|
@ -285,21 +305,23 @@ TEST_F(IR_InstructionTest, CreateLessThanEqual) {
|
|||
TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_value_id = Value::Id(42);
|
||||
auto instr = b.builder.GreaterThanEqual(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
auto instr = b.builder.GreaterThanEqual(b.builder.Constant(i32(4)), b.builder.Constant(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.Result()->Is<Temp>());
|
||||
EXPECT_EQ(Temp::Id(42), instr.Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr.HasLHS());
|
||||
auto lhs = instr.LHS();
|
||||
ASSERT_TRUE(instr.LHS()->Is<Constant>());
|
||||
auto lhs = instr.LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
|
||||
ASSERT_TRUE(instr.HasRHS());
|
||||
auto rhs = instr.RHS();
|
||||
ASSERT_TRUE(instr.RHS()->Is<Constant>());
|
||||
auto rhs = instr.RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
|
@ -311,21 +333,23 @@ TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
|
|||
TEST_F(IR_InstructionTest, CreateShiftLeft) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_value_id = Value::Id(42);
|
||||
auto instr = b.builder.ShiftLeft(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
auto instr = b.builder.ShiftLeft(b.builder.Constant(i32(4)), b.builder.Constant(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.Result()->Is<Temp>());
|
||||
EXPECT_EQ(Temp::Id(42), instr.Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr.HasLHS());
|
||||
auto lhs = instr.LHS();
|
||||
ASSERT_TRUE(instr.LHS()->Is<Constant>());
|
||||
auto lhs = instr.LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
|
||||
ASSERT_TRUE(instr.HasRHS());
|
||||
auto rhs = instr.RHS();
|
||||
ASSERT_TRUE(instr.RHS()->Is<Constant>());
|
||||
auto rhs = instr.RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
|
@ -337,21 +361,23 @@ TEST_F(IR_InstructionTest, CreateShiftLeft) {
|
|||
TEST_F(IR_InstructionTest, CreateShiftRight) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_value_id = Value::Id(42);
|
||||
auto instr = b.builder.ShiftRight(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
auto instr = b.builder.ShiftRight(b.builder.Constant(i32(4)), b.builder.Constant(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.Result()->Is<Temp>());
|
||||
EXPECT_EQ(Temp::Id(42), instr.Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr.HasLHS());
|
||||
auto lhs = instr.LHS();
|
||||
ASSERT_TRUE(instr.LHS()->Is<Constant>());
|
||||
auto lhs = instr.LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
|
||||
ASSERT_TRUE(instr.HasRHS());
|
||||
auto rhs = instr.RHS();
|
||||
ASSERT_TRUE(instr.RHS()->Is<Constant>());
|
||||
auto rhs = instr.RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
|
@ -363,21 +389,23 @@ TEST_F(IR_InstructionTest, CreateShiftRight) {
|
|||
TEST_F(IR_InstructionTest, CreateAdd) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_value_id = Value::Id(42);
|
||||
auto instr = b.builder.Add(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
auto instr = b.builder.Add(b.builder.Constant(i32(4)), b.builder.Constant(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.Result()->Is<Temp>());
|
||||
EXPECT_EQ(Temp::Id(42), instr.Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr.HasLHS());
|
||||
auto lhs = instr.LHS();
|
||||
ASSERT_TRUE(instr.LHS()->Is<Constant>());
|
||||
auto lhs = instr.LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
|
||||
ASSERT_TRUE(instr.HasRHS());
|
||||
auto rhs = instr.RHS();
|
||||
ASSERT_TRUE(instr.RHS()->Is<Constant>());
|
||||
auto rhs = instr.RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
|
@ -389,21 +417,23 @@ TEST_F(IR_InstructionTest, CreateAdd) {
|
|||
TEST_F(IR_InstructionTest, CreateSubtract) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_value_id = Value::Id(42);
|
||||
auto instr = b.builder.Subtract(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
auto instr = b.builder.Subtract(b.builder.Constant(i32(4)), b.builder.Constant(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.Result()->Is<Temp>());
|
||||
EXPECT_EQ(Temp::Id(42), instr.Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr.HasLHS());
|
||||
auto lhs = instr.LHS();
|
||||
ASSERT_TRUE(instr.LHS()->Is<Constant>());
|
||||
auto lhs = instr.LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
|
||||
ASSERT_TRUE(instr.HasRHS());
|
||||
auto rhs = instr.RHS();
|
||||
ASSERT_TRUE(instr.RHS()->Is<Constant>());
|
||||
auto rhs = instr.RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
|
@ -415,21 +445,23 @@ TEST_F(IR_InstructionTest, CreateSubtract) {
|
|||
TEST_F(IR_InstructionTest, CreateMultiply) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_value_id = Value::Id(42);
|
||||
auto instr = b.builder.Multiply(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
auto instr = b.builder.Multiply(b.builder.Constant(i32(4)), b.builder.Constant(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.Result()->Is<Temp>());
|
||||
EXPECT_EQ(Temp::Id(42), instr.Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr.HasLHS());
|
||||
auto lhs = instr.LHS();
|
||||
ASSERT_TRUE(instr.LHS()->Is<Constant>());
|
||||
auto lhs = instr.LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
|
||||
ASSERT_TRUE(instr.HasRHS());
|
||||
auto rhs = instr.RHS();
|
||||
ASSERT_TRUE(instr.RHS()->Is<Constant>());
|
||||
auto rhs = instr.RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
|
@ -441,21 +473,23 @@ TEST_F(IR_InstructionTest, CreateMultiply) {
|
|||
TEST_F(IR_InstructionTest, CreateDivide) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_value_id = Value::Id(42);
|
||||
auto instr = b.builder.Divide(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
auto instr = b.builder.Divide(b.builder.Constant(i32(4)), b.builder.Constant(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.Result()->Is<Temp>());
|
||||
EXPECT_EQ(Temp::Id(42), instr.Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr.HasLHS());
|
||||
auto lhs = instr.LHS();
|
||||
ASSERT_TRUE(instr.LHS()->Is<Constant>());
|
||||
auto lhs = instr.LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
|
||||
ASSERT_TRUE(instr.HasRHS());
|
||||
auto rhs = instr.RHS();
|
||||
ASSERT_TRUE(instr.RHS()->Is<Constant>());
|
||||
auto rhs = instr.RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
|
@ -467,21 +501,23 @@ TEST_F(IR_InstructionTest, CreateDivide) {
|
|||
TEST_F(IR_InstructionTest, CreateModulo) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_value_id = Value::Id(42);
|
||||
auto instr = b.builder.Modulo(b.builder.MkValue(i32(4)), b.builder.MkValue(i32(2)));
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
auto instr = b.builder.Modulo(b.builder.Constant(i32(4)), b.builder.Constant(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.Result()->Is<Temp>());
|
||||
EXPECT_EQ(Temp::Id(42), instr.Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr.HasLHS());
|
||||
auto lhs = instr.LHS();
|
||||
ASSERT_TRUE(instr.LHS()->Is<Constant>());
|
||||
auto lhs = instr.LHS()->As<Constant>();
|
||||
ASSERT_TRUE(lhs->IsI32());
|
||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||
|
||||
ASSERT_TRUE(instr.HasRHS());
|
||||
auto rhs = instr.RHS();
|
||||
ASSERT_TRUE(instr.RHS()->Is<Constant>());
|
||||
auto rhs = instr.RHS()->As<Constant>();
|
||||
ASSERT_TRUE(rhs->IsI32());
|
||||
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
// 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 "src/tint/ir/temp.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ir::Temp);
|
||||
|
||||
namespace tint::ir {
|
||||
|
||||
Temp::Temp(Id id) : id_(id) {}
|
||||
|
||||
Temp::~Temp() = default;
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const Temp& r) {
|
||||
out << "%" << std::to_string(r.AsId());
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace tint::ir
|
|
@ -0,0 +1,54 @@
|
|||
// 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.
|
||||
|
||||
#ifndef SRC_TINT_IR_TEMP_H_
|
||||
#define SRC_TINT_IR_TEMP_H_
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "src/tint/ir/value.h"
|
||||
|
||||
namespace tint::ir {
|
||||
|
||||
/// Temporary value in the IR.
|
||||
class Temp : public Castable<Temp, Value> {
|
||||
public:
|
||||
/// A value id.
|
||||
using Id = uint32_t;
|
||||
|
||||
/// Constructor
|
||||
/// @param id the id for the value
|
||||
explicit Temp(Id id);
|
||||
|
||||
/// Destructor
|
||||
~Temp() override;
|
||||
|
||||
Temp(const Temp&) = delete;
|
||||
Temp(Temp&&) = delete;
|
||||
|
||||
Temp& operator=(const Temp&) = delete;
|
||||
Temp& operator=(Temp&&) = delete;
|
||||
|
||||
/// @returns the value data as an `Id`.
|
||||
Id AsId() const { return id_; }
|
||||
|
||||
private:
|
||||
Id id_ = 0;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const Temp& r);
|
||||
|
||||
} // namespace tint::ir
|
||||
|
||||
#endif // SRC_TINT_IR_TEMP_H_
|
|
@ -0,0 +1,41 @@
|
|||
// 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 <sstream>
|
||||
|
||||
#include "src/tint/ir/temp.h"
|
||||
#include "src/tint/ir/test_helper.h"
|
||||
|
||||
namespace tint::ir {
|
||||
namespace {
|
||||
|
||||
using namespace tint::number_suffixes; // NOLINT
|
||||
|
||||
using IR_TempTest = TestHelper;
|
||||
|
||||
TEST_F(IR_TempTest, id) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
std::stringstream str;
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(4);
|
||||
auto* val = b.builder.Temp();
|
||||
EXPECT_EQ(4u, val->AsId());
|
||||
|
||||
str << *val;
|
||||
EXPECT_EQ("%4", str.str());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::ir
|
|
@ -14,50 +14,26 @@
|
|||
|
||||
#include "src/tint/ir/value.h"
|
||||
|
||||
#include "src/tint/ir/constant.h"
|
||||
#include "src/tint/ir/temp.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ir::Value);
|
||||
|
||||
namespace tint::ir {
|
||||
|
||||
Value::Value(Id id) : kind_(Kind::kTemp), data_(id) {}
|
||||
|
||||
Value::Value(f32 f) : kind_(Kind::kF32), data_(f) {}
|
||||
|
||||
Value::Value(f16 f) : kind_(Kind::kF16), data_(f) {}
|
||||
|
||||
Value::Value(u32 u) : kind_(Kind::kU32), data_(u) {}
|
||||
|
||||
Value::Value(i32 i) : kind_(Kind::kI32), data_(i) {}
|
||||
|
||||
Value::Value(bool b) : kind_(Kind::kBool), data_(b) {}
|
||||
Value::Value() = default;
|
||||
|
||||
Value::~Value() = default;
|
||||
|
||||
Value::Value(const Value& o) = default;
|
||||
std::ostream& operator<<(std::ostream& out, const Value& v) {
|
||||
const auto* ptr = &v;
|
||||
|
||||
Value::Value(Value&& o) = default;
|
||||
|
||||
Value& Value::operator=(const Value& o) = default;
|
||||
|
||||
Value& Value::operator=(Value&& o) = default;
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const Value& r) {
|
||||
switch (r.GetKind()) {
|
||||
case Value::Kind::kTemp:
|
||||
out << "%" << std::to_string(r.AsId());
|
||||
break;
|
||||
case Value::Kind::kF32:
|
||||
out << std::to_string(r.AsF32().value);
|
||||
break;
|
||||
case Value::Kind::kF16:
|
||||
out << std::to_string(r.AsF16().value);
|
||||
break;
|
||||
case Value::Kind::kI32:
|
||||
out << std::to_string(r.AsI32().value);
|
||||
break;
|
||||
case Value::Kind::kU32:
|
||||
out << std::to_string(r.AsU32().value);
|
||||
break;
|
||||
case Value::Kind::kBool:
|
||||
out << (r.AsBool() ? "true" : "false");
|
||||
break;
|
||||
if (auto* c = ptr->As<Constant>()) {
|
||||
out << *c;
|
||||
} else if (auto* t = ptr->As<Temp>()) {
|
||||
out << *t;
|
||||
} else {
|
||||
out << "Unknown value";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -16,122 +16,29 @@
|
|||
#define SRC_TINT_IR_VALUE_H_
|
||||
|
||||
#include <ostream>
|
||||
#include <variant>
|
||||
|
||||
#include "src/tint/number.h"
|
||||
#include "src/tint/castable.h"
|
||||
|
||||
namespace tint::ir {
|
||||
|
||||
/// 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 {
|
||||
/// Value in the IR.
|
||||
class Value : public Castable<Value> {
|
||||
public:
|
||||
/// A value id.
|
||||
using Id = uint32_t;
|
||||
|
||||
/// The type of the value
|
||||
enum class Kind {
|
||||
/// A temporary allocated value
|
||||
kTemp,
|
||||
/// A f32 value
|
||||
kF32,
|
||||
/// A f16 value
|
||||
kF16,
|
||||
/// An i32 value
|
||||
kI32,
|
||||
/// A u32 value
|
||||
kU32,
|
||||
/// A boolean value
|
||||
kBool,
|
||||
};
|
||||
|
||||
/// Constructor
|
||||
/// @param id the id for the value
|
||||
explicit Value(Id id);
|
||||
|
||||
/// Constructor
|
||||
/// @param b the `bool` value to store in the value
|
||||
explicit Value(bool b);
|
||||
|
||||
/// Constructor
|
||||
/// @param f the `f32` value to store in the value
|
||||
explicit Value(f32 f);
|
||||
|
||||
/// Constructor
|
||||
/// @param f the `f16` value to store in the value
|
||||
explicit Value(f16 f);
|
||||
|
||||
/// Constructor
|
||||
/// @param u the `u32` value to store in the value
|
||||
explicit Value(u32 u);
|
||||
|
||||
/// Constructor
|
||||
/// @param i the `i32` value to store in the value
|
||||
explicit Value(i32 i);
|
||||
|
||||
/// Destructor
|
||||
~Value();
|
||||
virtual ~Value();
|
||||
|
||||
/// Copy constructor
|
||||
/// @param o the value to copy from
|
||||
Value(const Value& o);
|
||||
/// Move constructor
|
||||
/// @param o the value to move from
|
||||
Value(Value&& o);
|
||||
Value(const Value&) = delete;
|
||||
Value(Value&&) = delete;
|
||||
|
||||
/// Copy assign
|
||||
/// @param o the value to copy from
|
||||
/// @returns this
|
||||
Value& operator=(const Value& o);
|
||||
/// Move assign
|
||||
/// @param o the value to move from
|
||||
/// @returns this
|
||||
Value& operator=(Value&& o);
|
||||
Value& operator=(const Value&) = delete;
|
||||
Value& operator=(Value&&) = delete;
|
||||
|
||||
/// @returns true if this is a temporary value
|
||||
bool IsTemp() const { return kind_ == Kind::kTemp; }
|
||||
/// @returns true if this is a f32 value
|
||||
bool IsF32() const { return kind_ == Kind::kF32; }
|
||||
/// @returns true if this is a f16 value
|
||||
bool IsF16() const { return kind_ == Kind::kF16; }
|
||||
/// @returns true if this is an i32 value
|
||||
bool IsI32() const { return kind_ == Kind::kI32; }
|
||||
/// @returns true if this is a u32 value
|
||||
bool IsU32() const { return kind_ == Kind::kU32; }
|
||||
/// @returns true if this is a bool value
|
||||
bool IsBool() const { return kind_ == Kind::kBool; }
|
||||
|
||||
/// @returns the kind of value
|
||||
Kind GetKind() const { return kind_; }
|
||||
|
||||
/// @returns the value data as a `f32`.
|
||||
/// @note, must only be called if `IsF32()` is true
|
||||
f32 AsF32() const { return std::get<f32>(data_); }
|
||||
/// @returns the value data as a `f16`.
|
||||
/// @note, must only be called if `IsF16()` is true
|
||||
f16 AsF16() const { return std::get<f16>(data_); }
|
||||
/// @returns the value data as an `i32`.
|
||||
/// @note, must only be called if `IsI32()` is true
|
||||
i32 AsI32() const { return std::get<i32>(data_); }
|
||||
/// @returns the value data as a `u32`.
|
||||
/// @note, must only be called if `IsU32()` is true
|
||||
u32 AsU32() const { return std::get<u32>(data_); }
|
||||
/// @returns the value data as an `Id`.
|
||||
/// @note, must only be called if `IsTemp()` is true
|
||||
Id AsId() const { return std::get<Id>(data_); }
|
||||
/// @returns the value data as a `bool`.
|
||||
/// @note, must only be called if `IsBool()` is true
|
||||
bool AsBool() const { return std::get<bool>(data_); }
|
||||
|
||||
private:
|
||||
/// The type of data stored in this value
|
||||
Kind kind_;
|
||||
/// The data stored in the value
|
||||
std::variant<Id, f32, f16, u32, i32, bool> data_;
|
||||
protected:
|
||||
/// Constructor
|
||||
Value();
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const Value& r);
|
||||
std::ostream& operator<<(std::ostream& out, const Value& v);
|
||||
|
||||
} // namespace tint::ir
|
||||
|
||||
|
|
|
@ -1,137 +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 <sstream>
|
||||
|
||||
#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.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.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.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.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.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_TRUE(val.IsBool());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::ir
|
Loading…
Reference in New Issue