spirv-reader: unwrap references for conversions
Bug: tint:804 Change-Id: I39a4d20de17a5c2ae23e9425d85559b7bb70fd22 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/52845 Auto-Submit: David Neto <dneto@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: James Price <jrprice@google.com> Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
parent
b29a59de6e
commit
5ed3f68eb5
|
@ -4475,6 +4475,7 @@ TypedExpression FunctionEmitter::MakeNumericConversion(
|
||||||
if (!arg_expr) {
|
if (!arg_expr) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
arg_expr.type = arg_expr.type->UnwrapRef();
|
||||||
|
|
||||||
const Type* expr_type = nullptr;
|
const Type* expr_type = nullptr;
|
||||||
if ((opcode == SpvOpConvertSToF) || (opcode == SpvOpConvertUToF)) {
|
if ((opcode == SpvOpConvertSToF) || (opcode == SpvOpConvertUToF)) {
|
||||||
|
@ -4482,21 +4483,24 @@ TypedExpression FunctionEmitter::MakeNumericConversion(
|
||||||
expr_type = requested_type;
|
expr_type = requested_type;
|
||||||
} else {
|
} else {
|
||||||
Fail() << "operand for conversion to floating point must be integral "
|
Fail() << "operand for conversion to floating point must be integral "
|
||||||
"scalar or vector";
|
"scalar or vector: "
|
||||||
|
<< inst.PrettyPrint();
|
||||||
}
|
}
|
||||||
} else if (inst.opcode() == SpvOpConvertFToU) {
|
} else if (inst.opcode() == SpvOpConvertFToU) {
|
||||||
if (arg_expr.type->IsFloatScalarOrVector()) {
|
if (arg_expr.type->IsFloatScalarOrVector()) {
|
||||||
expr_type = parser_impl_.GetUnsignedIntMatchingShape(arg_expr.type);
|
expr_type = parser_impl_.GetUnsignedIntMatchingShape(arg_expr.type);
|
||||||
} else {
|
} else {
|
||||||
Fail() << "operand for conversion to unsigned integer must be floating "
|
Fail() << "operand for conversion to unsigned integer must be floating "
|
||||||
"point scalar or vector";
|
"point scalar or vector: "
|
||||||
|
<< inst.PrettyPrint();
|
||||||
}
|
}
|
||||||
} else if (inst.opcode() == SpvOpConvertFToS) {
|
} else if (inst.opcode() == SpvOpConvertFToS) {
|
||||||
if (arg_expr.type->IsFloatScalarOrVector()) {
|
if (arg_expr.type->IsFloatScalarOrVector()) {
|
||||||
expr_type = parser_impl_.GetSignedIntMatchingShape(arg_expr.type);
|
expr_type = parser_impl_.GetSignedIntMatchingShape(arg_expr.type);
|
||||||
} else {
|
} else {
|
||||||
Fail() << "operand for conversion to signed integer must be floating "
|
Fail() << "operand for conversion to signed integer must be floating "
|
||||||
"point scalar or vector";
|
"point scalar or vector: "
|
||||||
|
<< inst.PrettyPrint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (expr_type == nullptr) {
|
if (expr_type == nullptr) {
|
||||||
|
@ -4506,16 +4510,17 @@ TypedExpression FunctionEmitter::MakeNumericConversion(
|
||||||
|
|
||||||
ast::ExpressionList params;
|
ast::ExpressionList params;
|
||||||
params.push_back(arg_expr.expr);
|
params.push_back(arg_expr.expr);
|
||||||
TypedExpression result{
|
TypedExpression result{expr_type,
|
||||||
expr_type, create<ast::TypeConstructorExpression>(
|
create<ast::TypeConstructorExpression>(
|
||||||
Source{}, expr_type->Build(builder_), std::move(params))};
|
GetSourceForInst(inst), expr_type->Build(builder_),
|
||||||
|
std::move(params))};
|
||||||
|
|
||||||
if (requested_type == expr_type) {
|
if (requested_type == expr_type) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return {requested_type,
|
return {requested_type, create<ast::BitcastExpression>(
|
||||||
create<ast::BitcastExpression>(
|
GetSourceForInst(inst),
|
||||||
Source{}, requested_type->Build(builder_), result.expr)};
|
requested_type->Build(builder_), result.expr)};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FunctionEmitter::EmitFunctionCall(const spvtools::opt::Instruction& inst) {
|
bool FunctionEmitter::EmitFunctionCall(const spvtools::opt::Instruction& inst) {
|
||||||
|
|
|
@ -343,7 +343,8 @@ TEST_F(SpvUnaryConversionTest, ConvertUToF_Scalar_BadArgType) {
|
||||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
auto fe = p->function_emitter(100);
|
auto fe = p->function_emitter(100);
|
||||||
EXPECT_FALSE(fe.EmitBody());
|
EXPECT_FALSE(fe.EmitBody());
|
||||||
EXPECT_THAT(p->error(), Eq("operand for conversion to floating point must be "
|
EXPECT_THAT(p->error(),
|
||||||
|
HasSubstr("operand for conversion to floating point must be "
|
||||||
"integral scalar or vector"));
|
"integral scalar or vector"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,8 +360,9 @@ TEST_F(SpvUnaryConversionTest, ConvertUToF_Vector_BadArgType) {
|
||||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
auto fe = p->function_emitter(100);
|
auto fe = p->function_emitter(100);
|
||||||
EXPECT_FALSE(fe.EmitBody());
|
EXPECT_FALSE(fe.EmitBody());
|
||||||
EXPECT_THAT(p->error(),
|
EXPECT_THAT(
|
||||||
Eq("operand for conversion to floating point must be integral "
|
p->error(),
|
||||||
|
HasSubstr("operand for conversion to floating point must be integral "
|
||||||
"scalar or vector"));
|
"scalar or vector"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,8 +486,9 @@ TEST_F(SpvUnaryConversionTest, ConvertFToS_Scalar_BadArgType) {
|
||||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
auto fe = p->function_emitter(100);
|
auto fe = p->function_emitter(100);
|
||||||
EXPECT_FALSE(fe.EmitBody());
|
EXPECT_FALSE(fe.EmitBody());
|
||||||
EXPECT_THAT(p->error(),
|
EXPECT_THAT(
|
||||||
Eq("operand for conversion to signed integer must be floating "
|
p->error(),
|
||||||
|
HasSubstr("operand for conversion to signed integer must be floating "
|
||||||
"point scalar or vector"));
|
"point scalar or vector"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,8 +504,9 @@ TEST_F(SpvUnaryConversionTest, ConvertFToS_Vector_BadArgType) {
|
||||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
auto fe = p->function_emitter(100);
|
auto fe = p->function_emitter(100);
|
||||||
EXPECT_FALSE(fe.EmitBody());
|
EXPECT_FALSE(fe.EmitBody());
|
||||||
EXPECT_THAT(p->error(),
|
EXPECT_THAT(
|
||||||
Eq("operand for conversion to signed integer must be floating "
|
p->error(),
|
||||||
|
HasSubstr("operand for conversion to signed integer must be floating "
|
||||||
"point scalar or vector"));
|
"point scalar or vector"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -626,8 +630,9 @@ TEST_F(SpvUnaryConversionTest, ConvertFToU_Scalar_BadArgType) {
|
||||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
auto fe = p->function_emitter(100);
|
auto fe = p->function_emitter(100);
|
||||||
EXPECT_FALSE(fe.EmitBody());
|
EXPECT_FALSE(fe.EmitBody());
|
||||||
EXPECT_THAT(p->error(),
|
EXPECT_THAT(
|
||||||
Eq("operand for conversion to unsigned integer must be floating "
|
p->error(),
|
||||||
|
HasSubstr("operand for conversion to unsigned integer must be floating "
|
||||||
"point scalar or vector"));
|
"point scalar or vector"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,8 +648,9 @@ TEST_F(SpvUnaryConversionTest, ConvertFToU_Vector_BadArgType) {
|
||||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
auto fe = p->function_emitter(100);
|
auto fe = p->function_emitter(100);
|
||||||
EXPECT_FALSE(fe.EmitBody());
|
EXPECT_FALSE(fe.EmitBody());
|
||||||
EXPECT_THAT(p->error(),
|
EXPECT_THAT(
|
||||||
Eq("operand for conversion to unsigned integer must be floating "
|
p->error(),
|
||||||
|
HasSubstr("operand for conversion to unsigned integer must be floating "
|
||||||
"point scalar or vector"));
|
"point scalar or vector"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -732,6 +738,56 @@ TEST_F(SpvUnaryConversionTest, ConvertFToU_Vector_ToUnsigned) {
|
||||||
})"));
|
})"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvUnaryConversionTest, ConvertFToU_HoistedValue) {
|
||||||
|
// From crbug.com/tint/804
|
||||||
|
const auto assembly = Preamble() + R"(
|
||||||
|
|
||||||
|
%100 = OpFunction %void None %voidfn
|
||||||
|
%10 = OpLabel
|
||||||
|
OpBranch %30
|
||||||
|
|
||||||
|
%30 = OpLabel
|
||||||
|
OpLoopMerge %90 %80 None
|
||||||
|
OpBranchConditional %true %90 %40
|
||||||
|
|
||||||
|
%40 = OpLabel
|
||||||
|
OpSelectionMerge %50 None
|
||||||
|
OpBranchConditional %true %45 %50
|
||||||
|
|
||||||
|
%45 = OpLabel
|
||||||
|
; This value is hoisted
|
||||||
|
%600 = OpCopyObject %float %float_50
|
||||||
|
OpBranch %50
|
||||||
|
|
||||||
|
%50 = OpLabel
|
||||||
|
OpBranch %90
|
||||||
|
|
||||||
|
%80 = OpLabel ; unreachable continue target
|
||||||
|
%82 = OpConvertFToU %uint %600
|
||||||
|
OpBranch %30 ; backedge
|
||||||
|
|
||||||
|
%90 = OpLabel
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
auto fe = p->function_emitter(100);
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
|
||||||
|
x_82
|
||||||
|
none
|
||||||
|
__u32
|
||||||
|
{
|
||||||
|
TypeConstructor[not set]{
|
||||||
|
__u32
|
||||||
|
Identifier[not set]{x_600}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"));
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(dneto): OpSConvert // only if multiple widths
|
// TODO(dneto): OpSConvert // only if multiple widths
|
||||||
// TODO(dneto): OpUConvert // only if multiple widths
|
// TODO(dneto): OpUConvert // only if multiple widths
|
||||||
// TODO(dneto): OpFConvert // only if multiple widths
|
// TODO(dneto): OpFConvert // only if multiple widths
|
||||||
|
|
|
@ -336,6 +336,14 @@ const Type* Type::UnwrapPtr() const {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Type* Type::UnwrapRef() const {
|
||||||
|
const Type* type = this;
|
||||||
|
while (auto* ptr = type->As<Reference>()) {
|
||||||
|
type = ptr->type;
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
const Type* Type::UnwrapAlias() const {
|
const Type* Type::UnwrapAlias() const {
|
||||||
const Type* type = this;
|
const Type* type = this;
|
||||||
while (auto* alias = type->As<Alias>()) {
|
while (auto* alias = type->As<Alias>()) {
|
||||||
|
|
|
@ -49,6 +49,10 @@ class Type : public Castable<Type> {
|
||||||
/// @returns the inner most store type if this is a pointer, `this` otherwise
|
/// @returns the inner most store type if this is a pointer, `this` otherwise
|
||||||
const Type* UnwrapPtr() const;
|
const Type* UnwrapPtr() const;
|
||||||
|
|
||||||
|
/// @returns the inner most store type if this is a reference, `this`
|
||||||
|
/// otherwise
|
||||||
|
const Type* UnwrapRef() const;
|
||||||
|
|
||||||
/// @returns the inner most aliased type if this is an alias, `this` otherwise
|
/// @returns the inner most aliased type if this is an alias, `this` otherwise
|
||||||
const Type* UnwrapAlias() const;
|
const Type* UnwrapAlias() const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue