// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include <utility>

#include "vm/compiler/backend/block_builder.h"
#include "vm/compiler/backend/il_printer.h"
#include "vm/compiler/backend/il_test_helper.h"
#include "vm/compiler/backend/inliner.h"
#include "vm/compiler/backend/loops.h"
#include "vm/compiler/backend/redundancy_elimination.h"
#include "vm/compiler/backend/type_propagator.h"
#include "vm/compiler/compiler_pass.h"
#include "vm/compiler/frontend/kernel_to_il.h"
#include "vm/compiler/jit/compiler.h"
#include "vm/compiler/jit/jit_call_specializer.h"
#include "vm/log.h"
#include "vm/object.h"
#include "vm/parser.h"
#include "vm/symbols.h"
#include "vm/unit_test.h"

namespace dart {

using compiler::BlockBuilder;

ISOLATE_UNIT_TEST_CASE(TypePropagator_RedefinitionAfterStrictCompareWithNull) {
  CompilerState S(thread, /*is_aot=*/false, /*is_optimizing=*/true);

  FlowGraphBuilderHelper H;

  // Add a variable into the scope which would provide static type for the
  // parameter.
  LocalVariable* v0_var =
      new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
                        String::Handle(Symbols::New(thread, "v0")),
                        AbstractType::ZoneHandle(Type::IntType()));
  v0_var->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
  H.flow_graph()->parsed_function().scope()->AddVariable(v0_var);

  auto normal_entry = H.flow_graph()->graph_entry()->normal_entry();

  // We are going to build the following graph:
  //
  // B0[graph_entry]:
  // B1[function_entry]:
  //   v0 <- Parameter(0)
  //   if v0 == null then B2 else B3
  // B2:
  //   Return(v0)
  // B3:
  //   Return(v0)

  Definition* v0;
  auto b2 = H.TargetEntry();
  auto b3 = H.TargetEntry();

  {
    BlockBuilder builder(H.flow_graph(), normal_entry);
    v0 = builder.AddParameter(0, 0, /*with_frame=*/true, kTagged);
    builder.AddBranch(
        new StrictCompareInstr(
            InstructionSource(), Token::kEQ_STRICT, new Value(v0),
            new Value(H.flow_graph()->GetConstant(Object::Handle())),
            /*needs_number_check=*/false, S.GetNextDeoptId()),
        b2, b3);
  }

  {
    BlockBuilder builder(H.flow_graph(), b2);
    builder.AddReturn(new Value(v0));
  }

  {
    BlockBuilder builder(H.flow_graph(), b3);
    builder.AddReturn(new Value(v0));
  }

  H.FinishGraph();

  FlowGraphTypePropagator::Propagate(H.flow_graph());

  // We expect that v0 is inferred to be nullable int because that is what
  // static type of an associated variable tells us.
  EXPECT(v0->Type()->IsNullableInt());

  // In B2 v0 should not have any additional type information so reaching
  // type should be still nullable int.
  auto b2_value = b2->last_instruction()->AsReturn()->value();
  EXPECT(b2_value->Type()->IsNullableInt());

  // In B3 v0 is constrained by comparison with null - it should be non-nullable
  // integer. There should be a Redefinition inserted to prevent LICM past
  // the branch.
  auto b3_value = b3->last_instruction()->AsReturn()->value();
  EXPECT(b3_value->Type()->IsInt());
  EXPECT(b3_value->definition()->IsRedefinition());
  EXPECT(b3_value->definition()->GetBlock() == b3);
}

ISOLATE_UNIT_TEST_CASE(
    TypePropagator_RedefinitionAfterStrictCompareWithLoadClassId) {
  CompilerState S(thread, /*is_aot=*/false, /*is_optimizing=*/true);

  FlowGraphBuilderHelper H;

  // We are going to build the following graph:
  //
  // B0[graph_entry]:
  // B1[function_entry]:
  //   v0 <- Parameter(0)
  //   v1 <- LoadClassId(v0)
  //   if v1 == kDoubleCid then B2 else B3
  // B2:
  //   Return(v0)
  // B3:
  //   Return(v0)

  Definition* v0;
  auto b1 = H.flow_graph()->graph_entry()->normal_entry();
  auto b2 = H.TargetEntry();
  auto b3 = H.TargetEntry();

  {
    BlockBuilder builder(H.flow_graph(), b1);
    v0 = builder.AddParameter(0, 0, /*with_frame=*/true, kTagged);
    auto load_cid = builder.AddDefinition(new LoadClassIdInstr(new Value(v0)));
    builder.AddBranch(
        new StrictCompareInstr(
            InstructionSource(), Token::kEQ_STRICT, new Value(load_cid),
            new Value(H.IntConstant(kDoubleCid)),
            /*needs_number_check=*/false, S.GetNextDeoptId()),
        b2, b3);
  }

  {
    BlockBuilder builder(H.flow_graph(), b2);
    builder.AddReturn(new Value(v0));
  }

  {
    BlockBuilder builder(H.flow_graph(), b3);
    builder.AddReturn(new Value(v0));
  }

  H.FinishGraph();

  FlowGraphTypePropagator::Propagate(H.flow_graph());

  // There should be no information available about the incoming type of
  // the parameter either on entry or in B3.
  EXPECT_PROPERTY(v0->Type()->ToAbstractType(), it.IsDynamicType());
  auto b3_value = b3->last_instruction()->AsReturn()->value();
  EXPECT(b3_value->Type() == v0->Type());

  // In B3 v0 is constrained by comparison of its cid with kDoubleCid - it
  // should be non-nullable double. There should be a Redefinition inserted to
  // prevent LICM past the branch.
  auto b2_value = b2->last_instruction()->AsReturn()->value();
  EXPECT_PROPERTY(b2_value->Type(), it.IsDouble());
  EXPECT_PROPERTY(b2_value->definition(), it.IsRedefinition());
  EXPECT_PROPERTY(b2_value->definition()->GetBlock(), &it == b2);
}

ISOLATE_UNIT_TEST_CASE(TypePropagator_Refinement) {
  CompilerState S(thread, /*is_aot=*/false, /*is_optimizing=*/true);

  const Class& object_class =
      Class::Handle(thread->isolate_group()->object_store()->object_class());

  const FunctionType& signature = FunctionType::Handle(FunctionType::New());
  const Function& target_func = Function::ZoneHandle(Function::New(
      signature, String::Handle(Symbols::New(thread, "dummy2")),
      UntaggedFunction::kRegularFunction,
      /*is_static=*/true,
      /*is_const=*/false,
      /*is_abstract=*/false,
      /*is_external=*/false,
      /*is_native=*/true, object_class, TokenPosition::kNoSource));
  signature.set_result_type(AbstractType::Handle(Type::IntType()));

  const Field& field = Field::ZoneHandle(
      Field::New(String::Handle(Symbols::New(thread, "dummy")),
                 /*is_static=*/true,
                 /*is_final=*/false,
                 /*is_const=*/false,
                 /*is_reflectable=*/true,
                 /*is_late=*/false, object_class, Object::dynamic_type(),
                 TokenPosition::kNoSource, TokenPosition::kNoSource));
  {
    SafepointWriteRwLocker locker(thread,
                                  thread->isolate_group()->program_lock());
    thread->isolate_group()->RegisterStaticField(field, Object::Handle());
  }

  FlowGraphBuilderHelper H;

  // We are going to build the following graph:
  //
  // B0[graph_entry]
  // B1[function_entry]:
  //   v0 <- Parameter(0)
  //   v1 <- Constant(0)
  //   if v0 == 1 then B3 else B2
  // B2:
  //   v2 <- StaticCall(target_func)
  //   goto B4
  // B3:
  //   goto B4
  // B4:
  //  v3 <- phi(v1, v2)
  //  return v5

  Definition* v0;
  Definition* v2;
  PhiInstr* v3;
  auto b1 = H.flow_graph()->graph_entry()->normal_entry();
  auto b2 = H.TargetEntry();
  auto b3 = H.TargetEntry();
  auto b4 = H.JoinEntry();

  {
    BlockBuilder builder(H.flow_graph(), b1);
    v0 = builder.AddParameter(0, 0, /*with_frame=*/true, kTagged);
    builder.AddBranch(new StrictCompareInstr(
                          InstructionSource(), Token::kEQ_STRICT, new Value(v0),
                          new Value(H.IntConstant(1)),
                          /*needs_number_check=*/false, S.GetNextDeoptId()),
                      b2, b3);
  }

  {
    BlockBuilder builder(H.flow_graph(), b2);
    v2 = builder.AddDefinition(
        new StaticCallInstr(InstructionSource(), target_func,
                            /*type_args_len=*/0,
                            /*argument_names=*/Array::empty_array(),
                            new InputsArray(0), S.GetNextDeoptId(),
                            /*call_count=*/0, ICData::RebindRule::kStatic));
    builder.AddInstruction(new GotoInstr(b4, S.GetNextDeoptId()));
  }

  {
    BlockBuilder builder(H.flow_graph(), b3);
    builder.AddInstruction(new GotoInstr(b4, S.GetNextDeoptId()));
  }

  {
    BlockBuilder builder(H.flow_graph(), b4);
    v3 = H.Phi(b4, {{b2, v2}, {b3, H.IntConstant(0)}});
    builder.AddPhi(v3);
    builder.AddReturn(new Value(v3));
  }

  H.FinishGraph();
  FlowGraphTypePropagator::Propagate(H.flow_graph());

  EXPECT_PROPERTY(v2->Type(), it.IsNullableInt());
  EXPECT_PROPERTY(v3->Type(), it.IsNullableInt());

  auto v4 = new LoadStaticFieldInstr(field, InstructionSource());
  H.flow_graph()->InsertBefore(v2, v4, nullptr, FlowGraph::kValue);
  v2->ReplaceUsesWith(v4);
  v2->RemoveFromGraph();

  FlowGraphTypePropagator::Propagate(H.flow_graph());

  EXPECT_PROPERTY(v3->Type(), it.IsNullableInt());
}

// This test verifies that mutable compile types are not incorrectly cached
// as reaching types after inference.
ISOLATE_UNIT_TEST_CASE(TypePropagator_Regress36156) {
  CompilerState S(thread, /*is_aot=*/false, /*is_optimizing=*/true);
  FlowGraphBuilderHelper H;

  // We are going to build the following graph:
  //
  // B0[graph_entry]
  // B1[function_entry]:
  //   v0 <- Parameter(0)
  //   v1 <- Constant(42)
  //   v2 <- Constant(24)
  //   v4 <- Constant(1.0)
  //   if v0 == 1 then B6 else B2
  // B2:
  //   if v0 == 2 then B3 else B4
  // B3:
  //   goto B5
  // B4:
  //   goto B5
  // B5:
  //   v3 <- phi(v1, v2)
  //   goto B7
  // B6:
  //   goto B7
  // B7:
  //  v5 <- phi(v4, v3)
  //  return v5

  Definition* v0;
  PhiInstr* v3;
  PhiInstr* v5;
  auto b1 = H.flow_graph()->graph_entry()->normal_entry();
  auto b2 = H.TargetEntry();
  auto b3 = H.TargetEntry();
  auto b4 = H.TargetEntry();
  auto b5 = H.JoinEntry();
  auto b6 = H.TargetEntry();
  auto b7 = H.JoinEntry();

  {
    BlockBuilder builder(H.flow_graph(), b1);
    v0 = builder.AddParameter(0, 0, /*with_frame=*/true, kTagged);
    builder.AddBranch(new StrictCompareInstr(
                          InstructionSource(), Token::kEQ_STRICT, new Value(v0),
                          new Value(H.IntConstant(1)),
                          /*needs_number_check=*/false, S.GetNextDeoptId()),
                      b6, b2);
  }

  {
    BlockBuilder builder(H.flow_graph(), b2);
    builder.AddBranch(new StrictCompareInstr(
                          InstructionSource(), Token::kEQ_STRICT, new Value(v0),
                          new Value(H.IntConstant(2)),
                          /*needs_number_check=*/false, S.GetNextDeoptId()),
                      b3, b4);
  }

  {
    BlockBuilder builder(H.flow_graph(), b3);
    builder.AddInstruction(new GotoInstr(b5, S.GetNextDeoptId()));
  }

  {
    BlockBuilder builder(H.flow_graph(), b4);
    builder.AddInstruction(new GotoInstr(b5, S.GetNextDeoptId()));
  }

  {
    BlockBuilder builder(H.flow_graph(), b5);
    v3 = H.Phi(b5, {{b3, H.IntConstant(42)}, {b4, H.IntConstant(24)}});
    builder.AddPhi(v3);
    builder.AddInstruction(new GotoInstr(b7, S.GetNextDeoptId()));
  }

  {
    BlockBuilder builder(H.flow_graph(), b6);
    builder.AddInstruction(new GotoInstr(b7, S.GetNextDeoptId()));
  }

  {
    BlockBuilder builder(H.flow_graph(), b7);
    v5 = H.Phi(b7, {{b5, v3}, {b6, H.DoubleConstant(1.0)}});
    builder.AddPhi(v5);
    builder.AddInstruction(new ReturnInstr(InstructionSource(), new Value(v5),
                                           S.GetNextDeoptId()));
  }

  H.FinishGraph();

  FlowGraphTypePropagator::Propagate(H.flow_graph());

  // We expect that v3 has an integer type, and v5 is either T{Object} or
  // T{num}.
  EXPECT_PROPERTY(v3->Type(), it.IsInt());
  EXPECT_PROPERTY(v5->Type()->ToAbstractType(),
                  it.IsObjectType() || it.IsNumberType());

  // Now unbox v3 phi by inserting unboxing for both inputs and boxing
  // for the result.
  {
    v3->set_representation(kUnboxedInt64);
    for (intptr_t i = 0; i < v3->InputCount(); i++) {
      auto input = v3->InputAt(i);
      auto unbox =
          new UnboxInt64Instr(input->CopyWithType(), S.GetNextDeoptId(),
                              Instruction::kNotSpeculative);
      H.flow_graph()->InsertBefore(
          v3->block()->PredecessorAt(i)->last_instruction(), unbox, nullptr,
          FlowGraph::kValue);
      input->BindTo(unbox);
    }

    auto box = new BoxInt64Instr(new Value(v3));
    v3->ReplaceUsesWith(box);
    H.flow_graph()->InsertBefore(b4->last_instruction(), box, nullptr,
                                 FlowGraph::kValue);
  }

  // Run type propagation again.
  FlowGraphTypePropagator::Propagate(H.flow_graph());

  // If CompileType of v3 would be cached as a reaching type at its use in
  // v5 then we will be incorrect type propagation results.
  // We expect that v3 has an integer type, and v5 is either T{Object} or
  // T{num}.
  EXPECT_PROPERTY(v3->Type(), it.IsInt());
  EXPECT_PROPERTY(v5->Type()->ToAbstractType(),
                  it.IsObjectType() || it.IsNumberType());
}

