[vm/compiler] Optimize 'double == int' in AOT
TEST=vm/cc/IRTest_DoubleEqualsSmi
Fixes https://github.com/dart-lang/sdk/issues/47031
Change-Id: I6395ae50806b238971872b375c495962cb868cb1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/212484
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc
index 8a0978b..6fa1d01 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.cc
+++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -602,7 +602,7 @@
case Token::kNE: {
// TODO(dartbug.com/32166): Support EQ, NE for nullable doubles.
// (requires null-aware comparison instruction).
- if (left_type->IsDouble() && right_type->IsDouble()) {
+ if (!left_type->is_nullable() && !right_type->is_nullable()) {
left_value = PrepareStaticOpInput(left_value, kDoubleCid, instr);
right_value = PrepareStaticOpInput(right_value, kDoubleCid, instr);
replacement = new (Z) EqualityCompareInstr(
diff --git a/runtime/vm/compiler/backend/il_test.cc b/runtime/vm/compiler/backend/il_test.cc
index 260d17d..d373a1a 100644
--- a/runtime/vm/compiler/backend/il_test.cc
+++ b/runtime/vm/compiler/backend/il_test.cc
@@ -604,4 +604,33 @@
RANGES_CONTAIN_EXPECTED_CIDS(abstract_range, expected_cids);
}
+// This test verifies that double == Smi is recognized and
+// implemented using EqualityCompare.
+// Regression test for https://github.com/dart-lang/sdk/issues/47031.
+ISOLATE_UNIT_TEST_CASE(IRTest_DoubleEqualsSmi) {
+ const char* kScript = R"(
+ bool foo(double x) => (x + 0.5) == 0;
+ main() {
+ foo(-0.5);
+ }
+ )";
+
+ const auto& root_library = Library::Handle(LoadTestScript(kScript));
+ const auto& function = Function::Handle(GetFunction(root_library, "foo"));
+
+ TestPipeline pipeline(function, CompilerPass::kAOT);
+ FlowGraph* flow_graph = pipeline.RunPasses({});
+
+ auto entry = flow_graph->graph_entry()->normal_entry();
+ ILMatcher cursor(flow_graph, entry, /*trace=*/true,
+ ParallelMovesHandling::kSkip);
+
+ RELEASE_ASSERT(cursor.TryMatch({
+ kMoveGlob,
+ kMatchAndMoveBinaryDoubleOp,
+ kMatchAndMoveEqualityCompare,
+ kMatchReturn,
+ }));
+}
+
} // namespace dart