diff --git a/compiler/Android.bp b/compiler/Android.bp
index f11d256..d060dd4 100644
--- a/compiler/Android.bp
+++ b/compiler/Android.bp
@@ -54,6 +54,7 @@
         "optimizing/code_generator_utils.cc",
         "optimizing/code_sinking.cc",
         "optimizing/constant_folding.cc",
+        "optimizing/constructor_fence_redundancy_elimination.cc",
         "optimizing/dead_code_elimination.cc",
         "optimizing/escape.cc",
         "optimizing/graph_checker.cc",
diff --git a/compiler/optimizing/code_sinking.cc b/compiler/optimizing/code_sinking.cc
index 6c3a9fd..b558eb1 100644
--- a/compiler/optimizing/code_sinking.cc
+++ b/compiler/optimizing/code_sinking.cc
@@ -64,6 +64,11 @@
     // A fence with "0" inputs is dead and should've been removed in a prior pass.
     DCHECK_NE(0u, ctor_fence->InputCount());
 
+    // TODO: this should be simplified to 'return true' since it's
+    // potentially pessimizing any code sinking for inlined constructors with final fields.
+    // TODO: double check that if the final field assignments are not moved,
+    // then the fence is not moved either.
+
     return ctor_fence->GetAssociatedAllocation() != nullptr;
   }
 