ISOLATE_UNIT_TEST_CASE(CompileType_CanBeSmi) {
  CompilerState S(thread, /*is_aot=*/false, /*is_optimizing=*/true);

  const char* late_tag = TestCase::LateTag();
  auto script_chars = Utils::CStringUniquePtr(
      OS::SCreate(nullptr, R"(
import 'dart:async';

class G<T> {}

class C<NoBound,
        NumBound extends num,
        ComparableBound extends Comparable,
        StringBound extends String> {
  // Simple instantiated types.
  @pragma('vm-test:can-be-smi') %s int t1;
  @pragma('vm-test:can-be-smi') %s num t2;
  @pragma('vm-test:can-be-smi') %s Object t3;
  %s String t4;

  // Type parameters.
  @pragma('vm-test:can-be-smi') %s NoBound tp1;
  @pragma('vm-test:can-be-smi') %s NumBound tp2;
  @pragma('vm-test:can-be-smi') %s ComparableBound tp3;
  %s StringBound tp4;

  // Comparable<T> instantiations.
  @pragma('vm-test:can-be-smi') %s Comparable c1;
  %s Comparable<String> c2;
  @pragma('vm-test:can-be-smi') %s Comparable<num> c3;
  %s Comparable<int> c4;  // int is not a subtype of Comparable<int>.
  @pragma('vm-test:can-be-smi') %s Comparable<NoBound> c5;
  @pragma('vm-test:can-be-smi') %s Comparable<NumBound> c6;
  @pragma('vm-test:can-be-smi') %s Comparable<ComparableBound> c7;
  %s Comparable<StringBound> c8;

  // FutureOr<T> instantiations.
  @pragma('vm-test:can-be-smi') %s FutureOr fo1;
  %s FutureOr<String> fo2;
  @pragma('vm-test:can-be-smi') %s FutureOr<num> fo3;
  @pragma('vm-test:can-be-smi') %s FutureOr<int> fo4;
  @pragma('vm-test:can-be-smi') %s FutureOr<NoBound> fo5;
  @pragma('vm-test:can-be-smi') %s FutureOr<NumBound> fo6;
  @pragma('vm-test:can-be-smi') %s FutureOr<ComparableBound> fo7;
  %s FutureOr<StringBound> fo8;

  // Other generic classes.
  %s G<int> g1;
  %s G<NoBound> g2;
}
)",
                  late_tag, late_tag, late_tag, late_tag, late_tag, late_tag,
                  late_tag, late_tag, late_tag, late_tag, late_tag, late_tag,
                  late_tag, late_tag, late_tag, late_tag, late_tag, late_tag,
                  late_tag, late_tag, late_tag, late_tag, late_tag, late_tag,
                  late_tag, late_tag),
      std::free);

  const auto& lib = Library::Handle(LoadTestScript(script_chars.get()));

  const auto& pragma_can_be_smi =
      String::Handle(Symbols::New(thread, "vm-test:can-be-smi"));
  auto expected_can_be_smi = [&](const Field& f) {
    auto& options = Object::Handle();
    return lib.FindPragma(thread, /*only_core=*/false, f, pragma_can_be_smi,
                          /*multiple=*/false, &options);
  };

  const auto& cls = Class::Handle(GetClass(lib, "C"));
  const auto& err = Error::Handle(cls.EnsureIsFinalized(thread));
  EXPECT(err.IsNull());
  const auto& fields = Array::Handle(cls.fields());

  auto& field = Field::Handle();
  auto& type = AbstractType::Handle();
  for (intptr_t i = 0; i < fields.Length(); i++) {
    field ^= fields.At(i);
    type = field.type();

    auto compile_type = CompileType::FromAbstractType(
        type, CompileType::kCanBeNull, CompileType::kCannotBeSentinel);
    if (compile_type.CanBeSmi() != expected_can_be_smi(field)) {
      dart::Expect(__FILE__, __LINE__)
          .Fail("expected that CanBeSmi() returns %s for compile type %s\n",
                expected_can_be_smi(field) ? "true" : "false",
                compile_type.ToCString());
    }
  }
}

