writer/spirv: Fix stack-use-after-return

Never create semantic types on the stack.
Always use ProgramBuilder::create().

These stack pointers have a tendency of being stored, either by other
types as sub-types, or by maps (see associated bug).

Also, there's a lot of logic that assumes that semantic types are
de-duplicated, and that you can compare pointers. Creating new instances
on the stack will break this in exciting ways.

Fixed: chromium:1243944
Change-Id: I40a652f8c424030106adad2e6531287af13c8714
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/62943
Auto-Submit: Ben Clayton <bclayton@google.com>
Commit-Queue: David Neto <dneto@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
Ben Clayton 2021-08-27 14:50:07 +00:00 committed by Tint LUCI CQ
parent 200cdd2052
commit e9fdd50443
1 changed files with 21 additions and 25 deletions

View File

@ -478,9 +478,9 @@ bool Builder::GenerateExecutionModes(ast::Function* func, uint32_t id) {
} }
has_overridable_workgroup_size_ = true; has_overridable_workgroup_size_ = true;
sem::U32 u32; auto* vec3_u32 =
sem::Vector vec3_u32(&u32, 3); builder_.create<sem::Vector>(builder_.create<sem::U32>(), 3);
uint32_t vec3_u32_type_id = GenerateTypeIfNeeded(&vec3_u32); uint32_t vec3_u32_type_id = GenerateTypeIfNeeded(vec3_u32);
if (vec3_u32_type_id == 0) { if (vec3_u32_type_id == 0) {
return 0; return 0;
} }
@ -1675,23 +1675,19 @@ uint32_t Builder::GenerateConstantIfNeeded(const ScalarConstant& constant) {
switch (constant.kind) { switch (constant.kind) {
case ScalarConstant::Kind::kU32: { case ScalarConstant::Kind::kU32: {
sem::U32 u32; type_id = GenerateTypeIfNeeded(builder_.create<sem::U32>());
type_id = GenerateTypeIfNeeded(&u32);
break; break;
} }
case ScalarConstant::Kind::kI32: { case ScalarConstant::Kind::kI32: {
sem::I32 i32; type_id = GenerateTypeIfNeeded(builder_.create<sem::I32>());
type_id = GenerateTypeIfNeeded(&i32);
break; break;
} }
case ScalarConstant::Kind::kF32: { case ScalarConstant::Kind::kF32: {
sem::F32 f32; type_id = GenerateTypeIfNeeded(builder_.create<sem::F32>());
type_id = GenerateTypeIfNeeded(&f32);
break; break;
} }
case ScalarConstant::Kind::kBool: { case ScalarConstant::Kind::kBool: {
sem::Bool bool_; type_id = GenerateTypeIfNeeded(builder_.create<sem::Bool>());
type_id = GenerateTypeIfNeeded(&bool_);
break; break;
} }
} }
@ -2457,8 +2453,9 @@ uint32_t Builder::GenerateIntrinsic(ast::CallExpression* call,
const uint32_t kMaxNormalExponent = 0x7f00000; const uint32_t kMaxNormalExponent = 0x7f00000;
auto set_id = GetGLSLstd450Import(); auto set_id = GetGLSLstd450Import();
sem::U32 u32; auto* u32 = builder_.create<sem::U32>();
auto unsigned_id = GenerateTypeIfNeeded(&u32);
auto unsigned_id = GenerateTypeIfNeeded(u32);
auto exponent_mask_id = auto exponent_mask_id =
GenerateConstantIfNeeded(ScalarConstant::U32(kExponentMask)); GenerateConstantIfNeeded(ScalarConstant::U32(kExponentMask));
auto min_exponent_id = auto min_exponent_id =
@ -2470,8 +2467,8 @@ uint32_t Builder::GenerateIntrinsic(ast::CallExpression* call,
// same size, and create vector constants by replicating the scalars. // same size, and create vector constants by replicating the scalars.
// I expect backend compilers to fold these into unique constants, so // I expect backend compilers to fold these into unique constants, so
// there is no loss of efficiency. // there is no loss of efficiency.
sem::Vector uvec_ty(&u32, fvec_ty->Width()); auto* uvec_ty = builder_.create<sem::Vector>(u32, fvec_ty->Width());
unsigned_id = GenerateTypeIfNeeded(&uvec_ty); unsigned_id = GenerateTypeIfNeeded(uvec_ty);
auto splat = [&](uint32_t scalar_id) -> uint32_t { auto splat = [&](uint32_t scalar_id) -> uint32_t {
auto splat_result = result_op(); auto splat_result = result_op();
OperandList splat_params{Operand::Int(unsigned_id), splat_result}; OperandList splat_params{Operand::Int(unsigned_id), splat_result};
@ -2562,12 +2559,12 @@ uint32_t Builder::GenerateIntrinsic(ast::CallExpression* call,
auto* result_vector_type = intrinsic->ReturnType()->As<sem::Vector>(); auto* result_vector_type = intrinsic->ReturnType()->As<sem::Vector>();
if (result_vector_type && if (result_vector_type &&
intrinsic->Parameters()[2]->Type()->is_scalar()) { intrinsic->Parameters()[2]->Type()->is_scalar()) {
sem::Bool bool_type; auto* bool_vec_ty = builder_.create<sem::Vector>(
sem::Vector bool_vec_type(&bool_type, result_vector_type->Width()); builder_.create<sem::Bool>(), result_vector_type->Width());
if (!GenerateTypeIfNeeded(&bool_vec_type)) { if (!GenerateTypeIfNeeded(bool_vec_ty)) {
return 0; return 0;
} }
cond_id = GenerateSplat(cond_id, &bool_vec_type); cond_id = GenerateSplat(cond_id, bool_vec_ty);
if (cond_id == 0) { if (cond_id == 0) {
return 0; return 0;
} }
@ -3231,8 +3228,8 @@ bool Builder::GenerateAtomicIntrinsic(ast::CallExpression* call,
return false; return false;
} }
sem::Bool bool_sem_type; auto* bool_sem_ty = builder_.create<sem::Bool>();
auto bool_type = GenerateTypeIfNeeded(&bool_sem_type); auto bool_type = GenerateTypeIfNeeded(bool_sem_ty);
if (bool_type == 0) { if (bool_type == 0) {
return false; return false;
} }
@ -3924,8 +3921,7 @@ bool Builder::GenerateTextureType(const sem::Texture* texture,
uint32_t type_id = 0u; uint32_t type_id = 0u;
if (texture->IsAnyOf<sem::DepthTexture, sem::DepthMultisampledTexture>()) { if (texture->IsAnyOf<sem::DepthTexture, sem::DepthMultisampledTexture>()) {
sem::F32 f32; type_id = GenerateTypeIfNeeded(builder_.create<sem::F32>());
type_id = GenerateTypeIfNeeded(&f32);
} else if (auto* s = texture->As<sem::SampledTexture>()) { } else if (auto* s = texture->As<sem::SampledTexture>()) {
type_id = GenerateTypeIfNeeded(s->type()); type_id = GenerateTypeIfNeeded(s->type());
} else if (auto* ms = texture->As<sem::MultisampledTexture>()) { } else if (auto* ms = texture->As<sem::MultisampledTexture>()) {
@ -3978,8 +3974,8 @@ bool Builder::GenerateArrayType(const sem::Array* ary, const Operand& result) {
bool Builder::GenerateMatrixType(const sem::Matrix* mat, bool Builder::GenerateMatrixType(const sem::Matrix* mat,
const Operand& result) { const Operand& result) {
sem::Vector col_type(mat->type(), mat->rows()); auto* col_type = builder_.create<sem::Vector>(mat->type(), mat->rows());
auto col_type_id = GenerateTypeIfNeeded(&col_type); auto col_type_id = GenerateTypeIfNeeded(col_type);
if (has_error()) { if (has_error()) {
return false; return false;
} }