Skip to content

Commit

Permalink
[WGSL] Concretize variable initializers
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=261759
rdar://115735821

Reviewed by Mike Wyrzykowski.

When initializing any non-const declaration (i.e. let, override or var), if the
type of the declaration is inferred from the initial value, then the value must
be concretized (as defined in the spec[1]). The implementation is built on top
of the existing constraint function `satisfyOrPromote`, which is applied to
primitive types and components of composite types.

[1]: https://www.w3.org/TR/WGSL/#var-and-value

* Source/WebGPU/WGSL/Constraints.cpp:
(WGSL::concretize):
* Source/WebGPU/WGSL/Constraints.h:
* Source/WebGPU/WGSL/TypeCheck.cpp:
(WGSL::TypeChecker::visitVariable):
* Source/WebGPU/WGSL/tests/invalid/for.wgsl:
* Source/WebGPU/WGSL/tests/valid/concretization.wgsl:

Canonical link: https://commits.webkit.org/268199@main
  • Loading branch information
tadeuzagallo committed Sep 20, 2023
1 parent 24d1408 commit ed75500
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 4 deletions.
40 changes: 40 additions & 0 deletions Source/WebGPU/WGSL/Constraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,44 @@ const Type* satisfyOrPromote(const Type* type, Constraint constraint, const Type
}
}

const Type* concretize(const Type* type, TypeStore& types)
{
using namespace Types;

return WTF::switchOn(*type,
[&](const Primitive&) -> const Type* {
return satisfyOrPromote(type, Constraints::ConcreteScalar, types);
},
[&](const Vector& vector) -> const Type* {
return types.vectorType(concretize(vector.element, types), vector.size);
},
[&](const Matrix& matrix) -> const Type* {
return types.matrixType(concretize(matrix.element, types), matrix.columns, matrix.rows);
},
[&](const Array& array) -> const Type* {
return types.arrayType(concretize(array.element, types), array.size);
},
[&](const Struct&) -> const Type* {
return type;
},
[&](const Function&) -> const Type* {
RELEASE_ASSERT_NOT_REACHED();
},
[&](const Texture&) -> const Type* {
RELEASE_ASSERT_NOT_REACHED();
},
[&](const TextureStorage&) -> const Type* {
RELEASE_ASSERT_NOT_REACHED();
},
[&](const Reference&) -> const Type* {
RELEASE_ASSERT_NOT_REACHED();
},
[&](const TypeConstructor&) -> const Type* {
RELEASE_ASSERT_NOT_REACHED();
},
[&](const Bottom&) -> const Type* {
return type;
});
}

} // namespace WGSL
1 change: 1 addition & 0 deletions Source/WebGPU/WGSL/Constraints.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,6 @@ constexpr Constraint Number = Float | Integer;

bool satisfies(const Type*, Constraint);
const Type* satisfyOrPromote(const Type*, Constraint, const TypeStore&);
const Type* concretize(const Type*, TypeStore&);

} // namespace WGSL
9 changes: 6 additions & 3 deletions Source/WebGPU/WGSL/TypeCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,12 @@ void TypeChecker::visitVariable(AST::Variable& variable, VariableKind variableKi
variable.maybeInitializer()->m_inferredType = initializerType;
}

if (!result)
result = initializerType;
else if (unify(result, initializerType))
if (!result) {
if (variable.flavor() == AST::VariableFlavor::Const)
result = initializerType;
else
result = concretize(initializerType, m_types);
} else if (unify(result, initializerType))
variable.maybeInitializer()->m_inferredType = result;
else
typeError(InferBottom::No, variable.span(), "cannot initialize var of type '", *result, "' with value of type '", *initializerType, "'");
Expand Down
2 changes: 1 addition & 1 deletion Source/WebGPU/WGSL/tests/invalid/for.wgsl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: %not %wgslc | %check

fn testForStatement() {
// CHECK-L: for-loop condition must be bool, got ref<function, <AbstractInt>, read_write>
// CHECK-L: for-loop condition must be bool, got ref<function, i32, read_write>
for (var i = 0; i; i++) {
}
}
3 changes: 3 additions & 0 deletions Source/WebGPU/WGSL/tests/valid/concretization.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ fn testVariableInialization() {
let x2: vec2<u32> = vec2(0, 0);
let x3: f32 = 0;
let x4: f32 = 0.0;

var v1 = vec2(0.0);
v1 = vec2f(0);
}

@vertex
Expand Down

0 comments on commit ed75500

Please sign in to comment.