diff --git a/compiler/optimizing/constructor_fence_redundancy_elimination.cc b/compiler/optimizing/constructor_fence_redundancy_elimination.cc
new file mode 100644
index 0000000..ff7ce60
--- /dev/null
+++ b/compiler/optimizing/constructor_fence_redundancy_elimination.cc
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "constructor_fence_redundancy_elimination.h"
+
+#include "base/arena_allocator.h"
+
+namespace art {
+
+static constexpr bool kCfreLogFenceInputCount = false;
+
+// TODO: refactor this code by reusing escape analysis.
+class CFREVisitor : public HGraphVisitor {
+ public:
+  CFREVisitor(HGraph* graph, OptimizingCompilerStats* stats)
+      : HGraphVisitor(graph),
+        scoped_allocator_(graph->GetArena()->GetArenaPool()),
+        candidate_fences_(scoped_allocator_.Adapter(kArenaAllocCFRE)),
+        candidate_fence_targets_(scoped_allocator_.Adapter(kArenaAllocCFRE)),
+        stats_(stats) {}
+
+  void VisitBasicBlock(HBasicBlock* block) OVERRIDE {
+    // Visit all instructions in block.
+    HGraphVisitor::VisitBasicBlock(block);
+
+    // If there were any unmerged fences left, merge them together,
+    // the objects are considered 'published' at the end of the block.
+    MergeCandidateFences();
+  }
+
+  void VisitConstructorFence(HConstructorFence* constructor_fence) OVERRIDE {
+    candidate_fences_.push_back(constructor_fence);
+
+    for (size_t input_idx = 0; input_idx < constructor_fence->InputCount(); ++input_idx) {
+      candidate_fence_targets_.Insert(constructor_fence->InputAt(input_idx));
+    }
+  }
+
+  void VisitBoundType(HBoundType* bound_type) OVERRIDE {
+    VisitAlias(bound_type);
+  }
+
+  void VisitNullCheck(HNullCheck* null_check) OVERRIDE {
+    VisitAlias(null_check);
+  }
+
+  void VisitSelect(HSelect* select) OVERRIDE {
+    VisitAlias(select);
+  }
+
+  void VisitInstanceFieldSet(HInstanceFieldSet* instruction) OVERRIDE {
+    HInstruction* value = instruction->InputAt(1);
+    VisitSetLocation(instruction, value);
+  }
+
+  void VisitStaticFieldSet(HStaticFieldSet* instruction) OVERRIDE {
+    HInstruction* value = instruction->InputAt(1);
+    VisitSetLocation(instruction, value);
+  }
+
+  void VisitArraySet(HArraySet* instruction) OVERRIDE {
+    HInstruction* value = instruction->InputAt(2);
+    VisitSetLocation(instruction, value);
+  }
+
+  void VisitDeoptimize(HDeoptimize* instruction ATTRIBUTE_UNUSED) {
+    // Pessimize: Merge all fences.
+    MergeCandidateFences();
+  }
+
+  void VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) OVERRIDE {
+    HandleInvoke(invoke);
+  }
+
+  void VisitInvokeVirtual(HInvokeVirtual* invoke) OVERRIDE {
+    HandleInvoke(invoke);
+  }
+
+  void VisitInvokeInterface(HInvokeInterface* invoke) OVERRIDE {
+    HandleInvoke(invoke);
+  }
+
+  void VisitInvokeUnresolved(HInvokeUnresolved* invoke) OVERRIDE {
+    HandleInvoke(invoke);
+  }
+
+  void VisitInvokePolymorphic(HInvokePolymorphic* invoke) OVERRIDE {
+    HandleInvoke(invoke);
+  }
+
+  void VisitClinitCheck(HClinitCheck* clinit) OVERRIDE {
+    HandleInvoke(clinit);
+  }
+
+  void VisitUnresolvedInstanceFieldGet(HUnresolvedInstanceFieldGet* instruction) OVERRIDE {
+    // Conservatively treat it as an invocation.
+    HandleInvoke(instruction);
+  }
+
+  void VisitUnresolvedInstanceFieldSet(HUnresolvedInstanceFieldSet* instruction) OVERRIDE {
+    // Conservatively treat it as an invocation.
+    HandleInvoke(instruction);
+  }
+
+  void VisitUnresolvedStaticFieldGet(HUnresolvedStaticFieldGet* instruction) OVERRIDE {
+    // Conservatively treat it as an invocation.
+    HandleInvoke(instruction);
+  }
+
+  void VisitUnresolvedStaticFieldSet(HUnresolvedStaticFieldSet* instruction) OVERRIDE {
+    // Conservatively treat it as an invocation.
+    HandleInvoke(instruction);
+  }
+
+ private:
+  void HandleInvoke(HInstruction* invoke) {
+    // An object is considered "published" if it escapes into an invoke as any of the parameters.
+    if (HasInterestingPublishTargetAsInput(invoke)) {
+        MergeCandidateFences();
+    }
+  }
+
+  // Called by any instruction visitor that may create an alias.
+  // These instructions may create an alias:
+  // - BoundType
+  // - NullCheck
+  // - Select
+  //
+  // These also create an alias, but are not handled by this function:
+  // - Phi: propagates values across blocks, but we always merge at the end of a block.
+  // - Invoke: this is handled by HandleInvoke.
+  void VisitAlias(HInstruction* aliasing_inst) {
+    // An object is considered "published" if it becomes aliased by other instructions.
+    if (HasInterestingPublishTargetAsInput(aliasing_inst))  {
+      // Note that constructing a "NullCheck" for new-instance, new-array,
+      // or a 'this' (receiver) reference is impossible.
+      //
+      // If by some reason we actually encounter such a NullCheck(FenceTarget),
+      // we LOG(WARNING).
+      if (UNLIKELY(aliasing_inst->IsNullCheck())) {
+        LOG(kIsDebugBuild ? FATAL : WARNING)
+            << "Unexpected instruction: NullCheck; should not be legal in graph";
+        // We then do a best-effort to handle this case.
+      }
+      MergeCandidateFences();
+    }
+  }
+
+  void VisitSetLocation(HInstruction* inst ATTRIBUTE_UNUSED, HInstruction* store_input) {
+    // An object is considered "published" if it's stored onto the heap.
+    // Sidenote: A later "LSE" pass can still remove the fence if it proves the
+    // object doesn't actually escape.
+    if (IsInterestingPublishTarget(store_input)) {
+      // Merge all constructor fences that we've seen since
+      // the last interesting store (or since the beginning).
+      MergeCandidateFences();
+    }
+  }
+
+  bool HasInterestingPublishTargetAsInput(HInstruction* inst) {
+    for (size_t input_count = 0; input_count < inst->InputCount(); ++input_count) {
+      if (IsInterestingPublishTarget(inst->InputAt(input_count))) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  // Merges all the existing fences we've seen so far into the last-most fence.
+  //
+  // This resets the list of candidate fences and their targets back to {}.
+  void MergeCandidateFences() {
+    if (candidate_fences_.empty()) {
+      // Nothing to do, need 1+ fences to merge.
+      return;
+    }
+
+    // The merge target is always the "last" candidate fence.
+    HConstructorFence* merge_target = candidate_fences_[candidate_fences_.size() - 1];
+
+    for (HConstructorFence* fence : candidate_fences_) {
+      MaybeMerge(merge_target, fence);
+    }
+
+    if (kCfreLogFenceInputCount) {
+      LOG(INFO) << "CFRE-MergeCandidateFences: Post-merge fence input count "
+                << merge_target->InputCount();
+    }
+
+    // Each merge acts as a cut-off point. The optimization is reset completely.
+    // In theory, we could push the fence as far as its publish, but in practice
+    // there is no benefit to this extra complexity unless we also reordered
+    // the stores to come later.
+    candidate_fences_.clear();
+    candidate_fence_targets_.Clear();
+  }
+
+  // A publishing 'store' is only interesting if the value being stored
+  // is one of the fence `targets` in `candidate_fences`.
+  bool IsInterestingPublishTarget(HInstruction* store_input) const {
+    return candidate_fence_targets_.Find(store_input) != candidate_fence_targets_.end();
+  }
+
+  void MaybeMerge(HConstructorFence* target, HConstructorFence* src) {
+    if (target == src) {
+      return;  // Don't merge a fence into itself.
+      // This is mostly for stats-purposes, we don't want to count merge(x,x)
+      // as removing a fence because it's a no-op.
+    }
+
+    target->Merge(src);
+
+    MaybeRecordStat(stats_, MethodCompilationStat::kConstructorFenceRemovedCFRE);
+  }
+
+  // Phase-local heap memory allocator for CFRE optimizer. Storage obtained
+  // through this allocator is immediately released when the CFRE optimizer is done.
+  ArenaAllocator scoped_allocator_;
+
+  // Set of constructor fences that we've seen in the current block.
+  // Each constructor fences acts as a guard for one or more `targets`.
+  // There exist no stores to any `targets` between any of these fences.
+  //
+  // Fences are in succession order (e.g. fence[i] succeeds fence[i-1]
+  // within the same basic block).
+  ArenaVector<HConstructorFence*> candidate_fences_;
+
+  // Stores a set of the fence targets, to allow faster lookup of whether
+  // a detected publish is a target of one of the candidate fences.
+  ArenaHashSet<HInstruction*> candidate_fence_targets_;
+
+  // Used to record stats about the optimization.
+  OptimizingCompilerStats* const stats_;
+
+  DISALLOW_COPY_AND_ASSIGN(CFREVisitor);
+};
+
+void ConstructorFenceRedundancyElimination::Run() {
+  CFREVisitor cfre_visitor(graph_, stats_);
+
+  // Arbitrarily visit in reverse-post order.
+  // The exact block visit order does not matter, as the algorithm
+  // only operates on a single block at a time.
+  cfre_visitor.VisitReversePostOrder();
+}
+
+}  // namespace art
diff --git a/compiler/optimizing/constructor_fence_redundancy_elimination.h b/compiler/optimizing/constructor_fence_redundancy_elimination.h
new file mode 100644
index 0000000..d89210c
--- /dev/null
+++ b/compiler/optimizing/constructor_fence_redundancy_elimination.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_COMPILER_OPTIMIZING_CONSTRUCTOR_FENCE_REDUNDANCY_ELIMINATION_H_
+#define ART_COMPILER_OPTIMIZING_CONSTRUCTOR_FENCE_REDUNDANCY_ELIMINATION_H_
+
+#include "optimization.h"
+
+namespace art {
+
+/*
+ * Constructor Fence Redundancy Elimination (CFRE).
+ *
+ * A local optimization pass that merges redundant constructor fences
+ * together within the same basic block.
+ *
+ * Abbreviations:
+ * - CF: Constructor Fence
+ * - CFS: Constructor Fence Set
+ * - CFTargets: The unique set of the inputs of all the instructions in CFS.
+ *
+ * Given any CFS = { CF(x), CF(y), CF(z), ... }, define CFTargets = { x, y, z, ... }.
+ * - Publish(R) must not exist for any R in CFTargets if this Publish(R) is between any CF in CFS.
+ * - This type of Publish(R) is called an "interesting publish".
+ *
+ * A Publish(R) is considered any instruction at which the reference to "R"
+ * may escape (e.g. invoke, store, return, etc) to another thread.
+ *
+ * Starting at the beginning of the block:
+ * - Find the largest contiguous CFS.
+ * - If we see an interesting publish, merge all instructions in CFS into a single CF(CFTargets).
+ * - Repeat until the block is fully visited.
+ * - At the end of the block, merge all instructions in CFS into a single CF(CFTargets).
+ */
+class ConstructorFenceRedundancyElimination : public HOptimization {
+ public:
+  ConstructorFenceRedundancyElimination(HGraph* graph,
+                                        OptimizingCompilerStats* stats)
+      : HOptimization(graph, kPassName, stats) {}
+
+  void Run() OVERRIDE;
+
+  static constexpr const char* kPassName = "constructor_fence_redundancy_elimination";
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ConstructorFenceRedundancyElimination);
+};
+
+}  // namespace art
+
+#endif  // ART_COMPILER_OPTIMIZING_CONSTRUCTOR_FENCE_REDUNDANCY_ELIMINATION_H_
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 8644f67..e34d4a2 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -1271,18 +1271,59 @@
   return remove_count;
 }
 