// Verifies that Propagate does not crash when running in AOT mode on a graph
// which contains both AssertAssignable and a CheckClass/Smi after
// EliminateEnvironments was called.
ISOLATE_UNIT_TEST_CASE(TypePropagator_RegressFlutter76919) {
  CompilerState S(thread, /*is_aot=*/true, /*is_optimizing=*/true);

  FlowGraphBuilderHelper H;

  // Add a variable into the scope which would provide static type for the
  // parameter.
  LocalVariable* v0_var =
      new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
                        String::Handle(Symbols::New(thread, "v0")),
                        AbstractType::ZoneHandle(Type::DynamicType()));
  v0_var->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
  H.flow_graph()->parsed_function().scope()->AddVariable(v0_var);

  auto normal_entry = H.flow_graph()->graph_entry()->normal_entry();

  // We are going to build the following graph:
  //
  // B0[graph_entry]:
  // B1[function_entry]:
  //   v0 <- Parameter(0)
  //   AssertAssignable(v0, 'int')
  //   CheckSmi(v0)
  //   Return(v0)

  {
    BlockBuilder builder(H.flow_graph(), normal_entry);
    Definition* v0 = builder.AddParameter(0, 0, /*with_frame=*/true, kTagged);
    auto null_value = builder.AddNullDefinition();
    builder.AddDefinition(new AssertAssignableInstr(
        InstructionSource(), new Value(v0),
        new Value(
            H.flow_graph()->GetConstant(Type::ZoneHandle(Type::IntType()))),
        new Value(null_value), new Value(null_value), Symbols::Value(),
        S.GetNextDeoptId()));
    builder.AddInstruction(new CheckSmiInstr(new Value(v0), S.GetNextDeoptId(),
                                             InstructionSource()));
    builder.AddReturn(new Value(v0));
  }

  H.FinishGraph();

  H.flow_graph()->EliminateEnvironments();
  FlowGraphTypePropagator::Propagate(H.flow_graph());  // Should not crash.
}

