[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>
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index a8eaa1d..9483257 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -1163,6 +1163,7 @@
if (val_id == 0) {
return 0;
}
+ val_id = GenerateLoadIfNeeded(cast->expr()->result_type(), val_id);
auto* to_type = cast->result_type()->UnwrapPtrIfNeeded();
auto* from_type = cast->expr()->result_type()->UnwrapPtrIfNeeded();
@@ -1178,7 +1179,8 @@
op = spv::Op::OpConvertFToU;
}
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;
}
diff --git a/src/writer/spirv/builder_cast_expression_test.cc b/src/writer/spirv/builder_cast_expression_test.cc
index 0af27a2..90ca156 100644
--- a/src/writer/spirv/builder_cast_expression_test.cc
+++ b/src/writer/spirv/builder_cast_expression_test.cc
@@ -15,6 +15,7 @@
#include "gtest/gtest.h"
#include "src/ast/cast_expression.h"
#include "src/ast/float_literal.h"
+#include "src/ast/identifier_expression.h"
#include "src/ast/int_literal.h"
#include "src/ast/module.h"
#include "src/ast/scalar_constructor_expression.h"
@@ -64,7 +65,39 @@
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) {}