-HInstruction* HConstructorFence::GetAssociatedAllocation() {
+void HConstructorFence::Merge(HConstructorFence* other) {
+  // Do not delete yourself from the graph.
+  DCHECK(this != other);
+  // Don't try to merge with an instruction not associated with a block.
+  DCHECK(other->GetBlock() != nullptr);
+  // A constructor fence's return type is "kPrimVoid"
+  // and therefore it cannot have any environment uses.
+  DCHECK(!other->HasEnvironmentUses());
+
+  auto has_input = [](HInstruction* haystack, HInstruction* needle) {
+    // Check if `haystack` has `needle` as any of its inputs.
+    for (size_t input_count = 0; input_count < haystack->InputCount(); ++input_count) {
+      if (haystack->InputAt(input_count) == needle) {
+        return true;
+      }
+    }
+    return false;
+  };
+
+  // Add any inputs from `other` into `this` if it wasn't already an input.
+  for (size_t input_count = 0; input_count < other->InputCount(); ++input_count) {
+    HInstruction* other_input = other->InputAt(input_count);
+    if (!has_input(this, other_input)) {
+      AddInput(other_input);
+    }
+  }
+
+  other->GetBlock()->RemoveInstruction(other);
+}
+
+HInstruction* HConstructorFence::GetAssociatedAllocation(bool ignore_inputs) {
   HInstruction* new_instance_inst = GetPrevious();
   // Check if the immediately preceding instruction is a new-instance/new-array.
   // Otherwise this fence is for protecting final fields.
   if (new_instance_inst != nullptr &&
       (new_instance_inst->IsNewInstance() || new_instance_inst->IsNewArray())) {
-    // TODO: Need to update this code to handle multiple inputs.
-    DCHECK_EQ(InputCount(), 1u);
-    return new_instance_inst;
-  } else {
-    return nullptr;
+    if (ignore_inputs) {
+      // If inputs are ignored, simply check if the predecessor is
+      // *any* HNewInstance/HNewArray.
+      //
+      // Inputs are normally only ignored for prepare_for_register_allocation,
+      // at which point *any* prior HNewInstance/Array can be considered
+      // associated.
+      return new_instance_inst;
+    } else {
+      // Normal case: There must be exactly 1 input and the previous instruction
+      // must be that input.
+      if (InputCount() == 1u && InputAt(0) == new_instance_inst) {
+        return new_instance_inst;
+      }
+    }
   }
+  return nullptr;
 }
 
 #define DEFINE_ACCEPT(name, super)                                             \
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 29be8ac..3e4928b 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -6634,13 +6634,24 @@
   // Returns how many HConstructorFence instructions were removed from graph.
   static size_t RemoveConstructorFences(HInstruction* instruction);
 
+  // Combine all inputs of `this` and `other` instruction and remove
+  // `other` from the graph.
+  //
+  // Inputs are unique after the merge.
+  //
+  // Requirement: `this` must not be the same as `other.
+  void Merge(HConstructorFence* other);
+
   // Check if this constructor fence is protecting
   // an HNewInstance or HNewArray that is also the immediate
   // predecessor of `this`.
   //
+  // If `ignore_inputs` is true, then the immediate predecessor doesn't need
+  // to be one of the inputs of `this`.
+  //
   // Returns the associated HNewArray or HNewInstance,
   // or null otherwise.
-  HInstruction* GetAssociatedAllocation();
+  HInstruction* GetAssociatedAllocation(bool ignore_inputs = false);
 
   DECLARE_INSTRUCTION(ConstructorFence);
 
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 435ca1c..b45f3c6 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -55,6 +55,7 @@
 #include "compiled_method.h"
 #include "compiler.h"
 #include "constant_folding.h"
+#include "constructor_fence_redundancy_elimination.h"
 #include "dead_code_elimination.h"
 #include "debug/elf_debug_writer.h"
 #include "debug/method_debug_info.h"
@@ -516,6 +517,8 @@
     return new (arena) CHAGuardOptimization(graph);
   } else if (opt_name == CodeSinking::kCodeSinkingPassName) {
     return new (arena) CodeSinking(graph, stats);
+  } else if (opt_name == ConstructorFenceRedundancyElimination::kPassName) {
+    return new (arena) ConstructorFenceRedundancyElimination(graph, stats);
 #ifdef ART_ENABLE_CODEGEN_arm
   } else if (opt_name == arm::InstructionSimplifierArm::kInstructionSimplifierArmPassName) {
     return new (arena) arm::InstructionSimplifierArm(graph, stats);
@@ -786,6 +789,8 @@
   IntrinsicsRecognizer* intrinsics = new (arena) IntrinsicsRecognizer(graph, stats);
   CHAGuardOptimization* cha_guard = new (arena) CHAGuardOptimization(graph);
   CodeSinking* code_sinking = new (arena) CodeSinking(graph, stats);
+  ConstructorFenceRedundancyElimination* cfre =
+      new (arena) ConstructorFenceRedundancyElimination(graph, stats);
 
   HOptimization* optimizations1[] = {
     intrinsics,
@@ -823,6 +828,8 @@
     // can satisfy. For example, the code generator does not expect to see a
     // HTypeConversion from a type to the same type.
     simplify4,
+    cfre,  // Eliminate constructor fences after code sinking to avoid
+           // complicated sinking logic to split a fence with many inputs.
   };
   RunOptimizations(optimizations2, arraysize(optimizations2), pass_observer);
 
diff --git a/compiler/optimizing/optimizing_compiler_stats.h b/compiler/optimizing/optimizing_compiler_stats.h
index d6da73c..af7ab2f 100644
--- a/compiler/optimizing/optimizing_compiler_stats.h
+++ b/compiler/optimizing/optimizing_compiler_stats.h
@@ -91,6 +91,7 @@
   kConstructorFenceGeneratedFinal,
   kConstructorFenceRemovedLSE,
   kConstructorFenceRemovedPFRA,
+  kConstructorFenceRemovedCFRE,
   kLastStat
 };
 
@@ -211,6 +212,7 @@
       case kConstructorFenceGeneratedFinal: name = "ConstructorFenceGeneratedFinal"; break;
       case kConstructorFenceRemovedLSE: name = "ConstructorFenceRemovedLSE"; break;
       case kConstructorFenceRemovedPFRA: name = "ConstructorFenceRemovedPFRA"; break;
