[spirv-builder] Generate load for cast expression.

If the value being casted is a pointer it must be loaded first. This CL
adds the needed load.

Bug: tint:72
Change-Id: Ia019b7976db6b97c811f6424db8fe4f07a3d11f3
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/20900
Reviewed-by: David Neto <dneto@google.com>
Commit-Queue: dan sinclair <dsinclair@google.com>
This commit is contained in:
dan sinclair 2020-05-04 17:06:05 +00:00
parent c8c10e83df
commit 8a669aabeb
2 changed files with 37 additions and 2 deletions

View File

@ -1163,6 +1163,7 @@ uint32_t Builder::GenerateCastExpression(ast::CastExpression* cast) {
if (val_id == 0) { if (val_id == 0) {
return 0; return 0;
} }
val_id = GenerateLoadIfNeeded(cast->expr()->result_type(), val_id);
auto* to_type = cast->result_type()->UnwrapPtrIfNeeded(); auto* to_type = cast->result_type()->UnwrapPtrIfNeeded();
auto* from_type = cast->expr()->result_type()->UnwrapPtrIfNeeded(); auto* from_type = cast->expr()->result_type()->UnwrapPtrIfNeeded();
@ -1178,7 +1179,8 @@ uint32_t Builder::GenerateCastExpression(ast::CastExpression* cast) {
op = spv::Op::OpConvertFToU; op = spv::Op::OpConvertFToU;
} }
if (op == spv::Op::OpNop) { if (op == spv::Op::OpNop) {
error_ = "unable to determine conversion type for cast"; error_ = "unable to determine conversion type for cast, from: " +
from_type->type_name() + " to: " + to_type->type_name();
return 0; return 0;
} }

View File

@ -15,6 +15,7 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "src/ast/cast_expression.h" #include "src/ast/cast_expression.h"
#include "src/ast/float_literal.h" #include "src/ast/float_literal.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/int_literal.h" #include "src/ast/int_literal.h"
#include "src/ast/module.h" #include "src/ast/module.h"
#include "src/ast/scalar_constructor_expression.h" #include "src/ast/scalar_constructor_expression.h"
@ -64,7 +65,39 @@ TEST_F(BuilderTest, Cast_I32ToFloat) {
TEST_F(BuilderTest, DISABLED_Cast_U32ToFloat) {} TEST_F(BuilderTest, DISABLED_Cast_U32ToFloat) {}
TEST_F(BuilderTest, DISABLED_Cast_WithLoad) {} TEST_F(BuilderTest, Cast_WithLoad) {
ast::type::F32Type f32;
ast::type::I32Type i32;
// var i : i32 = 1;
// cast<f32>(i);
auto var =
std::make_unique<ast::Variable>("i", ast::StorageClass::kPrivate, &i32);
ast::CastExpression cast(&f32,
std::make_unique<ast::IdentifierExpression>("i"));
Context ctx;
ast::Module mod;
TypeDeterminer td(&ctx, &mod);
td.RegisterVariableForTesting(var.get());
ASSERT_TRUE(td.DetermineResultType(&cast)) << td.error();
Builder b(&mod);
b.push_function(Function{});
ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
EXPECT_EQ(b.GenerateCastExpression(&cast), 4u) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
%2 = OpTypePointer Private %3
%1 = OpVariable %2 Private
%5 = OpTypeFloat 32
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
R"(%6 = OpLoad %3 %1
%4 = OpConvertSToF %5 %6
)");
}
TEST_F(BuilderTest, DISABLED_Cast_WithAlias) {} TEST_F(BuilderTest, DISABLED_Cast_WithAlias) {}