#if defined(DART_PRECOMPILER)

// This test verifies that LoadStaticField for non-nullable field
// is non-nullable with sound null safety.
// Regression test for https://github.com/dart-lang/sdk/issues/47119.
ISOLATE_UNIT_TEST_CASE(TypePropagator_NonNullableLoadStaticField) {
  if (!IsolateGroup::Current()->null_safety()) {
    // This test requires sound null safety.
    return;
  }

  const char* kScript = R"(
    const y = 0xDEADBEEF;
    final int x = int.parse('0xFEEDFEED');

    void main(List<String> args) {
      print(x);
      print(x + y);
    }
  )";

  const auto& root_library = Library::Handle(LoadTestScript(kScript));
  const auto& function = Function::Handle(GetFunction(root_library, "main"));

  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);

  Instruction* load = nullptr;

  RELEASE_ASSERT(cursor.TryMatch({
      kMoveGlob,
      {kMatchAndMoveLoadStaticField, &load},
      kMatchAndMovePushArgument,
      kMatchAndMoveStaticCall,
      kMatchAndMoveUnboxInt64,
      kMatchAndMoveBinaryInt64Op,
      kMatchAndMoveBoxInt64,
      kMatchAndMovePushArgument,
      kMatchAndMoveStaticCall,
      kMatchReturn,
  }));

  EXPECT_PROPERTY(load->AsLoadStaticField()->Type(), !it.is_nullable());
}