+      case kConstructorFenceRemovedCFRE: name = "ConstructorFenceRemovedCFRE"; break;
 
       case kLastStat:
         LOG(FATAL) << "invalid stat "
diff --git a/runtime/base/arena_allocator.cc b/runtime/base/arena_allocator.cc
index 148ef86..8738adf 100644
--- a/runtime/base/arena_allocator.cc
+++ b/runtime/base/arena_allocator.cc
@@ -73,6 +73,7 @@
   "BCE          ",
   "DCE          ",
   "LSE          ",
+  "CFRE         ",
   "LICM         ",
   "LoopOpt      ",
   "SsaLiveness  ",
diff --git a/runtime/base/arena_allocator.h b/runtime/base/arena_allocator.h
index 0b1a3ba..212edfb 100644
--- a/runtime/base/arena_allocator.h
+++ b/runtime/base/arena_allocator.h
@@ -80,6 +80,7 @@
   kArenaAllocBoundsCheckElimination,
   kArenaAllocDCE,
   kArenaAllocLSE,
+  kArenaAllocCFRE,
   kArenaAllocLICM,
   kArenaAllocLoopOptimization,
   kArenaAllocSsaLiveness,
diff --git a/test/476-checker-ctor-fence-redun-elim/expected.txt b/test/476-checker-ctor-fence-redun-elim/expected.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/476-checker-ctor-fence-redun-elim/expected.txt
diff --git a/test/476-checker-ctor-fence-redun-elim/info.txt b/test/476-checker-ctor-fence-redun-elim/info.txt
new file mode 100644
index 0000000..46d62f7
--- /dev/null
+++ b/test/476-checker-ctor-fence-redun-elim/info.txt
@@ -0,0 +1,2 @@
+Tests to ensure constructor fences (after new-instance, new-array, or final fields) are properly
+merged together by the compiler when they are redundant.
diff --git a/test/476-checker-ctor-fence-redun-elim/src/Main.java b/test/476-checker-ctor-fence-redun-elim/src/Main.java
new file mode 100644
index 0000000..05f2f7c
--- /dev/null
+++ b/test/476-checker-ctor-fence-redun-elim/src/Main.java
@@ -0,0 +1,844 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+// Baseline class. This has no final fields, so there are no additional freezes
+// in its constructor.
+//
+// The new-instance itself always has 1 freeze for the happens-before on the object header
+// write (i.e. [obj.class = X] happens-before any access to obj).
+//
+// Total freezes for "new Base()": 1.
+class Base {
+  int w0;
+  int w1;
+  int w2;
+  int w3;
+
+  @Override
+  public String toString() {
+    return getClass().getName() + "(" + baseString() + ")";
+  }
+
+  protected String baseString() {
+    return String.format("w0: %d, w1: %d, w2: %d, w3: %d", w0, w1, w2, w3);
+  }
+}
+
+// This has a final field in its constructor, so there must be a field freeze
+// at the end of <init>.
+//
+// Total freezes for "new OneFinal()": 2.
+class OneFinal extends Base {
+  final int x;
+  OneFinal(int x) {
+    this.x = x;
+  }
+
+  @Override
+  protected String baseString() {
+    return String.format("%s, x: %d", super.baseString(), x);
+  }
+}
+
+class Assert {
+  public static void stringEquals(String expected, Object actual) {
+    stringEquals$noinline$(expected, actual);
+  }
+
+  // Forbid compiler from inlining this to avoid overly clever optimizations.
+  private static void stringEquals$noinline$(String expected, Object actual) {
+    String actualStr = Main.valueToString(actual);
+    if (!expected.equals(actualStr)) {
+      throw new AssertionError("Expected: " + expected + ", actual: " + actualStr);
+    }
+  }
+}
+
+interface Test {
+  public void exercise();
+  public void check();
+}
+
+class TestOneFinal implements Test {
+  // Initialize at least once before actual test.
+  public static Object external;
+
+  /// CHECK-START: void TestOneFinal.exercise() constructor_fence_redundancy_elimination (before)
+  /// CHECK: <<NewInstance:l\d+>>     NewInstance
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
+  /// CHECK-NOT:                      ConstructorFence
+  /// CHECK-DAG:                      StaticFieldSet [<<External:l\d+>>,<<NewInstance>>]
+
+  /// CHECK-START: void TestOneFinal.exercise() constructor_fence_redundancy_elimination (after)
+  /// CHECK: <<NewInstance:l\d+>>     NewInstance
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
+  /// CHECK-NOT:                      ConstructorFence
+  /// CHECK-DAG:                      StaticFieldSet [<<External:l\d+>>,<<NewInstance>>]
+  @Override
+  public void exercise() {
+      Base b = new OneFinal(1);
+      // 1 store, 2 freezes.
+
+      // Stores to 'b' do not escape b.
+      b.w0 = 1;
+      b.w1 = 2;
+      b.w2 = 3;
+
+      // Publish the result to a global so that it is not LSE-eliminated.
+      external = b;
+  }
+
+  @Override
+  public void check() {
+    Assert.stringEquals("OneFinal(w0: 1, w1: 2, w2: 3, w3: 0, x: 1)", external);
+  }
+}
+
+// This has a final field in its constructor, so there must be a field freeze
+// at the end of <init>. The previous base class's freezes accumulate on top
+// of this one.
+//
+// Total freezes for "new TwoFinal()": 3.
+class TwoFinal extends OneFinal {
+  final int y;
+  TwoFinal(int x, int y) {
+    super(x);
+    this.y = y;
+  }
+
+  @Override
+  protected String baseString() {
+    return String.format("%s, y: %d", super.baseString(), y);
+  }
+}
+
+// This has a final field in its constructor, so there must be a field freeze
+// at the end of <init>. The previous base class's freezes accumulate on top
+// of this one.
+//
+// Total freezes for "new ThreeFinal()": 4.
+class ThreeFinal extends TwoFinal {
+  final int z;
+  ThreeFinal(int x, int y, int z) {
+    super(x, y);
+    this.z = z;
+  }
+
+  @Override
+  protected String baseString() {
+    return String.format("%s, z: %d", super.baseString(), z);
+  }
+}
+
+class TestThreeFinal implements Test {
+  // Initialize at least once before actual test.
+  public static Object external;
+
+  /// CHECK-START: void TestThreeFinal.exercise() constructor_fence_redundancy_elimination (before)
+  /// CHECK: <<NewInstance:l\d+>>     NewInstance
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
+  /// CHECK-NOT:                      ConstructorFence
+  /// CHECK-DAG:                      StaticFieldSet [<<External:l\d+>>,<<NewInstance>>]
+
+  /// CHECK-START: void TestThreeFinal.exercise() constructor_fence_redundancy_elimination (after)
+  /// CHECK: <<NewInstance:l\d+>>     NewInstance
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
+  /// CHECK-NOT:                      ConstructorFence
+  /// CHECK-DAG:                      StaticFieldSet [<<External:l\d+>>,<<NewInstance>>]
+  @Override
+  public void exercise() {
+    Base b = new ThreeFinal(1, 1, 2);
+    // 3 store, 4 freezes.
+
+    // Stores to 'b' do not escape b.
+    b.w0 = 3;
+
+    // Publish the result to a global so that it is not LSE-eliminated.
+    external = b;
+  }
+
+  @Override
+  public void check() {
+    Assert.stringEquals("ThreeFinal(w0: 3, w1: 0, w2: 0, w3: 0, x: 1, y: 1, z: 2)", external);
+  }
+}
+
+// Ensure "freezes" between multiple new-instances are optimized out.
+class TestMultiAlloc implements Test {
+  public static Object external;
+  public static Object external2;
+
+  /// CHECK-START: void TestMultiAlloc.exercise() constructor_fence_redundancy_elimination (before)
+  /// CHECK: <<NewInstance:l\d+>>     NewInstance
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
+  /// CHECK: <<NewInstance2:l\d+>>    NewInstance
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
+  /// CHECK-NOT:                      ConstructorFence
+  /// CHECK-DAG:                      StaticFieldSet [<<External:l\d+>>,<<NewInstance>>]
+  /// CHECK-DAG:                      StaticFieldSet [<<External2:l\d+>>,<<NewInstance2>>]
+
+  /// CHECK-START: void TestMultiAlloc.exercise() constructor_fence_redundancy_elimination (after)
+  /// CHECK: <<NewInstance:l\d+>>     NewInstance
+  /// CHECK: <<NewInstance2:l\d+>>    NewInstance
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>,<<NewInstance>>]
+  /// CHECK-NOT:                      ConstructorFence
+  /// CHECK-DAG:                      StaticFieldSet [<<External:l\d+>>,<<NewInstance>>]
+  /// CHECK-DAG:                      StaticFieldSet [<<External2:l\d+>>,<<NewInstance2>>]
+  @Override
+  public void exercise() {
+    // 1 freeze
+    Base b = new Base();
+    // 1 freeze
+    Base b2 = new Base();
+
+    // Merge 2 freezes above into 1 constructor fence.
+    external = b;
+    external2 = b2;
+  }
+
+  @Override
+  public void check() {
+    Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external);
+    Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external2);
+  }
+}
+
+// Ensure "freezes" between multiple new-instances are optimized out.
+class TestThreeFinalTwice implements Test {
+  // Initialize at least once before actual test.
+  public static Object external;
+  public static Object external2;
+
+  /// CHECK-START: void TestThreeFinalTwice.exercise() constructor_fence_redundancy_elimination (before)
+  /// CHECK: <<NewInstance:l\d+>>     NewInstance
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
+  /// CHECK: <<NewInstance2:l\d+>>    NewInstance
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
+  /// CHECK-NOT:                      ConstructorFence
+  /// CHECK-DAG:                      StaticFieldSet [<<External:l\d+>>,<<NewInstance>>]
+  /// CHECK-DAG:                      StaticFieldSet [<<External2:l\d+>>,<<NewInstance2>>]
+
+  /// CHECK-START: void TestThreeFinalTwice.exercise() constructor_fence_redundancy_elimination (after)
+  /// CHECK: <<NewInstance:l\d+>>     NewInstance
+  /// CHECK: <<NewInstance2:l\d+>>    NewInstance
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>,<<NewInstance>>]
+  /// CHECK-NOT:                      ConstructorFence
+  /// CHECK-DAG:                      StaticFieldSet [<<External:l\d+>>,<<NewInstance>>]
+  /// CHECK-DAG:                      StaticFieldSet [<<External2:l\d+>>,<<NewInstance2>>]
+  @Override
+  public void exercise() {
+    Base b = new ThreeFinal(1, 1, 2);
+    // 3 store, 4 freezes.
+
+    // Stores to 'b' do not escape b.
+    b.w0 = 3;
+
+    Base b2 = new ThreeFinal(4, 5, 6);
+    // 3 store, 4 freezes.
+
+    // Stores to 'b2' do not escape b2.
+    b2.w0 = 7;
+
+    // Publish the result to a global so that it is not LSE-eliminated.
+    // Publishing is done at the end to give freezes above a chance to merge.
+    external = b;
+    external2 = b2;
+  }
+
+  @Override
+  public void check() {
+    Assert.stringEquals("ThreeFinal(w0: 3, w1: 0, w2: 0, w3: 0, x: 1, y: 1, z: 2)", external);
+    Assert.stringEquals("ThreeFinal(w0: 7, w1: 0, w2: 0, w3: 0, x: 4, y: 5, z: 6)", external2);
+  }
+}
+
+class TestNonEscaping {
+  // Prevent constant folding.
+  static boolean test;
+
+  static Object external;
+  static Object external2;
+  static Object external3;
+  static Object external4;
+
+  static class Invoke implements Test {
+    /// CHECK-START: void TestNonEscaping$Invoke.exercise() constructor_fence_redundancy_elimination (before)
+    /// CHECK: <<NewInstance:l\d+>>     NewInstance
+    /// CHECK:                          ConstructorFence [<<NewInstance>>]
+    /// CHECK:                          InvokeStaticOrDirect
+    /// CHECK: <<NewInstance2:l\d+>>    NewInstance
+    /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
+    /// CHECK-NOT:                      ConstructorFence
+
+    /// CHECK-START: void TestNonEscaping$Invoke.exercise() constructor_fence_redundancy_elimination (after)
+    /// CHECK: <<NewInstance:l\d+>>     NewInstance
+    /// CHECK:                          InvokeStaticOrDirect
+    /// CHECK: <<NewInstance2:l\d+>>    NewInstance
+    /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>,<<NewInstance>>]
+    /// CHECK-NOT:                      ConstructorFence
+    @Override
+    public void exercise() {
+      Base b = new Base();
+
+      // b cannot possibly escape into this invoke because it hasn't escaped onto the heap earlier,
+      // and the invoke doesn't take it as a parameter.
+      noEscape$noinline$();
+
+      // Remove the Constructor Fence for b, merging into the fence for b2.
+      Base b2 = new Base();
+
+      // Do not LSE-eliminate b,b2
+      external = b;
+      external2 = b2;
+    }
+
+    @Override
+    public void check() {
+      Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external);
+      Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external2);
+    }
+  }
+
+  public static int[] array = new int[1];
+  static Base base = new Base();
+
+  static class Store implements Test {
+    /// CHECK-START: void TestNonEscaping$Store.exercise() constructor_fence_redundancy_elimination (before)
+    /// CHECK: <<NewInstance:l\d+>>     NewInstance
+    /// CHECK:                          ConstructorFence [<<NewInstance>>]
+    /// CHECK-DAG:                      ArraySet
+    /// CHECK-DAG:                      StaticFieldSet
+    /// CHECK-DAG:                      InstanceFieldSet
+    /// CHECK: <<NewInstance2:l\d+>>    NewInstance
+    /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
+    /// CHECK-NOT:                      ConstructorFence
+
+    /// CHECK-START: void TestNonEscaping$Store.exercise() constructor_fence_redundancy_elimination (after)
+    /// CHECK-DAG: <<NewInstance:l\d+>>   NewInstance
+    /// CHECK-DAG: <<NewInstance2:l\d+>>  NewInstance
+    /// CHECK-DAG:                        ConstructorFence [<<NewInstance2>>,<<NewInstance>>]
+    /// CHECK-NOT:                        ConstructorFence
+    @Override
+    public void exercise() {
+      Base b = new Base();
+
+      // Stores of inputs other than the fence target do not publish 'b'.
+      array[0] = b.w0;  // aput
+      external = array; // sput
+      base.w0 = b.w0;   // iput
+
+      // Remove the Constructor Fence for b, merging into the fence for b2.
+      Base b2 = new Base();
+
+      // Do not LSE-eliminate b,b2
+      external3 = b;
+      external4 = b2;
+    }
+
+    @Override
+    public void check() {
+      Assert.stringEquals("[0]", array);
+      Assert.stringEquals("[0]", external);
+      Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", base);
+      Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external3);
+      Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external4);
+    }
+  }
+
+  private static void noEscape$noinline$() {
+  }
+}
+
+class TestDontOptimizeAcrossBlocks implements Test {
+  // Prevent constant folding.
+  static boolean test;
+
+  static Object external;
+  static Object external3;
+
+  /// CHECK-START: void TestDontOptimizeAcrossBlocks.exercise() constructor_fence_redundancy_elimination (before)
+  /// CHECK: <<NewInstance:l\d+>>     NewInstance
+  /// CHECK:                          ConstructorFence [<<NewInstance>>]
+  /// CHECK: <<NewInstance2:l\d+>>    NewInstance
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
+  /// CHECK-NOT:                      ConstructorFence
+  /// CHECK-DAG:                      StaticFieldSet [<<External:l\d+>>,<<NewInstance>>]
+  /// CHECK-DAG:                      StaticFieldSet [<<External2:l\d+>>,<<NewInstance2>>]
+
+  /// CHECK-START: void TestDontOptimizeAcrossBlocks.exercise() constructor_fence_redundancy_elimination (after)
+  /// CHECK: <<NewInstance:l\d+>>     NewInstance
+  /// CHECK:                          ConstructorFence [<<NewInstance>>]
+  /// CHECK: <<NewInstance2:l\d+>>    NewInstance
+  /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
+  /// CHECK-NOT:                      ConstructorFence
+  /// CHECK-DAG:                      StaticFieldSet [<<External:l\d+>>,<<NewInstance>>]
+  /// CHECK-DAG:                      StaticFieldSet [<<External2:l\d+>>,<<NewInstance2>>]
+  @Override
+  public void exercise() {
+    Base b = new Base();
+
+    // Do not move constructor fence across this block, even though 'b' is not published yet.
+    if (test) {
+      external = null;
+    }
+
+    Base b2 = new Base();
+    external = b2;
+    external3 = b;
+  }
+
+  @Override
+  public void check() {
+    Assert.stringEquals("false", test);
+    Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external);
+    Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external3);
+  }
+}
+
+class TestDontOptimizeAcrossEscape {
+  // Prevent constant folding.
+  static boolean test;
+
+  static Object external;
+  static Object external2;
+  static Object external3;
+  static Object external4;
+
+  static class Invoke implements Test {
+    /// CHECK-START: void TestDontOptimizeAcrossEscape$Invoke.exercise() constructor_fence_redundancy_elimination (before)
+    /// CHECK: <<NewInstance:l\d+>>     NewInstance
+    /// CHECK:                          ConstructorFence [<<NewInstance>>]
+    /// CHECK:                          InvokeStaticOrDirect
+    /// CHECK: <<NewInstance2:l\d+>>    NewInstance
+    /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
+    /// CHECK-NOT:                      ConstructorFence
+
+    /// CHECK-START: void TestDontOptimizeAcrossEscape$Invoke.exercise() constructor_fence_redundancy_elimination (after)
+    /// CHECK: <<NewInstance:l\d+>>     NewInstance
+    /// CHECK:                          ConstructorFence [<<NewInstance>>]
+    /// CHECK:                          InvokeStaticOrDirect
+    /// CHECK: <<NewInstance2:l\d+>>    NewInstance
+    /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
+    /// CHECK-NOT:                      ConstructorFence
+    @Override
+    public void exercise() {
+      Base b = new Base();
+      // Do not optimize across invokes into which the fence target escapes.
+      invoke$noinline$(b);
+
+      Base b2 = new Base();
+
+      // Do not LSE-eliminate b,b2
+      external = b;
+      external2 = b2;
+    }
+
+    private static void invoke$noinline$(Object b) {
+      // Even though 'b' does not escape this method, we conservatively assume all parameters
+      // of an invoke escape.
+    }
+
+    @Override
+    public void check() {
+      Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external);
+      Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external2);
+    }
+  }
+
+  public static Object[] array = new Object[3];
+  static Base base = new Base();
+
+  static class InstanceEscaper {
+    public Object holder;
+
+    @Override
+    public String toString() {
+      return getClass().getName() + "(" + baseString() + ")";
+    }
+
+    protected String baseString() {
+      return String.format("holder: %s", Main.valueToString(holder));
+    }
+  }
+
+  static InstanceEscaper instanceEscaper = new InstanceEscaper();
+
+  static class StoreIput implements Test {
+    /// CHECK-START: void TestDontOptimizeAcrossEscape$StoreIput.exercise() constructor_fence_redundancy_elimination (before)
+    /// CHECK: <<NewInstance:l\d+>>     NewInstance
+    /// CHECK:                          ConstructorFence [<<NewInstance>>]
+    /// CHECK-DAG:                      InstanceFieldSet
+    /// CHECK: <<NewInstance2:l\d+>>    NewInstance
+    /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
+    /// CHECK-NOT:                      ConstructorFence
+
+    /// CHECK-START: void TestDontOptimizeAcrossEscape$StoreIput.exercise() constructor_fence_redundancy_elimination (after)
+    /// CHECK-DAG: <<NewInstance:l\d+>>   NewInstance
+    /// CHECK:                            ConstructorFence [<<NewInstance>>]
+    /// CHECK-DAG: <<NewInstance2:l\d+>>  NewInstance
+    /// CHECK-DAG:                        ConstructorFence [<<NewInstance2>>]
+    /// CHECK-NOT:                        ConstructorFence
+    @Override
+    public void exercise() {
+      Base b = new Base();
+
+      // A store of 'b' into another instance will publish 'b'.
+      instanceEscaper.holder = b;
+
+      // Do not remove any constructor fences above.
+      Base b2 = new Base();
+
+      // Do not LSE-eliminate b,b2
+      external3 = b;
+      external4 = b2;
+    }
+
+    @Override
+    public void check() {
+      Assert.stringEquals(
+          "TestDontOptimizeAcrossEscape$InstanceEscaper(holder: Base(w0: 0, w1: 0, w2: 0, w3: 0))",
+          instanceEscaper);
+      Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external3);
+      Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external4);
+    }
+  }
+
+  static class StoreAput implements Test {
+    /// CHECK-START: void TestDontOptimizeAcrossEscape$StoreAput.exercise() constructor_fence_redundancy_elimination (before)
+    /// CHECK: <<NewInstance:l\d+>>     NewInstance
+    /// CHECK:                          ConstructorFence [<<NewInstance>>]
+    /// CHECK-DAG:                      ArraySet
+    /// CHECK: <<NewInstance2:l\d+>>    NewInstance
+    /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
+    /// CHECK-NOT:                      ConstructorFence
+
+    /// CHECK-START: void TestDontOptimizeAcrossEscape$StoreAput.exercise() constructor_fence_redundancy_elimination (after)
+    /// CHECK-DAG: <<NewInstance:l\d+>>   NewInstance
+    /// CHECK:                            ConstructorFence [<<NewInstance>>]
+    /// CHECK-DAG: <<NewInstance2:l\d+>>  NewInstance
+    /// CHECK-DAG:                        ConstructorFence [<<NewInstance2>>]
+    /// CHECK-NOT:                        ConstructorFence
+    @Override
+    public void exercise() {
+      Base b = new Base();
+
+      // A store of 'b' into another array will publish 'b'.
+      array[0] = b;  // aput
+
+      // Do not remove any constructor fences above.
+      Base b2 = new Base();
+
+      // Do not LSE-eliminate b,b2
+      external3 = b;
+      external4 = b2;
+    }
+
+    @Override
+    public void check() {
+      Assert.stringEquals("[Base(w0: 0, w1: 0, w2: 0, w3: 0),<null>,<null>]", array);
+      Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external3);
+      Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external4);
+    }
+  }
+
+  static class StoreSput implements Test {
+    /// CHECK-START: void TestDontOptimizeAcrossEscape$StoreSput.exercise() constructor_fence_redundancy_elimination (before)
+    /// CHECK: <<NewInstance:l\d+>>     NewInstance
+    /// CHECK:                          ConstructorFence [<<NewInstance>>]
+    /// CHECK-DAG:                      StaticFieldSet
+    /// CHECK: <<NewInstance2:l\d+>>    NewInstance
+    /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
+    /// CHECK-NOT:                      ConstructorFence
+
+    /// CHECK-START: void TestDontOptimizeAcrossEscape$StoreSput.exercise() constructor_fence_redundancy_elimination (after)
+    /// CHECK-DAG: <<NewInstance:l\d+>>   NewInstance
+    /// CHECK:                            ConstructorFence [<<NewInstance>>]
+    /// CHECK-DAG: <<NewInstance2:l\d+>>  NewInstance
+    /// CHECK-DAG:                        ConstructorFence [<<NewInstance2>>]
+    /// CHECK-NOT:                        ConstructorFence
+    @Override
+    public void exercise() {
+      Base b = new Base();
+
+      // A store of 'b' into a static will publish 'b'.
+      external = b;
+
+      // Do not remove any constructor fences above.
+      Base b2 = new Base();
+
+      // Do not LSE-eliminate b,b2
+      external3 = b;
+      external4 = b2;
+    }
+
+    @Override
+    public void check() {
+      Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external);
+      Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external3);
+      Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external4);
+    }
+  }
+
+  static class Deopt implements Test {
+    /// CHECK-START: void TestDontOptimizeAcrossEscape$Deopt.exercise() constructor_fence_redundancy_elimination (before)
+    /// CHECK: <<NewInstance:l\d+>>     NewInstance
+    /// CHECK:                          ConstructorFence [<<NewInstance>>]
+    /// CHECK-DAG:                      Deoptimize
+    /// CHECK: <<NewInstance2:l\d+>>    NewInstance
+    /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
+    /// CHECK-NOT:                      ConstructorFence
+
+    /// CHECK-START: void TestDontOptimizeAcrossEscape$Deopt.exercise() constructor_fence_redundancy_elimination (after)
+    /// CHECK-DAG: <<NewInstance:l\d+>>   NewInstance
+    /// CHECK:                            ConstructorFence [<<NewInstance>>]
+    /// CHECK-DAG: <<NewInstance2:l\d+>>  NewInstance
+    /// CHECK-DAG:                        ConstructorFence [<<NewInstance2>>]
+    /// CHECK-NOT:                        ConstructorFence
+    @Override
+    public void exercise() {
+      Base b = new Base();
+
+      // An array access generates a Deopt to avoid doing bounds check.
+      array[0] = external;  // aput
+      array[1] = external;  // aput
+      array[2] = external;  // aput
+
+      // Do not remove any constructor fences above.
+      Base b2 = new Base();
+
+      // Do not LSE-eliminate b,b2
+      external3 = b;
+      external4 = b2;
+    }
+
+    @Override
+    public void check() {
+      Assert.stringEquals("[Base(w0: 0, w1: 0, w2: 0, w3: 0),"
+              + "Base(w0: 0, w1: 0, w2: 0, w3: 0),"
+              + "Base(w0: 0, w1: 0, w2: 0, w3: 0)]",
+          array);
+      Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external3);
+      Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external4);
+    }
+  }
+
+  static class Select implements Test {
+    /// CHECK-START: void TestDontOptimizeAcrossEscape$Select.exercise() constructor_fence_redundancy_elimination (before)
+    /// CHECK: <<NewInstance:l\d+>>     NewInstance
+    /// CHECK:                          ConstructorFence [<<NewInstance>>]
+    /// CHECK-DAG:                      Select
+    /// CHECK: <<NewInstance2:l\d+>>    NewInstance
+    /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
+    /// CHECK-NOT:                      ConstructorFence
+
+    /// CHECK-START: void TestDontOptimizeAcrossEscape$Select.exercise() constructor_fence_redundancy_elimination (after)
+    /// CHECK-DAG: <<NewInstance:l\d+>>   NewInstance
+    /// CHECK:                            ConstructorFence [<<NewInstance>>]
+    /// CHECK-DAG: <<NewInstance2:l\d+>>  NewInstance
+    /// CHECK-DAG:                        ConstructorFence [<<NewInstance2>>]
+    /// CHECK-NOT:                        ConstructorFence
+    @Override
+    public void exercise() {
+      Base b = new Base();
+
+      boolean localTest = test;
+      Object localExternal = external3;
+
+      // Selecting 'b' creates an alias, which we conservatively assume escapes immediately.
+      external = localTest ? b : localExternal;
+
+      // Do not remove any constructor fences above.
+      Base b2 = new Base();
+
+      // Do not LSE-eliminate b,b2
+      external3 = b;
+      external4 = b2;
+    }
+
+    @Override
+    public void check() {
+      Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external);
+      Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external3);
+      Assert.stringEquals("Base(w0: 0, w1: 0, w2: 0, w3: 0)", external4);
+    }
+  }
+
+  static class MakeBoundTypeTest implements Test {
+    public static Object makeBoundType;
+    public static Object makeBoundTypeSub;
+
+    @Override
+    public void exercise() {
+      // Note: MakeBoundType is special and we have to call the constructor directly
+      // to prevent inlining it.
+      try {
+        makeBoundType = exerciseNewInstance(MakeBoundType.class, 123);
+        makeBoundTypeSub = exerciseNewInstance(MakeBoundTypeSub.class, 123);
+      } catch (Exception e) {
+        throw new RuntimeException(e);
+      }
+    }
+
+    @Override
+    public void check() {
+      Assert.stringEquals(
+          "TestDontOptimizeAcrossEscape$MakeBoundTypeTest$MakeBoundType(abcdefgh: 123, x: 2)",
+          makeBoundType);
+      Assert.stringEquals(
+          "TestDontOptimizeAcrossEscape$MakeBoundTypeTest$MakeBoundTypeSub(abcdefgh: 123, x: 1)",
+          makeBoundTypeSub);
+    }
+
+    // Make a new instance of 'klass'.
+    private static <T> T exerciseNewInstance(Class<T> klass, int params) throws Exception {
+      return klass.cast(klass.getDeclaredConstructor(int.class).newInstance(params));
+    }
+
+    /// CHECK-START: void TestDontOptimizeAcrossEscape$MakeBoundTypeTest$MakeBoundType.<init>(int) constructor_fence_redundancy_elimination (before)
+    /// CHECK-DAG: <<This:l\d+>>         ParameterValue
+    /// CHECK-DAG: <<NewInstance:l\d+>>  NewInstance
+    /// CHECK:                           ConstructorFence [<<NewInstance>>]
+    /// CHECK-DAG:                       BoundType
+    /// CHECK-DAG:                       ConstructorFence [<<This>>]
+    /// CHECK-NOT:                       ConstructorFence
+
+    /// CHECK-START: void TestDontOptimizeAcrossEscape$MakeBoundTypeTest$MakeBoundType.<init>(int) constructor_fence_redundancy_elimination (after)
+    /// CHECK-DAG: <<This:l\d+>>         ParameterValue
+    /// CHECK-DAG: <<NewInstance:l\d+>>  NewInstance
+    /// CHECK:                           ConstructorFence [<<NewInstance>>]
+    /// CHECK-DAG:                       BoundType
+    /// CHECK-DAG:                       ConstructorFence [<<This>>]
+    /// CHECK-NOT:                       ConstructorFence
+    static class MakeBoundType {
+      final int abcdefgh;
+      int x;
+
+      MakeBoundType(int param) {
+        abcdefgh = param;
+
+        Base b = new Base();
+        // constructor-fence(b)
+
+        if (this instanceof MakeBoundTypeSub) {
+          // Create a "BoundType(this)" which prevents
+          // a merged constructor-fence(this, b)
+          x = 1;
+        } else {
+          x = 2;
+        }
+
+        // publish(b).
+        external = b;
+
+        // constructor-fence(this)
+      }
+
+      @Override
+      public String toString() {
+        return getClass().getName() + "(" + baseString() + ")";
+      }
+
+      protected String baseString() {
+        return String.format("abcdefgh: %d, x: %d", abcdefgh, x);
+      }
+    }
+
+    static class MakeBoundTypeSub extends MakeBoundType {
+      MakeBoundTypeSub(int xyz) {
+        super(xyz);
+      }
+    }
+  }
+}
+
+public class Main {
+  public static void main(String[] args) throws Exception {
+    // Ensure that all of this code does not get optimized out into a no-op
+    // by actually running the code with reflection, then validating
+    // the result by asserting it against a string.
+    Class<? extends Test>[] testClasses = new Class[] {
+      TestOneFinal.class,
+      TestThreeFinal.class,
+      TestMultiAlloc.class,
+      TestThreeFinalTwice.class,
+      TestNonEscaping.Invoke.class,
+      TestNonEscaping.Store.class,
+      TestDontOptimizeAcrossBlocks.class,
+      TestDontOptimizeAcrossEscape.Invoke.class,
+      TestDontOptimizeAcrossEscape.StoreIput.class,
+      TestDontOptimizeAcrossEscape.StoreAput.class,
+      TestDontOptimizeAcrossEscape.StoreSput.class,
+      TestDontOptimizeAcrossEscape.Deopt.class,
+      TestDontOptimizeAcrossEscape.Select.class,
+      TestDontOptimizeAcrossEscape.MakeBoundTypeTest.class,
+    };
+
+    for (Class<? extends Test> klass : testClasses) {
+      exerciseTestClass(klass);
+    }
+  }
+
+  /**
+   * Invoke Test#exercise(), then Test#check().
+   * @throws AssertionError if test fails.
+   */
+  private static void exerciseTestClass(Class<? extends Test> klass) throws Exception {
+    Test instance = klass.cast(klass.getDeclaredConstructor().newInstance());
+
+    // Use reflection as a best-effort to avoid compiler optimizations (e.g. inlining).
+    instance.getClass().getDeclaredMethod("exercise").invoke(instance);
+    instance.getClass().getDeclaredMethod("check").invoke(instance);
+  }
+
+  // Print an object, with special handling for array and null.
+  public static String valueToString(Object val) {
+    if (val == null) {
+      return "<null>";
+    }
+    if (val.getClass().isArray()) {
+      String fmt = "[";
+      int length = Array.getLength(val);
+      for (int i = 0; i < length; ++i) {
+        Object arrayElement = Array.get(val, i);
+        fmt += valueToString(arrayElement);
+
+        if (i != length - 1) {
+          fmt += ",";
+        }
+      }
+      fmt += "]";
+
+      return fmt;
+    }
+
+    return val.toString();
+  }
+}
