tint: Implement const eval of unary complement
Bug: tint:1581
Bug: chromium:1343242
Change-Id: I76b4f041494ceb2afcf5a604fcda32e046ffca35
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/96100
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index 7fc09cc..4c49cd1 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -1508,7 +1508,7 @@
current_statement_, value, has_side_effects);
};
- // ct_ctor_or_conv is a helper for building a sem::TypeConstructor for an array or structure
+ // arr_or_str_ctor is a helper for building a sem::TypeConstructor for an array or structure
// constructor call target.
auto arr_or_str_ctor = [&](const sem::Type* ty,
const sem::CallTarget* call_target) -> sem::Call* {
@@ -1523,15 +1523,18 @@
if (!value) {
// Constant evaluation failed.
// Can happen for expressions that will fail validation (later).
+ // Use the kRuntime EvaluationStage, as kConstant will trigger an assertion in the
+ // sem::Expression constructor, which checks that kConstant is paired with a
+ // constant value.
stage = sem::EvaluationStage::kRuntime;
}
}
return builder_->create<sem::Call>(expr, call_target, stage, std::move(args),
- current_statement_, std::move(value), has_side_effects);
+ current_statement_, value, has_side_effects);
};
- // ct_ctor_or_conv is a helper for building either a sem::TypeConstructor or sem::TypeConversion
+ // ty_ctor_or_conv is a helper for building either a sem::TypeConstructor or sem::TypeConversion
// call for the given semantic type.
auto ty_ctor_or_conv = [&](const sem::Type* ty) {
return Switch(
@@ -1710,7 +1713,12 @@
}
auto stage = builtin.sem->Stage();
- if (stage == sem::EvaluationStage::kConstant) {
+ if (stage == sem::EvaluationStage::kConstant) { // <-- Optimization
+ // If the builtin is not annotated with @const, then it can only be evaluated
+ // at runtime, in which case there's no point checking the evaluation stage of the
+ // arguments.
+
+ // The builtin is @const annotated. Check all arguments are also constant.
for (auto* arg : args) {
stage = sem::EarliestStage(stage, arg->Stage());
}
@@ -1718,7 +1726,7 @@
// If the builtin is @const, and all arguments have constant values, evaluate the builtin now.
const sem::Constant* value = nullptr;
- if (stage == sem::EvaluationStage::kConstant && builtin.const_eval_fn) {
+ if (stage == sem::EvaluationStage::kConstant) {
value = (const_eval_.*builtin.const_eval_fn)(builtin.sem->ReturnType(), args.data(),
args.size());
}
@@ -2129,7 +2137,7 @@
const sem::Type* ty = nullptr;
const sem::Variable* source_var = nullptr;
const sem::Constant* value = nullptr;
- auto stage = sem::EvaluationStage::kRuntime; // TODO(crbug.com/tint/1581)
+ auto stage = sem::EvaluationStage::kRuntime;
switch (unary->op) {
case ast::UnaryOp::kAddressOf:
@@ -2181,10 +2189,15 @@
return nullptr;
}
}
- ty = op.result;
- if (op.const_eval_fn) {
- value = (const_eval_.*op.const_eval_fn)(ty, &expr, 1u);
+ stage = expr->Stage();
+ if (stage == sem::EvaluationStage::kConstant) {
+ if (op.const_eval_fn) {
+ value = (const_eval_.*op.const_eval_fn)(ty, &expr, 1u);
+ } else {
+ stage = sem::EvaluationStage::kRuntime;
+ }
}
+ ty = op.result;
break;
}
}