ISOLATE_UNIT_TEST_CASE(TypePropagator_RedefineCanBeSentinelWithCannotBe) {
  const char* kScript = R"(
    late final int x;
  )";
  Zone* const Z = Thread::Current()->zone();
  const auto& root_library = Library::CheckedHandle(Z, LoadTestScript(kScript));
  const auto& toplevel = Class::Handle(Z, root_library.toplevel_class());
  const auto& field_x = Field::Handle(
      Z, toplevel.LookupStaticField(String::Handle(Z, String::New("x"))));

  using compiler::BlockBuilder;
  CompilerState S(thread, /*is_aot=*/false, /*is_optimizing=*/true);
  FlowGraphBuilderHelper H;

  // We are going to build the following graph:
  //
  // B0[graph]:0 {
  //     v2 <- Constant(#3)
  // }
  // B1[function entry]:2
  //     v3 <- LoadStaticField:10(x, ThrowIfSentinel)
  //     v5 <- Constant(#sentinel)
  //     Branch if StrictCompare:12(===, v3, v5) goto (2, 3)
  // B2[target]:4
  //     goto:16 B4
  // B3[target]:6
  //     v7 <- Redefinition(v3 ^ T{int?})
  //     goto:18 B4
  // B4[join]:8 pred(B2, B3) {
  //       v9 <- phi(v2, v7) alive
  // }
  //     Return:20(v9)

  Definition* v2 = H.IntConstant(3);
  Definition* v3;
  Definition* v7;
  PhiInstr* v9;
  auto b1 = H.flow_graph()->graph_entry()->normal_entry();
  auto b2 = H.TargetEntry();
  auto b3 = H.TargetEntry();
  auto b4 = H.JoinEntry();

  {
    BlockBuilder builder(H.flow_graph(), b1);
    v3 = builder.AddDefinition(new LoadStaticFieldInstr(
        field_x, {},
        /*calls_initializer=*/false, S.GetNextDeoptId()));
    auto v5 = builder.AddDefinition(new ConstantInstr(Object::sentinel()));
    builder.AddBranch(new StrictCompareInstr(
                          {}, Token::kEQ_STRICT, new Value(v3), new Value(v5),
                          /*needs_number_check=*/false, S.GetNextDeoptId()),
                      b2, b3);
  }

  {
    BlockBuilder builder(H.flow_graph(), b2);
    builder.AddInstruction(new GotoInstr(b4, S.GetNextDeoptId()));
  }

  {
    BlockBuilder builder(H.flow_graph(), b3);
    v7 = builder.AddDefinition(new RedefinitionInstr(new Value(v3)));
    CompileType int_type = CompileType::FromAbstractType(
        Type::Handle(Type::IntType()),
        /*can_be_null=*/
        !IsolateGroup::Current()->use_strict_null_safety_checks(),
        /*can_be_sentinel=*/false);
    v7->AsRedefinition()->set_constrained_type(new CompileType(int_type));
    builder.AddInstruction(new GotoInstr(b4, S.GetNextDeoptId()));
  }

  {
    BlockBuilder builder(H.flow_graph(), b4);
    v9 = H.Phi(b4, {{b2, v2}, {b3, v7}});
    builder.AddPhi(v9);
    builder.AddReturn(new Value(v9));
  }

  H.FinishGraph();

  FlowGraphPrinter::PrintGraph("Before TypePropagator", H.flow_graph());
  FlowGraphTypePropagator::Propagate(H.flow_graph());
  FlowGraphPrinter::PrintGraph("After TypePropagator", H.flow_graph());

  auto& blocks = H.flow_graph()->reverse_postorder();
  EXPECT_EQ(5, blocks.length());
  EXPECT_PROPERTY(blocks[0], it.IsGraphEntry());

  // We expect the following types:
  //
  // B1[function entry]:2
  //     v3 <- LoadStaticField:10(x) T{int?~}  // T{int~} in null safe mode
  //     v5 <- Constant(#sentinel) T{Sentinel~}
  //     Branch if StrictCompare:12(===, v3, v5) goto (2, 3)

  EXPECT_PROPERTY(blocks[1], it.IsFunctionEntry());
  EXPECT_PROPERTY(blocks[1]->next(), it.IsLoadStaticField());
  EXPECT_PROPERTY(blocks[1]->next()->AsLoadStaticField(), it.HasType());
  EXPECT_PROPERTY(blocks[1]->next()->AsLoadStaticField()->Type(),
                  it.can_be_sentinel());

  // B3[target]:6
  //     v7 <- Redefinition(v3 ^ T{int?}) T{int?}  // T{int} in null safe mode
  //     goto:18 B4
  EXPECT_PROPERTY(blocks[3], it.IsTargetEntry());
  EXPECT_PROPERTY(blocks[3]->next(), it.IsRedefinition());
  EXPECT_PROPERTY(blocks[3]->next()->AsRedefinition(), it.HasType());
  EXPECT_PROPERTY(blocks[3]->next()->AsRedefinition()->Type(),
                  !it.can_be_sentinel());

  // B4[join]:8 pred(B2, B3) {
  //       v9 <- phi(v2, v7) alive T{int?}  // T{int} in null safe mode
  // }
  //     Return:20(v9)
  EXPECT_PROPERTY(blocks[4], it.IsJoinEntry());
  EXPECT_PROPERTY(blocks[4], it.AsJoinEntry()->phis() != nullptr);
  EXPECT_PROPERTY(blocks[4]->AsJoinEntry()->phis()->At(0), it.HasType());
  EXPECT_PROPERTY(blocks[4]->AsJoinEntry()->phis()->At(0)->Type(),
                  !it.can_be_sentinel());
}

#endif  // defined(DART_PRECOMPILER)

}  // namespace dart
