[ir] Add bitcast expression.
This CL adds the Bitcast expression into the IR. Bug: tint:1718 Change-Id: Ic48bd54485e9b380c94f599e683c2fbba7505787 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/116041 Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Dan Sinclair <dsinclair@chromium.org> Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
cf58122c58
commit
4cef4362b0
|
@ -678,6 +678,8 @@ if(${TINT_BUILD_IR})
|
|||
list(APPEND TINT_LIB_SRCS
|
||||
ir/binary.cc
|
||||
ir/binary.h
|
||||
ir/bitcast.cc
|
||||
ir/bitcast.h
|
||||
ir/block.cc
|
||||
ir/block.h
|
||||
ir/builder.cc
|
||||
|
@ -1378,6 +1380,7 @@ if(TINT_BUILD_TESTS)
|
|||
if (${TINT_BUILD_IR})
|
||||
list(APPEND TINT_TEST_SRCS
|
||||
ir/binary_test.cc
|
||||
ir/bitcast_test.cc
|
||||
ir/builder_impl_test.cc
|
||||
ir/constant_test.cc
|
||||
ir/temp_test.cc
|
||||
|
|
|
@ -34,6 +34,7 @@ TEST_F(IR_InstructionTest, CreateAnd) {
|
|||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kAnd);
|
||||
|
||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||
ASSERT_NE(instr->Result()->Type(), nullptr);
|
||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
|
||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||
|
@ -48,7 +49,7 @@ TEST_F(IR_InstructionTest, CreateAnd) {
|
|||
|
||||
std::stringstream str;
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 & 2");
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 & 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateOr) {
|
||||
|
@ -75,7 +76,7 @@ TEST_F(IR_InstructionTest, CreateOr) {
|
|||
|
||||
std::stringstream str;
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 | 2");
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 | 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateXor) {
|
||||
|
@ -102,14 +103,14 @@ TEST_F(IR_InstructionTest, CreateXor) {
|
|||
|
||||
std::stringstream str;
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 ^ 2");
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 ^ 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateLogicalAnd) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr = b.builder.LogicalAnd(b.builder.ir.types.Get<type::I32>(),
|
||||
const auto* instr = b.builder.LogicalAnd(b.builder.ir.types.Get<type::Bool>(),
|
||||
b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kLogicalAnd);
|
||||
|
@ -129,14 +130,14 @@ TEST_F(IR_InstructionTest, CreateLogicalAnd) {
|
|||
|
||||
std::stringstream str;
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 && 2");
|
||||
EXPECT_EQ(str.str(), "%42 (bool) = 4 && 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateLogicalOr) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr = b.builder.LogicalOr(b.builder.ir.types.Get<type::I32>(),
|
||||
const auto* instr = b.builder.LogicalOr(b.builder.ir.types.Get<type::Bool>(),
|
||||
b.builder.Constant(4_i), b.builder.Constant(2_i));
|
||||
|
||||
EXPECT_EQ(instr->GetKind(), Binary::Kind::kLogicalOr);
|
||||
|
@ -156,7 +157,7 @@ TEST_F(IR_InstructionTest, CreateLogicalOr) {
|
|||
|
||||
std::stringstream str;
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 || 2");
|
||||
EXPECT_EQ(str.str(), "%42 (bool) = 4 || 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateEqual) {
|
||||
|
@ -183,7 +184,7 @@ TEST_F(IR_InstructionTest, CreateEqual) {
|
|||
|
||||
std::stringstream str;
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 == 2");
|
||||
EXPECT_EQ(str.str(), "%42 (bool) = 4 == 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateNotEqual) {
|
||||
|
@ -210,7 +211,7 @@ TEST_F(IR_InstructionTest, CreateNotEqual) {
|
|||
|
||||
std::stringstream str;
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 != 2");
|
||||
EXPECT_EQ(str.str(), "%42 (bool) = 4 != 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateLessThan) {
|
||||
|
@ -237,7 +238,7 @@ TEST_F(IR_InstructionTest, CreateLessThan) {
|
|||
|
||||
std::stringstream str;
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 < 2");
|
||||
EXPECT_EQ(str.str(), "%42 (bool) = 4 < 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateGreaterThan) {
|
||||
|
@ -264,7 +265,7 @@ TEST_F(IR_InstructionTest, CreateGreaterThan) {
|
|||
|
||||
std::stringstream str;
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 > 2");
|
||||
EXPECT_EQ(str.str(), "%42 (bool) = 4 > 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateLessThanEqual) {
|
||||
|
@ -291,7 +292,7 @@ TEST_F(IR_InstructionTest, CreateLessThanEqual) {
|
|||
|
||||
std::stringstream str;
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 <= 2");
|
||||
EXPECT_EQ(str.str(), "%42 (bool) = 4 <= 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
|
||||
|
@ -318,7 +319,7 @@ TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
|
|||
|
||||
std::stringstream str;
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 >= 2");
|
||||
EXPECT_EQ(str.str(), "%42 (bool) = 4 >= 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateShiftLeft) {
|
||||
|
@ -345,7 +346,7 @@ TEST_F(IR_InstructionTest, CreateShiftLeft) {
|
|||
|
||||
std::stringstream str;
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 << 2");
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 << 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateShiftRight) {
|
||||
|
@ -372,7 +373,7 @@ TEST_F(IR_InstructionTest, CreateShiftRight) {
|
|||
|
||||
std::stringstream str;
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 >> 2");
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 >> 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateAdd) {
|
||||
|
@ -399,7 +400,7 @@ TEST_F(IR_InstructionTest, CreateAdd) {
|
|||
|
||||
std::stringstream str;
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 + 2");
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 + 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateSubtract) {
|
||||
|
@ -426,7 +427,7 @@ TEST_F(IR_InstructionTest, CreateSubtract) {
|
|||
|
||||
std::stringstream str;
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 - 2");
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 - 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateMultiply) {
|
||||
|
@ -453,7 +454,7 @@ TEST_F(IR_InstructionTest, CreateMultiply) {
|
|||
|
||||
std::stringstream str;
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 * 2");
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 * 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateDivide) {
|
||||
|
@ -480,7 +481,7 @@ TEST_F(IR_InstructionTest, CreateDivide) {
|
|||
|
||||
std::stringstream str;
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 / 2");
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 / 2");
|
||||
}
|
||||
|
||||
TEST_F(IR_InstructionTest, CreateModulo) {
|
||||
|
@ -507,7 +508,7 @@ TEST_F(IR_InstructionTest, CreateModulo) {
|
|||
|
||||
std::stringstream str;
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 = 4 % 2");
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = 4 % 2");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright 2023 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/bitcast.h"
|
||||
#include "src/tint/debug.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::ir::Bitcast);
|
||||
|
||||
namespace tint::ir {
|
||||
|
||||
Bitcast::Bitcast(const Value* result, const Value* val) : result_(result), val_(val) {
|
||||
TINT_ASSERT(IR, result_);
|
||||
TINT_ASSERT(IR, val_);
|
||||
}
|
||||
|
||||
Bitcast::~Bitcast() = default;
|
||||
|
||||
std::ostream& Bitcast::ToString(std::ostream& out, const SymbolTable& st) const {
|
||||
Result()->ToString(out, st);
|
||||
out << " = bitcast(";
|
||||
val_->ToString(out, st);
|
||||
out << ")";
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace tint::ir
|
|
@ -0,0 +1,63 @@
|
|||
// Copyright 2023 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_BITCAST_H_
|
||||
#define SRC_TINT_IR_BITCAST_H_
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "src/tint/castable.h"
|
||||
#include "src/tint/ir/instruction.h"
|
||||
#include "src/tint/ir/value.h"
|
||||
#include "src/tint/symbol_table.h"
|
||||
#include "src/tint/type/type.h"
|
||||
|
||||
namespace tint::ir {
|
||||
|
||||
/// A bitcast instruction in the IR.
|
||||
class Bitcast : public Castable<Bitcast, Instruction> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param result the result value
|
||||
/// @param val the value being bitcast
|
||||
Bitcast(const Value* result, const Value* val);
|
||||
Bitcast(const Bitcast& instr) = delete;
|
||||
Bitcast(Bitcast&& instr) = delete;
|
||||
~Bitcast() override;
|
||||
|
||||
Bitcast& operator=(const Bitcast& instr) = delete;
|
||||
Bitcast& operator=(Bitcast&& instr) = delete;
|
||||
|
||||
/// @returns the result value for the instruction
|
||||
const Value* Result() const { return result_; }
|
||||
|
||||
/// @returns the left-hand-side value for the instruction
|
||||
const Value* Val() const { return val_; }
|
||||
|
||||
/// Write the instruction to the given stream
|
||||
/// @param out the stream to write to
|
||||
/// @param st the symbol table
|
||||
/// @returns the stream
|
||||
std::ostream& ToString(std::ostream& out, const SymbolTable& st) const override;
|
||||
|
||||
private:
|
||||
const Value* result_ = nullptr;
|
||||
const Value* val_ = nullptr;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const Bitcast&);
|
||||
|
||||
} // namespace tint::ir
|
||||
|
||||
#endif // SRC_TINT_IR_BITCAST_H_
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright 2023 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/instruction.h"
|
||||
#include "src/tint/ir/test_helper.h"
|
||||
|
||||
namespace tint::ir {
|
||||
namespace {
|
||||
|
||||
using namespace tint::number_suffixes; // NOLINT
|
||||
//
|
||||
using IR_InstructionTest = TestHelper;
|
||||
|
||||
TEST_F(IR_InstructionTest, Bitcast) {
|
||||
auto& b = CreateEmptyBuilder();
|
||||
|
||||
b.builder.next_temp_id = Temp::Id(42);
|
||||
const auto* instr =
|
||||
b.builder.Bitcast(b.builder.ir.types.Get<type::I32>(), b.builder.Constant(4_i));
|
||||
|
||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||
ASSERT_NE(instr->Result()->Type(), nullptr);
|
||||
|
||||
ASSERT_TRUE(instr->Val()->Is<Constant>());
|
||||
auto val = instr->Val()->As<Constant>()->value;
|
||||
ASSERT_TRUE(val->Is<constant::Scalar<i32>>());
|
||||
EXPECT_EQ(4_i, val->As<constant::Scalar<i32>>()->ValueAs<i32>());
|
||||
|
||||
std::stringstream str;
|
||||
instr->ToString(str, program->Symbols());
|
||||
EXPECT_EQ(str.str(), "%42 (i32) = bitcast(4)");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::ir
|
|
@ -178,4 +178,8 @@ const Binary* Builder::Modulo(const type::Type* type, const Value* lhs, const Va
|
|||
return CreateBinary(Binary::Kind::kModulo, type, lhs, rhs);
|
||||
}
|
||||
|
||||
const ir::Bitcast* Builder::Bitcast(const type::Type* type, const Value* val) {
|
||||
return ir.instructions.Create<ir::Bitcast>(Temp(type), val);
|
||||
}
|
||||
|
||||
} // namespace tint::ir
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "src/tint/constant/scalar.h"
|
||||
#include "src/tint/ir/binary.h"
|
||||
#include "src/tint/ir/bitcast.h"
|
||||
#include "src/tint/ir/constant.h"
|
||||
#include "src/tint/ir/function.h"
|
||||
#include "src/tint/ir/if.h"
|
||||
|
@ -287,6 +288,12 @@ class Builder {
|
|||
/// @returns the operation
|
||||
const Binary* Modulo(const type::Type* type, const Value* lhs, const Value* rhs);
|
||||
|
||||
/// Creates a bitcast instruction
|
||||
/// @param type the result type of the bitcast
|
||||
/// @param val the value being bitcast
|
||||
/// @returns the instruction
|
||||
const ir::Bitcast* Bitcast(const type::Type* type, const Value* val);
|
||||
|
||||
/// @returns a unique temp id
|
||||
Temp::Id AllocateTempId();
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "src/tint/ast/alias.h"
|
||||
#include "src/tint/ast/binary_expression.h"
|
||||
#include "src/tint/ast/bitcast_expression.h"
|
||||
#include "src/tint/ast/block_statement.h"
|
||||
#include "src/tint/ast/bool_literal_expression.h"
|
||||
#include "src/tint/ast/break_if_statement.h"
|
||||
|
@ -522,7 +523,7 @@ utils::Result<const Value*> BuilderImpl::EmitExpression(const ast::Expression* e
|
|||
expr,
|
||||
// [&](const ast::IndexAccessorExpression* a) { return EmitIndexAccessor(a); },
|
||||
[&](const ast::BinaryExpression* b) { return EmitBinary(b); },
|
||||
// [&](const ast::BitcastExpression* b) { return EmitBitcast(b); },
|
||||
[&](const ast::BitcastExpression* b) { return EmitBitcast(b); },
|
||||
// [&](const ast::CallExpression* c) { return EmitCall(c); },
|
||||
// [&](const ast::IdentifierExpression* i) { return EmitIdentifier(i); },
|
||||
[&](const ast::LiteralExpression* l) { return EmitLiteral(l); },
|
||||
|
@ -629,6 +630,19 @@ utils::Result<const Value*> BuilderImpl::EmitBinary(const ast::BinaryExpression*
|
|||
return utils::Result<const Value*>(instr->Result());
|
||||
}
|
||||
|
||||
utils::Result<const Value*> BuilderImpl::EmitBitcast(const ast::BitcastExpression* expr) {
|
||||
auto val = EmitExpression(expr->expr);
|
||||
if (!val) {
|
||||
return utils::Failure;
|
||||
}
|
||||
|
||||
auto* sem = builder.ir.program->Sem().Get(expr);
|
||||
auto* instr = builder.Bitcast(sem->Type(), val.Get());
|
||||
|
||||
current_flow_block->instructions.Push(instr);
|
||||
return utils::Result<const Value*>(instr->Result());
|
||||
}
|
||||
|
||||
utils::Result<const Value*> BuilderImpl::EmitLiteral(const ast::LiteralExpression* lit) {
|
||||
auto* sem = builder.ir.program->Sem().Get(lit);
|
||||
if (!sem) {
|
||||
|
|
|
@ -32,6 +32,7 @@ class Program;
|
|||
} // namespace tint
|
||||
namespace tint::ast {
|
||||
class BinaryExpression;
|
||||
class BitcastExpression;
|
||||
class BlockStatement;
|
||||
class BreakIfStatement;
|
||||
class BreakStatement;
|
||||
|
@ -152,6 +153,11 @@ class BuilderImpl {
|
|||
/// @returns the value storing the result if successful, utils::Failure otherwise
|
||||
utils::Result<const Value*> EmitBinary(const ast::BinaryExpression* expr);
|
||||
|
||||
/// Emits a bitcast expression
|
||||
/// @param expr the bitcast expression
|
||||
/// @returns the value storing the result if successful, utils::Failure otherwise
|
||||
utils::Result<const Value*> EmitBitcast(const ast::BitcastExpression* expr);
|
||||
|
||||
/// Emits a literal expression
|
||||
/// @param lit the literal to emit
|
||||
/// @returns true if successful, false otherwise
|
||||
|
|
|
@ -1437,7 +1437,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Add) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 + 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 + 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1452,7 +1452,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Subtract) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 - 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 - 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1467,7 +1467,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Multiply) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 * 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 * 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1482,7 +1482,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Div) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 / 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 / 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1497,7 +1497,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Modulo) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 % 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 % 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1512,7 +1512,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_And) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 & 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 & 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1527,7 +1527,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Or) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 | 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 | 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1542,7 +1542,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Xor) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 ^ 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 ^ 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1557,7 +1557,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LogicalAnd) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = true && false
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (bool) = true && false
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1572,7 +1572,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LogicalOr) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = false || true
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (bool) = false || true
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1587,7 +1587,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Equal) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 == 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (bool) = 3 == 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1602,7 +1602,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_NotEqual) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 != 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (bool) = 3 != 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1617,7 +1617,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LessThan) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 < 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (bool) = 3 < 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1632,7 +1632,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_GreaterThan) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 > 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (bool) = 3 > 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1647,7 +1647,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LessThanEqual) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 <= 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (bool) = 3 <= 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1662,7 +1662,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_GreaterThanEqual) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 >= 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (bool) = 3 >= 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1677,7 +1677,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_ShiftLeft) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 << 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 << 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1692,7 +1692,7 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_ShiftRight) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 >> 4
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 >> 4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1708,15 +1708,29 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Compound) {
|
|||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 = 3 >> 4
|
||||
%2 = %1 + 9
|
||||
%3 = 1 < %2
|
||||
%4 = 2.3 * 5.5
|
||||
%5 = 6.7 / %4
|
||||
%6 = 2.5 > %5
|
||||
%7 = %3 || %6
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (u32) = 3 >> 4
|
||||
%2 (u32) = %1 (u32) + 9
|
||||
%3 (bool) = 1 < %2 (u32)
|
||||
%4 (f32) = 2.3 * 5.5
|
||||
%5 (f32) = 6.7 / %4 (f32)
|
||||
%6 (bool) = 2.5 > %5 (f32)
|
||||
%7 (bool) = %3 (bool) || %6 (bool)
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(IR_BuilderImplTest, EmitExpression_Bitcast) {
|
||||
auto* expr = Bitcast(ty.f32(), 3_u);
|
||||
WrapInFunction(expr);
|
||||
|
||||
auto& b = CreateBuilder();
|
||||
InjectFlowBlock();
|
||||
auto r = b.EmitExpression(expr);
|
||||
ASSERT_TRUE(r) << b.error();
|
||||
|
||||
Disassembler d(b.builder.ir);
|
||||
d.EmitBlockInstructions(b.current_flow_block);
|
||||
EXPECT_EQ(d.AsString(), R"(%1 (f32) = bitcast(3)
|
||||
)");
|
||||
}
|
||||
} // namespace
|
||||
} // namespace tint::ir
|
||||
|
|
|
@ -24,8 +24,8 @@ Temp::Temp(const type::Type* type, Id id) : type_(type), id_(id) {}
|
|||
|
||||
Temp::~Temp() = default;
|
||||
|
||||
std::ostream& Temp::ToString(std::ostream& out, const SymbolTable&) const {
|
||||
out << "%" << std::to_string(AsId());
|
||||
std::ostream& Temp::ToString(std::ostream& out, const SymbolTable& st) const {
|
||||
out << "%" << std::to_string(AsId()) << " (" << type_->FriendlyName(st) << ")";
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ TEST_F(IR_TempTest, id) {
|
|||
EXPECT_EQ(4u, val->AsId());
|
||||
|
||||
val->ToString(str, program->Symbols());
|
||||
EXPECT_EQ("%4", str.str());
|
||||
EXPECT_EQ("%4 (i32)", str.str());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
Loading…
Reference in New Issue