diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/eager_load_03.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/eager_load_03.exp
new file mode 100644
index 0000000000000..bc43cd9fc3906
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/eager_load_03.exp
@@ -0,0 +1,112 @@
+============ initial bytecode ================
+
+[variant baseline]
+fun m::bar($t0: &mut u64) {
+  0: return ()
+}
+
+
+[variant baseline]
+fun m::baz($t0: u64, $t1: u64) {
+  0: return ()
+}
+
+
+[variant baseline]
+public fun m::foo($t0: u64) {
+     var $t1: u64
+     var $t2: &mut u64
+  0: $t1 := m::one()
+  1: $t2 := borrow_local($t0)
+  2: m::bar($t2)
+  3: m::baz($t0, $t1)
+  4: return ()
+}
+
+
+[variant baseline]
+fun m::one(): u64 {
+     var $t0: u64
+  0: $t0 := 1
+  1: return $t0
+}
+
+============ after LiveVarAnalysisProcessor: ================
+
+[variant baseline]
+fun m::bar($t0: &mut u64) {
+     # live vars: $t0
+  0: drop($t0)
+     # live vars:
+  1: return ()
+}
+
+
+[variant baseline]
+fun m::baz($t0: u64, $t1: u64) {
+     # live vars: $t0, $t1
+  0: return ()
+}
+
+
+[variant baseline]
+public fun m::foo($t0: u64) {
+     var $t1: u64
+     var $t2: &mut u64
+     # live vars: $t0
+  0: $t1 := m::one()
+     # live vars: $t0, $t1
+  1: $t2 := borrow_local($t0)
+     # live vars: $t0, $t1, $t2
+  2: m::bar($t2)
+     # live vars: $t0, $t1
+  3: m::baz($t0, $t1)
+     # live vars:
+  4: return ()
+}
+
+
+[variant baseline]
+fun m::one(): u64 {
+     var $t0: u64
+     # live vars:
+  0: $t0 := 1
+     # live vars: $t0
+  1: return $t0
+}
+
+
+============ disassembled file-format ==================
+// Move bytecode v7
+module c0ffee.m {
+
+
+bar(Arg0: &mut u64) /* def_idx: 0 */ {
+B0:
+	0: MoveLoc[0](Arg0: &mut u64)
+	1: Pop
+	2: Ret
+}
+baz(Arg0: u64, Arg1: u64) /* def_idx: 1 */ {
+B0:
+	0: Ret
+}
+public foo(Arg0: u64) /* def_idx: 2 */ {
+L1:	loc0: u64
+B0:
+	0: Call one(): u64
+	1: MutBorrowLoc[0](Arg0: u64)
+	2: Call bar(&mut u64)
+	3: StLoc[1](loc0: u64)
+	4: MoveLoc[0](Arg0: u64)
+	5: MoveLoc[1](loc0: u64)
+	6: Call baz(u64, u64)
+	7: Ret
+}
+one(): u64 /* def_idx: 3 */ {
+B0:
+	0: LdU64(1)
+	1: Ret
+}
+}
+============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/eager_load_03.move b/third_party/move/move-compiler-v2/tests/eager-pushes/eager_load_03.move
new file mode 100644
index 0000000000000..fd9dc1647c213
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/eager_load_03.move
@@ -0,0 +1,15 @@
+module 0xc0ffee::m {
+    fun one(): u64 {
+        1
+    }
+
+    fun bar(_x: &mut u64) {}
+
+    fun baz(_x: u64, _y: u64) {}
+
+    public fun foo(x: u64) {
+        let t = one();
+        bar(&mut x);
+        baz(x, t);
+    }
+}
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_01.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_01.exp
new file mode 100644
index 0000000000000..68d16c3fc8412
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_01.exp
@@ -0,0 +1,148 @@
+============ initial bytecode ================
+
+[variant baseline]
+fun m::foo() {
+  0: return ()
+}
+
+
+[variant baseline]
+fun m::one(): u64 {
+     var $t0: u64
+  0: $t0 := 1
+  1: return $t0
+}
+
+
+[variant baseline]
+public fun m::test($t0: u64) {
+     var $t1: u64
+     var $t2: bool
+     var $t3: u64
+     var $t4: u64
+     var $t5: u64
+  0: $t1 := m::two()
+  1: $t4 := infer($t0)
+  2: $t5 := m::one()
+  3: $t3 := -($t4, $t5)
+  4: $t2 := >($t3, $t1)
+  5: if ($t2) goto 6 else goto 9
+  6: label L0
+  7: m::foo()
+  8: goto 10
+  9: label L1
+ 10: label L2
+ 11: return ()
+}
+
+
+[variant baseline]
+fun m::two(): u64 {
+     var $t0: u64
+  0: $t0 := 2
+  1: return $t0
+}
+
+============ after LiveVarAnalysisProcessor: ================
+
+[variant baseline]
+fun m::foo() {
+     # live vars:
+  0: return ()
+}
+
+
+[variant baseline]
+fun m::one(): u64 {
+     var $t0: u64
+     # live vars:
+  0: $t0 := 1
+     # live vars: $t0
+  1: return $t0
+}
+
+
+[variant baseline]
+public fun m::test($t0: u64) {
+     var $t1: u64
+     var $t2: bool
+     var $t3: u64 [unused]
+     var $t4: u64 [unused]
+     var $t5: u64
+     # live vars: $t0
+  0: $t1 := m::two()
+     # live vars: $t0, $t1
+  1: $t5 := m::one()
+     # live vars: $t0, $t1, $t5
+  2: $t0 := -($t0, $t5)
+     # live vars: $t0, $t1
+  3: $t2 := >($t0, $t1)
+     # live vars: $t2
+  4: if ($t2) goto 7 else goto 5
+     # live vars:
+  5: label L3
+     # live vars:
+  6: goto 9
+     # live vars:
+  7: label L0
+     # live vars:
+  8: m::foo()
+     # live vars:
+  9: label L2
+     # live vars:
+ 10: return ()
+}
+
+
+[variant baseline]
+fun m::two(): u64 {
+     var $t0: u64
+     # live vars:
+  0: $t0 := 2
+     # live vars: $t0
+  1: return $t0
+}
+
+
+============ disassembled file-format ==================
+// Move bytecode v7
+module c0ffee.m {
+
+
+foo() /* def_idx: 0 */ {
+B0:
+	0: Ret
+}
+one(): u64 /* def_idx: 1 */ {
+B0:
+	0: LdU64(1)
+	1: Ret
+}
+public test(Arg0: u64) /* def_idx: 2 */ {
+L1:	loc0: u64
+L2:	loc1: u64
+B0:
+	0: Call two(): u64
+	1: StLoc[1](loc0: u64)
+	2: Call one(): u64
+	3: StLoc[2](loc1: u64)
+	4: MoveLoc[0](Arg0: u64)
+	5: MoveLoc[2](loc1: u64)
+	6: Sub
+	7: MoveLoc[1](loc0: u64)
+	8: Gt
+	9: BrTrue(11)
+B1:
+	10: Branch(12)
+B2:
+	11: Call foo()
+B3:
+	12: Ret
+}
+two(): u64 /* def_idx: 3 */ {
+B0:
+	0: LdU64(2)
+	1: Ret
+}
+}
+============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_01.move b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_01.move
new file mode 100644
index 0000000000000..9359e34bc82d6
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_01.move
@@ -0,0 +1,19 @@
+module 0xc0ffee::m {
+    fun one(): u64 {
+        1
+    }
+
+    fun two(): u64 {
+        2
+    }
+
+    fun foo() {}
+
+    public fun test(p: u64) {
+        let e = two();
+        if (p - one() > e) {
+            foo();
+        }
+    }
+
+}
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_02.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_02.exp
new file mode 100644
index 0000000000000..e2b68c2225ac0
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_02.exp
@@ -0,0 +1,62 @@
+============ initial bytecode ================
+
+[variant baseline]
+public fun m::make($t0: u64, $t1: u64, $t2: u64, $t3: &0xc0ffee::m::S, $t4: u64): 0xc0ffee::m::Wrap {
+     var $t5: 0xc0ffee::m::Wrap
+     var $t6: u64
+     var $t7: &u64
+  0: $t7 := borrow_field<0xc0ffee::m::S>.x($t3)
+  1: $t6 := read_ref($t7)
+  2: $t5 := pack 0xc0ffee::m::Wrap($t0, $t1, $t2, $t6, $t4)
+  3: return $t5
+}
+
+============ after LiveVarAnalysisProcessor: ================
+
+[variant baseline]
+public fun m::make($t0: u64, $t1: u64, $t2: u64, $t3: &0xc0ffee::m::S, $t4: u64): 0xc0ffee::m::Wrap {
+     var $t5: 0xc0ffee::m::Wrap
+     var $t6: u64
+     var $t7: &u64
+     # live vars: $t0, $t1, $t2, $t3, $t4
+  0: $t7 := borrow_field<0xc0ffee::m::S>.x($t3)
+     # live vars: $t0, $t1, $t2, $t4, $t7
+  1: $t6 := read_ref($t7)
+     # live vars: $t0, $t1, $t2, $t4, $t6
+  2: $t5 := pack 0xc0ffee::m::Wrap($t0, $t1, $t2, $t6, $t4)
+     # live vars: $t5
+  3: return $t5
+}
+
+
+============ disassembled file-format ==================
+// Move bytecode v7
+module c0ffee.m {
+struct S {
+	x: u64
+}
+struct Wrap {
+	a: u64,
+	b: u64,
+	c: u64,
+	d: u64,
+	e: u64
+}
+
+public make(Arg0: u64, Arg1: u64, Arg2: u64, Arg3: &S, Arg4: u64): Wrap /* def_idx: 0 */ {
+L5:	loc0: u64
+B0:
+	0: MoveLoc[3](Arg3: &S)
+	1: ImmBorrowField[0](S.x: u64)
+	2: ReadRef
+	3: StLoc[5](loc0: u64)
+	4: MoveLoc[0](Arg0: u64)
+	5: MoveLoc[1](Arg1: u64)
+	6: MoveLoc[2](Arg2: u64)
+	7: MoveLoc[5](loc0: u64)
+	8: MoveLoc[4](Arg4: u64)
+	9: Pack[1](Wrap)
+	10: Ret
+}
+}
+============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_02.move b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_02.move
new file mode 100644
index 0000000000000..919d41586e43d
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_02.move
@@ -0,0 +1,23 @@
+module 0xc0ffee::m {
+    struct Wrap {
+        a: u64,
+        b: u64,
+        c: u64,
+        d: u64,
+        e: u64,
+    }
+
+    struct S {
+        x: u64,
+    }
+
+    public fun make(a: u64, b: u64, c: u64, d: &S, e: u64): Wrap {
+        Wrap {
+            a,
+            b,
+            c,
+            d: d.x,
+            e,
+        }
+    }
+}
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_03.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_03.exp
new file mode 100644
index 0000000000000..a203fca7796c0
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_03.exp
@@ -0,0 +1,89 @@
+============ initial bytecode ================
+
+[variant baseline]
+public fun m::make($t0: u64, $t1: u64, $t2: u64, $t3: address, $t4: u64): 0xc0ffee::m::Wrap {
+     var $t5: 0xc0ffee::m::Wrap
+     var $t6: &0xc0ffee::m::S
+     var $t7: u64
+     var $t8: &u64
+     var $t9: u64
+     var $t10: &u64
+  0: $t6 := borrow_global<0xc0ffee::m::S>($t3)
+  1: $t8 := borrow_field<0xc0ffee::m::S>.x($t6)
+  2: $t7 := read_ref($t8)
+  3: $t10 := borrow_field<0xc0ffee::m::S>.y($t6)
+  4: $t9 := read_ref($t10)
+  5: $t5 := pack 0xc0ffee::m::Wrap($t0, $t1, $t2, $t7, $t4, $t9)
+  6: return $t5
+}
+
+============ after LiveVarAnalysisProcessor: ================
+
+[variant baseline]
+public fun m::make($t0: u64, $t1: u64, $t2: u64, $t3: address, $t4: u64): 0xc0ffee::m::Wrap {
+     var $t5: 0xc0ffee::m::Wrap
+     var $t6: &0xc0ffee::m::S
+     var $t7: u64
+     var $t8: &u64
+     var $t9: u64
+     var $t10: &u64 [unused]
+     # live vars: $t0, $t1, $t2, $t3, $t4
+  0: $t6 := borrow_global<0xc0ffee::m::S>($t3)
+     # live vars: $t0, $t1, $t2, $t4, $t6
+  1: $t8 := borrow_field<0xc0ffee::m::S>.x($t6)
+     # live vars: $t0, $t1, $t2, $t4, $t6, $t8
+  2: $t7 := read_ref($t8)
+     # live vars: $t0, $t1, $t2, $t4, $t6, $t7
+  3: $t8 := borrow_field<0xc0ffee::m::S>.y($t6)
+     # live vars: $t0, $t1, $t2, $t4, $t7, $t8
+  4: $t9 := read_ref($t8)
+     # live vars: $t0, $t1, $t2, $t4, $t7, $t9
+  5: $t5 := pack 0xc0ffee::m::Wrap($t0, $t1, $t2, $t7, $t4, $t9)
+     # live vars: $t5
+  6: return $t5
+}
+
+
+============ disassembled file-format ==================
+// Move bytecode v7
+module c0ffee.m {
+struct S has key {
+	x: u64,
+	y: u64
+}
+struct Wrap {
+	a: u64,
+	b: u64,
+	c: u64,
+	d: u64,
+	e: u64,
+	f: u64
+}
+
+public make(Arg0: u64, Arg1: u64, Arg2: u64, Arg3: address, Arg4: u64): Wrap /* def_idx: 0 */ {
+L5:	loc0: &S
+L6:	loc1: u64
+L7:	loc2: u64
+B0:
+	0: MoveLoc[3](Arg3: address)
+	1: ImmBorrowGlobal[0](S)
+	2: StLoc[5](loc0: &S)
+	3: CopyLoc[5](loc0: &S)
+	4: ImmBorrowField[0](S.x: u64)
+	5: ReadRef
+	6: MoveLoc[5](loc0: &S)
+	7: ImmBorrowField[1](S.y: u64)
+	8: ReadRef
+	9: StLoc[6](loc1: u64)
+	10: StLoc[7](loc2: u64)
+	11: MoveLoc[0](Arg0: u64)
+	12: MoveLoc[1](Arg1: u64)
+	13: MoveLoc[2](Arg2: u64)
+	14: MoveLoc[7](loc2: u64)
+	15: MoveLoc[4](Arg4: u64)
+	16: MoveLoc[6](loc1: u64)
+	17: Pack[1](Wrap)
+	18: Ret
+}
+}
+============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_03.move b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_03.move
new file mode 100644
index 0000000000000..02c6a79aaeee3
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_03.move
@@ -0,0 +1,27 @@
+module 0xc0ffee::m {
+    struct Wrap {
+        a: u64,
+        b: u64,
+        c: u64,
+        d: u64,
+        e: u64,
+        f: u64,
+    }
+
+    struct S has key {
+        x: u64,
+        y: u64,
+    }
+
+    public fun make(a: u64, b: u64, c: u64, d: address, e: u64): Wrap acquires S {
+        let ref = borrow_global<S>(d);
+        Wrap {
+            a,
+            b,
+            c,
+            d: ref.x,
+            e,
+            f: ref.y,
+        }
+    }
+}
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_04.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_04.exp
new file mode 100644
index 0000000000000..9aa46823a704c
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_04.exp
@@ -0,0 +1,149 @@
+============ initial bytecode ================
+
+[variant baseline]
+fun m::bar($t0: &signer, $t1: &mut u64, $t2: 0xc0ffee::m::Wrap) {
+  0: return ()
+}
+
+
+[variant baseline]
+public fun m::test($t0: signer, $t1: address) {
+     var $t2: &mut 0xc0ffee::m::Wrap
+     var $t3: &signer
+     var $t4: &mut u64
+     var $t5: 0xc0ffee::m::Wrap
+     var $t6: u64
+     var $t7: u64
+     var $t8: u64
+     var $t9: u64
+     var $t10: u64
+  0: $t2 := borrow_global<0xc0ffee::m::Wrap>($t1)
+  1: $t3 := borrow_local($t0)
+  2: $t4 := borrow_field<0xc0ffee::m::Wrap>.a($t2)
+  3: $t6 := 0
+  4: $t7 := 0
+  5: $t9 := 0
+  6: $t8 := m::zero($t9)
+  7: $t10 := 0
+  8: $t5 := pack 0xc0ffee::m::Wrap($t6, $t7, $t8, $t10)
+  9: m::bar($t3, $t4, $t5)
+ 10: return ()
+}
+
+
+[variant baseline]
+fun m::zero($t0: u64): u64 {
+     var $t1: u64
+  0: $t1 := 0
+  1: return $t1
+}
+
+============ after LiveVarAnalysisProcessor: ================
+
+[variant baseline]
+fun m::bar($t0: &signer, $t1: &mut u64, $t2: 0xc0ffee::m::Wrap) {
+     # live vars: $t0, $t1, $t2
+  0: drop($t0)
+     # live vars: $t1
+  1: drop($t1)
+     # live vars:
+  2: return ()
+}
+
+
+[variant baseline]
+public fun m::test($t0: signer, $t1: address) {
+     var $t2: &mut 0xc0ffee::m::Wrap
+     var $t3: &signer
+     var $t4: &mut u64
+     var $t5: 0xc0ffee::m::Wrap
+     var $t6: u64
+     var $t7: u64
+     var $t8: u64 [unused]
+     var $t9: u64
+     var $t10: u64
+     # live vars: $t0, $t1
+  0: $t2 := borrow_global<0xc0ffee::m::Wrap>($t1)
+     # live vars: $t0, $t2
+  1: $t3 := borrow_local($t0)
+     # live vars: $t2, $t3
+  2: $t4 := borrow_field<0xc0ffee::m::Wrap>.a($t2)
+     # live vars: $t3, $t4
+  3: $t6 := 0
+     # live vars: $t3, $t4, $t6
+  4: $t7 := 0
+     # live vars: $t3, $t4, $t6, $t7
+  5: $t9 := 0
+     # live vars: $t3, $t4, $t6, $t7, $t9
+  6: $t9 := m::zero($t9)
+     # live vars: $t3, $t4, $t6, $t7, $t9
+  7: $t10 := 0
+     # live vars: $t3, $t4, $t6, $t7, $t9, $t10
+  8: $t5 := pack 0xc0ffee::m::Wrap($t6, $t7, $t9, $t10)
+     # live vars: $t3, $t4, $t5
+  9: m::bar($t3, $t4, $t5)
+     # live vars:
+ 10: return ()
+}
+
+
+[variant baseline]
+fun m::zero($t0: u64): u64 {
+     var $t1: u64 [unused]
+     # live vars: $t0
+  0: $t0 := 0
+     # live vars: $t0
+  1: return $t0
+}
+
+
+============ disassembled file-format ==================
+// Move bytecode v7
+module c0ffee.m {
+struct Wrap has drop, key {
+	a: u64,
+	b: u64,
+	c: u64,
+	d: u64
+}
+
+bar(Arg0: &signer, Arg1: &mut u64, Arg2: Wrap) /* def_idx: 0 */ {
+B0:
+	0: MoveLoc[0](Arg0: &signer)
+	1: Pop
+	2: MoveLoc[1](Arg1: &mut u64)
+	3: Pop
+	4: Ret
+}
+public test(Arg0: signer, Arg1: address) /* def_idx: 1 */ {
+L2:	loc0: &signer
+L3:	loc1: &mut Wrap
+L4:	loc2: Wrap
+L5:	loc3: &mut u64
+B0:
+	0: MoveLoc[1](Arg1: address)
+	1: MutBorrowGlobal[0](Wrap)
+	2: ImmBorrowLoc[0](Arg0: signer)
+	3: StLoc[2](loc0: &signer)
+	4: MutBorrowField[0](Wrap.a: u64)
+	5: LdU64(0)
+	6: LdU64(0)
+	7: LdU64(0)
+	8: Call zero(u64): u64
+	9: LdU64(0)
+	10: Pack[0](Wrap)
+	11: StLoc[4](loc2: Wrap)
+	12: StLoc[5](loc3: &mut u64)
+	13: MoveLoc[2](loc0: &signer)
+	14: MoveLoc[5](loc3: &mut u64)
+	15: MoveLoc[4](loc2: Wrap)
+	16: Call bar(&signer, &mut u64, Wrap)
+	17: Ret
+}
+zero(Arg0: u64): u64 /* def_idx: 2 */ {
+B0:
+	0: LdU64(0)
+	1: Ret
+}
+}
+============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_04.move b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_04.move
new file mode 100644
index 0000000000000..b22d2aa1e2c70
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_04.move
@@ -0,0 +1,20 @@
+module 0xc0ffee::m {
+    struct Wrap has drop, key {
+        a: u64,
+        b: u64,
+        c: u64,
+        d: u64,
+    }
+
+    fun zero(_y: u64): u64 {
+        0
+    }
+
+    fun bar(_x: &signer, _y: &mut u64, _w: Wrap) {}
+
+    public fun test(x: signer, a: address) acquires Wrap {
+        let y = 0;
+        let ref = borrow_global_mut<Wrap>(a);
+        bar(&x, &mut ref.a, Wrap {a: y, b: 0, c: zero(y), d: 0});
+    }
+}
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_05.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_05.exp
new file mode 100644
index 0000000000000..df80a414a62d7
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_05.exp
@@ -0,0 +1,98 @@
+============ initial bytecode ================
+
+[variant baseline]
+fun m::foo($t0: &signer, $t1: u64, $t2: u64) {
+  0: return ()
+}
+
+
+[variant baseline]
+public fun m::test($t0: &signer, $t1: 0xc0ffee::m::S) {
+     var $t2: u64
+     var $t3: &0xc0ffee::m::S
+     var $t4: &u64
+     var $t5: u64
+     var $t6: &0xc0ffee::m::S
+     var $t7: &u64
+  0: $t3 := borrow_local($t1)
+  1: $t4 := borrow_field<0xc0ffee::m::S>.a($t3)
+  2: $t2 := read_ref($t4)
+  3: $t6 := borrow_local($t1)
+  4: $t7 := borrow_field<0xc0ffee::m::S>.b($t6)
+  5: $t5 := read_ref($t7)
+  6: m::foo($t0, $t2, $t5)
+  7: return ()
+}
+
+============ after LiveVarAnalysisProcessor: ================
+
+[variant baseline]
+fun m::foo($t0: &signer, $t1: u64, $t2: u64) {
+     # live vars: $t0, $t1, $t2
+  0: drop($t0)
+     # live vars:
+  1: return ()
+}
+
+
+[variant baseline]
+public fun m::test($t0: &signer, $t1: 0xc0ffee::m::S) {
+     var $t2: u64
+     var $t3: &0xc0ffee::m::S
+     var $t4: &u64
+     var $t5: u64
+     var $t6: &0xc0ffee::m::S [unused]
+     var $t7: &u64 [unused]
+     # live vars: $t0, $t1
+  0: $t3 := borrow_local($t1)
+     # live vars: $t0, $t1, $t3
+  1: $t4 := borrow_field<0xc0ffee::m::S>.a($t3)
+     # live vars: $t0, $t1, $t4
+  2: $t2 := read_ref($t4)
+     # live vars: $t0, $t1, $t2
+  3: $t3 := borrow_local($t1)
+     # live vars: $t0, $t2, $t3
+  4: $t4 := borrow_field<0xc0ffee::m::S>.b($t3)
+     # live vars: $t0, $t2, $t4
+  5: $t5 := read_ref($t4)
+     # live vars: $t0, $t2, $t5
+  6: m::foo($t0, $t2, $t5)
+     # live vars:
+  7: return ()
+}
+
+
+============ disassembled file-format ==================
+// Move bytecode v7
+module c0ffee.m {
+struct S has drop {
+	a: u64,
+	b: u64
+}
+
+foo(Arg0: &signer, Arg1: u64, Arg2: u64) /* def_idx: 0 */ {
+B0:
+	0: MoveLoc[0](Arg0: &signer)
+	1: Pop
+	2: Ret
+}
+public test(Arg0: &signer, Arg1: S) /* def_idx: 1 */ {
+L2:	loc0: u64
+L3:	loc1: u64
+B0:
+	0: ImmBorrowLoc[1](Arg1: S)
+	1: ImmBorrowField[0](S.a: u64)
+	2: ReadRef
+	3: ImmBorrowLoc[1](Arg1: S)
+	4: ImmBorrowField[1](S.b: u64)
+	5: ReadRef
+	6: StLoc[2](loc0: u64)
+	7: StLoc[3](loc1: u64)
+	8: MoveLoc[0](Arg0: &signer)
+	9: MoveLoc[3](loc1: u64)
+	10: MoveLoc[2](loc0: u64)
+	11: Call foo(&signer, u64, u64)
+	12: Ret
+}
+}
+============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_05.move b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_05.move
new file mode 100644
index 0000000000000..2f2b8af3c2d3c
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_05.move
@@ -0,0 +1,13 @@
+module 0xc0ffee::m {
+    struct S has drop {
+        a: u64,
+        b: u64,
+    }
+
+    fun foo(_x: &signer, _y: u64, _z: u64) {}
+
+    public fun test(x: &signer, y: S) {
+        foo(x, y.a, y.b);
+    }
+
+}
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_06.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_06.exp
new file mode 100644
index 0000000000000..f55c5a103ba6d
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_06.exp
@@ -0,0 +1,222 @@
+============ initial bytecode ================
+
+[variant baseline]
+fun m::bar($t0: &mut 0xc0ffee::m::S, $t1: u64): u64 {
+     var $t2: u64
+     var $t3: &mut u64
+  0: $t3 := borrow_field<0xc0ffee::m::S>.x($t0)
+  1: write_ref($t3, $t1)
+  2: $t2 := infer($t1)
+  3: return $t2
+}
+
+
+[variant baseline]
+fun m::destroy($t0: 0xc0ffee::m::S) {
+     var $t1: u64
+  0: $t1 := unpack 0xc0ffee::m::S($t0)
+  1: return ()
+}
+
+
+[variant baseline]
+fun m::foo($t0: &mut 0xc0ffee::m::S, $t1: u64) {
+     var $t2: &mut u64
+  0: $t2 := borrow_field<0xc0ffee::m::S>.x($t0)
+  1: write_ref($t2, $t1)
+  2: return ()
+}
+
+
+[variant baseline]
+public fun m::test($t0: &mut 0xc0ffee::m::S, $t1: 0xc0ffee::m::S) {
+     var $t2: u64
+     var $t3: bool
+     var $t4: u64
+     var $t5: &mut 0xc0ffee::m::S
+     var $t6: u64
+     var $t7: &mut 0xc0ffee::m::S
+     var $t8: u64
+     var $t9: u64
+  0: $t2 := 0
+  1: label L0
+  2: $t4 := 42
+  3: $t3 := <($t2, $t4)
+  4: if ($t3) goto 5 else goto 14
+  5: label L2
+  6: $t5 := infer($t0)
+  7: $t7 := borrow_local($t1)
+  8: $t6 := m::bar($t7, $t2)
+  9: m::foo($t5, $t6)
+ 10: $t9 := 1
+ 11: $t8 := +($t2, $t9)
+ 12: $t2 := infer($t8)
+ 13: goto 16
+ 14: label L3
+ 15: goto 18
+ 16: label L4
+ 17: goto 1
+ 18: label L1
+ 19: m::destroy($t1)
+ 20: return ()
+}
+
+============ after LiveVarAnalysisProcessor: ================
+
+[variant baseline]
+fun m::bar($t0: &mut 0xc0ffee::m::S, $t1: u64): u64 {
+     var $t2: u64 [unused]
+     var $t3: &mut u64
+     # live vars: $t0, $t1
+  0: $t3 := borrow_field<0xc0ffee::m::S>.x($t0)
+     # live vars: $t1, $t3
+  1: write_ref($t3, $t1)
+     # live vars: $t1
+  2: return $t1
+}
+
+
+[variant baseline]
+fun m::destroy($t0: 0xc0ffee::m::S) {
+     var $t1: u64
+     # live vars: $t0
+  0: $t1 := unpack 0xc0ffee::m::S($t0)
+     # live vars:
+  1: return ()
+}
+
+
+[variant baseline]
+fun m::foo($t0: &mut 0xc0ffee::m::S, $t1: u64) {
+     var $t2: &mut u64
+     # live vars: $t0, $t1
+  0: $t2 := borrow_field<0xc0ffee::m::S>.x($t0)
+     # live vars: $t1, $t2
+  1: write_ref($t2, $t1)
+     # live vars:
+  2: return ()
+}
+
+
+[variant baseline]
+public fun m::test($t0: &mut 0xc0ffee::m::S, $t1: 0xc0ffee::m::S) {
+     var $t2: u64
+     var $t3: bool
+     var $t4: u64
+     var $t5: &mut 0xc0ffee::m::S
+     var $t6: u64 [unused]
+     var $t7: &mut 0xc0ffee::m::S
+     var $t8: u64 [unused]
+     var $t9: u64 [unused]
+     # live vars: $t0, $t1
+  0: $t2 := 0
+     # live vars: $t0, $t1, $t2
+  1: label L0
+     # live vars: $t0, $t1, $t2
+  2: $t4 := 42
+     # live vars: $t0, $t1, $t2, $t4
+  3: $t3 := <($t2, $t4)
+     # live vars: $t0, $t1, $t2, $t3
+  4: if ($t3) goto 5 else goto 14
+     # live vars: $t0, $t1, $t2
+  5: label L2
+     # live vars: $t0, $t1, $t2
+  6: $t5 := copy($t0)
+     # live vars: $t0, $t1, $t2, $t5
+  7: $t7 := borrow_local($t1)
+     # live vars: $t0, $t1, $t2, $t5, $t7
+  8: $t4 := m::bar($t7, $t2)
+     # live vars: $t0, $t1, $t2, $t4, $t5
+  9: m::foo($t5, $t4)
+     # live vars: $t0, $t1, $t2
+ 10: $t4 := 1
+     # live vars: $t0, $t1, $t2, $t4
+ 11: $t4 := +($t2, $t4)
+     # live vars: $t0, $t1, $t4
+ 12: $t2 := move($t4)
+     # live vars: $t0, $t1, $t2
+ 13: goto 1
+     # live vars: $t0, $t1, $t2
+ 14: label L3
+     # live vars: $t0, $t1
+ 15: drop($t0)
+     # live vars: $t1
+ 16: m::destroy($t1)
+     # live vars:
+ 17: return ()
+}
+
+
+============ disassembled file-format ==================
+// Move bytecode v7
+module c0ffee.m {
+struct S {
+	x: u64
+}
+
+bar(Arg0: &mut S, Arg1: u64): u64 /* def_idx: 0 */ {
+L2:	loc0: &mut u64
+B0:
+	0: MoveLoc[0](Arg0: &mut S)
+	1: MutBorrowField[0](S.x: u64)
+	2: StLoc[2](loc0: &mut u64)
+	3: CopyLoc[1](Arg1: u64)
+	4: MoveLoc[2](loc0: &mut u64)
+	5: WriteRef
+	6: MoveLoc[1](Arg1: u64)
+	7: Ret
+}
+destroy(Arg0: S) /* def_idx: 1 */ {
+B0:
+	0: MoveLoc[0](Arg0: S)
+	1: Unpack[0](S)
+	2: Pop
+	3: Ret
+}
+foo(Arg0: &mut S, Arg1: u64) /* def_idx: 2 */ {
+L2:	loc0: &mut u64
+B0:
+	0: MoveLoc[0](Arg0: &mut S)
+	1: MutBorrowField[0](S.x: u64)
+	2: StLoc[2](loc0: &mut u64)
+	3: MoveLoc[1](Arg1: u64)
+	4: MoveLoc[2](loc0: &mut u64)
+	5: WriteRef
+	6: Ret
+}
+public test(Arg0: &mut S, Arg1: S) /* def_idx: 3 */ {
+L2:	loc0: u64
+L3:	loc1: u64
+L4:	loc2: &mut S
+B0:
+	0: LdU64(0)
+	1: StLoc[2](loc0: u64)
+B1:
+	2: CopyLoc[2](loc0: u64)
+	3: LdU64(42)
+	4: Lt
+	5: BrFalse(20)
+B2:
+	6: CopyLoc[0](Arg0: &mut S)
+	7: StLoc[4](loc2: &mut S)
+	8: MutBorrowLoc[1](Arg1: S)
+	9: CopyLoc[2](loc0: u64)
+	10: Call bar(&mut S, u64): u64
+	11: StLoc[3](loc1: u64)
+	12: MoveLoc[4](loc2: &mut S)
+	13: MoveLoc[3](loc1: u64)
+	14: Call foo(&mut S, u64)
+	15: MoveLoc[2](loc0: u64)
+	16: LdU64(1)
+	17: Add
+	18: StLoc[2](loc0: u64)
+	19: Branch(2)
+B3:
+	20: MoveLoc[0](Arg0: &mut S)
+	21: Pop
+	22: MoveLoc[1](Arg1: S)
+	23: Call destroy(S)
+	24: Ret
+}
+}
+============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_06.move b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_06.move
new file mode 100644
index 0000000000000..d096ccd80248c
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_06.move
@@ -0,0 +1,27 @@
+module 0xc0ffee::m {
+    struct S {
+        x: u64,
+    }
+
+    fun bar(r: &mut S, i: u64): u64 {
+        r.x = i;
+        i
+    }
+
+    fun foo(l: &mut S, i: u64) {
+        l.x = i;
+    }
+
+    fun destroy(s: S) {
+        let S { x: _ } = s;
+    }
+
+    public fun test(l: &mut S, r: S) {
+        let i = 0;
+        while (i < 42) {
+            foo(l, bar(&mut r, i));
+            i = i + 1;
+        };
+        destroy(r);
+    }
+}
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_07.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_07.exp
new file mode 100644
index 0000000000000..2b2cd73ef54e5
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_07.exp
@@ -0,0 +1,142 @@
+============ initial bytecode ================
+
+[variant baseline]
+fun m::bar($t0: &mut u64, $t1: u64) {
+  0: write_ref($t0, $t1)
+  1: return ()
+}
+
+
+[variant baseline]
+fun m::foo($t0: &mut u64, $t1: u64): &mut u64 {
+     var $t2: &mut u64
+  0: write_ref($t0, $t1)
+  1: $t2 := infer($t0)
+  2: return $t2
+}
+
+
+[variant baseline]
+public fun m::test($t0: &mut 0xc0ffee::m::S, $t1: u64) {
+     var $t2: &mut u64
+     var $t3: &mut u64
+     var $t4: u64
+     var $t5: u64
+     var $t6: &u64
+     var $t7: u64
+     var $t8: u64
+     var $t9: &u64
+  0: $t3 := borrow_field<0xc0ffee::m::S>.x($t0)
+  1: $t6 := borrow_field<0xc0ffee::m::S>.y($t0)
+  2: $t5 := read_ref($t6)
+  3: $t4 := /($t1, $t5)
+  4: $t2 := m::foo($t3, $t4)
+  5: $t9 := borrow_field<0xc0ffee::m::S>.y($t0)
+  6: $t8 := read_ref($t9)
+  7: $t7 := /($t1, $t8)
+  8: m::bar($t2, $t7)
+  9: return ()
+}
+
+============ after LiveVarAnalysisProcessor: ================
+
+[variant baseline]
+fun m::bar($t0: &mut u64, $t1: u64) {
+     # live vars: $t0, $t1
+  0: write_ref($t0, $t1)
+     # live vars:
+  1: return ()
+}
+
+
+[variant baseline]
+fun m::foo($t0: &mut u64, $t1: u64): &mut u64 {
+     var $t2: &mut u64 [unused]
+     # live vars: $t0, $t1
+  0: write_ref($t0, $t1)
+     # live vars: $t0
+  1: return $t0
+}
+
+
+[variant baseline]
+public fun m::test($t0: &mut 0xc0ffee::m::S, $t1: u64) {
+     var $t2: &mut u64 [unused]
+     var $t3: &mut u64
+     var $t4: u64 [unused]
+     var $t5: u64
+     var $t6: &u64
+     var $t7: u64 [unused]
+     var $t8: u64 [unused]
+     var $t9: &u64 [unused]
+     # live vars: $t0, $t1
+  0: $t3 := borrow_field<0xc0ffee::m::S>.x($t0)
+     # live vars: $t0, $t1, $t3
+  1: $t6 := borrow_field<0xc0ffee::m::S>.y($t0)
+     # live vars: $t0, $t1, $t3, $t6
+  2: $t5 := read_ref($t6)
+     # live vars: $t0, $t1, $t3, $t5
+  3: $t5 := /($t1, $t5)
+     # live vars: $t0, $t1, $t3, $t5
+  4: $t3 := m::foo($t3, $t5)
+     # live vars: $t0, $t1, $t3
+  5: $t6 := borrow_field<0xc0ffee::m::S>.y($t0)
+     # live vars: $t1, $t3, $t6
+  6: $t5 := read_ref($t6)
+     # live vars: $t1, $t3, $t5
+  7: $t1 := /($t1, $t5)
+     # live vars: $t1, $t3
+  8: m::bar($t3, $t1)
+     # live vars:
+  9: return ()
+}
+
+
+============ disassembled file-format ==================
+// Move bytecode v7
+module c0ffee.m {
+struct S {
+	x: u64,
+	y: u64
+}
+
+bar(Arg0: &mut u64, Arg1: u64) /* def_idx: 0 */ {
+B0:
+	0: MoveLoc[1](Arg1: u64)
+	1: MoveLoc[0](Arg0: &mut u64)
+	2: WriteRef
+	3: Ret
+}
+foo(Arg0: &mut u64, Arg1: u64): &mut u64 /* def_idx: 1 */ {
+B0:
+	0: MoveLoc[1](Arg1: u64)
+	1: CopyLoc[0](Arg0: &mut u64)
+	2: WriteRef
+	3: MoveLoc[0](Arg0: &mut u64)
+	4: Ret
+}
+public test(Arg0: &mut S, Arg1: u64) /* def_idx: 2 */ {
+L2:	loc0: u64
+B0:
+	0: CopyLoc[0](Arg0: &mut S)
+	1: MutBorrowField[0](S.x: u64)
+	2: CopyLoc[0](Arg0: &mut S)
+	3: ImmBorrowField[1](S.y: u64)
+	4: ReadRef
+	5: StLoc[2](loc0: u64)
+	6: CopyLoc[1](Arg1: u64)
+	7: MoveLoc[2](loc0: u64)
+	8: Div
+	9: Call foo(&mut u64, u64): &mut u64
+	10: MoveLoc[0](Arg0: &mut S)
+	11: ImmBorrowField[1](S.y: u64)
+	12: ReadRef
+	13: StLoc[2](loc0: u64)
+	14: MoveLoc[1](Arg1: u64)
+	15: MoveLoc[2](loc0: u64)
+	16: Div
+	17: Call bar(&mut u64, u64)
+	18: Ret
+}
+}
+============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_07.move b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_07.move
new file mode 100644
index 0000000000000..37427dea2a2cf
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_07.move
@@ -0,0 +1,19 @@
+module 0xc0ffee::m {
+    struct S {
+        x: u64,
+        y: u64,
+    }
+
+    fun foo(l: &mut u64, i: u64): &mut u64 {
+        *l = i;
+        l
+    }
+
+    fun bar(r: &mut u64, i: u64) {
+        *r = i;
+    }
+
+    public fun test(s: &mut S, i: u64) {
+        bar(foo(&mut s.x, i / s.y), i / s.y);
+    }
+}
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_08.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_08.exp
new file mode 100644
index 0000000000000..f8557d046d801
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_08.exp
@@ -0,0 +1,134 @@
+============ initial bytecode ================
+
+[variant baseline]
+fun m::bar($t0: &u64, $t1: u64) {
+  0: return ()
+}
+
+
+[variant baseline]
+fun m::foo($t0: &u64, $t1: u64): &u64 {
+     var $t2: &u64
+  0: $t2 := infer($t0)
+  1: return $t2
+}
+
+
+[variant baseline]
+public fun m::test($t0: &0xc0ffee::m::S, $t1: u64) {
+     var $t2: &u64
+     var $t3: &u64
+     var $t4: u64
+     var $t5: u64
+     var $t6: &u64
+     var $t7: u64
+     var $t8: u64
+     var $t9: &u64
+  0: $t3 := borrow_field<0xc0ffee::m::S>.x($t0)
+  1: $t6 := borrow_field<0xc0ffee::m::S>.y($t0)
+  2: $t5 := read_ref($t6)
+  3: $t4 := /($t1, $t5)
+  4: $t2 := m::foo($t3, $t4)
+  5: $t9 := borrow_field<0xc0ffee::m::S>.y($t0)
+  6: $t8 := read_ref($t9)
+  7: $t7 := /($t1, $t8)
+  8: m::bar($t2, $t7)
+  9: return ()
+}
+
+============ after LiveVarAnalysisProcessor: ================
+
+[variant baseline]
+fun m::bar($t0: &u64, $t1: u64) {
+     # live vars: $t0, $t1
+  0: drop($t0)
+     # live vars:
+  1: return ()
+}
+
+
+[variant baseline]
+fun m::foo($t0: &u64, $t1: u64): &u64 {
+     var $t2: &u64 [unused]
+     # live vars: $t0, $t1
+  0: return $t0
+}
+
+
+[variant baseline]
+public fun m::test($t0: &0xc0ffee::m::S, $t1: u64) {
+     var $t2: &u64 [unused]
+     var $t3: &u64
+     var $t4: u64 [unused]
+     var $t5: u64
+     var $t6: &u64
+     var $t7: u64 [unused]
+     var $t8: u64 [unused]
+     var $t9: &u64 [unused]
+     # live vars: $t0, $t1
+  0: $t3 := borrow_field<0xc0ffee::m::S>.x($t0)
+     # live vars: $t0, $t1, $t3
+  1: $t6 := borrow_field<0xc0ffee::m::S>.y($t0)
+     # live vars: $t0, $t1, $t3, $t6
+  2: $t5 := read_ref($t6)
+     # live vars: $t0, $t1, $t3, $t5
+  3: $t5 := /($t1, $t5)
+     # live vars: $t0, $t1, $t3, $t5
+  4: $t3 := m::foo($t3, $t5)
+     # live vars: $t0, $t1, $t3
+  5: $t6 := borrow_field<0xc0ffee::m::S>.y($t0)
+     # live vars: $t1, $t3, $t6
+  6: $t5 := read_ref($t6)
+     # live vars: $t1, $t3, $t5
+  7: $t1 := /($t1, $t5)
+     # live vars: $t1, $t3
+  8: m::bar($t3, $t1)
+     # live vars:
+  9: return ()
+}
+
+
+============ disassembled file-format ==================
+// Move bytecode v7
+module c0ffee.m {
+struct S {
+	x: u64,
+	y: u64
+}
+
+bar(Arg0: &u64, Arg1: u64) /* def_idx: 0 */ {
+B0:
+	0: MoveLoc[0](Arg0: &u64)
+	1: Pop
+	2: Ret
+}
+foo(Arg0: &u64, Arg1: u64): &u64 /* def_idx: 1 */ {
+B0:
+	0: MoveLoc[0](Arg0: &u64)
+	1: Ret
+}
+public test(Arg0: &S, Arg1: u64) /* def_idx: 2 */ {
+L2:	loc0: u64
+B0:
+	0: CopyLoc[0](Arg0: &S)
+	1: ImmBorrowField[0](S.x: u64)
+	2: CopyLoc[0](Arg0: &S)
+	3: ImmBorrowField[1](S.y: u64)
+	4: ReadRef
+	5: StLoc[2](loc0: u64)
+	6: CopyLoc[1](Arg1: u64)
+	7: MoveLoc[2](loc0: u64)
+	8: Div
+	9: Call foo(&u64, u64): &u64
+	10: MoveLoc[0](Arg0: &S)
+	11: ImmBorrowField[1](S.y: u64)
+	12: ReadRef
+	13: StLoc[2](loc0: u64)
+	14: MoveLoc[1](Arg1: u64)
+	15: MoveLoc[2](loc0: u64)
+	16: Div
+	17: Call bar(&u64, u64)
+	18: Ret
+}
+}
+============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_08.move b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_08.move
new file mode 100644
index 0000000000000..6f352d2fdaf87
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_08.move
@@ -0,0 +1,16 @@
+module 0xc0ffee::m {
+    struct S {
+        x: u64,
+        y: u64,
+    }
+
+    fun foo(l: &u64, _i: u64): &u64 {
+        l
+    }
+
+    fun bar(_r: &u64, _i: u64) {}
+
+    public fun test(s: &S, i: u64) {
+        bar(foo(&s.x, i / s.y), i / s.y);
+    }
+}
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_09.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_09.exp
new file mode 100644
index 0000000000000..df94d0ba33f15
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_09.exp
@@ -0,0 +1,204 @@
+============ initial bytecode ================
+
+[variant baseline]
+fun m::bar($t0: &mut u64, $t1: u64): &mut u64 {
+     var $t2: &mut u64
+  0: write_ref($t0, $t1)
+  1: $t2 := infer($t0)
+  2: return $t2
+}
+
+
+[variant baseline]
+fun m::baz($t0: &mut u64, $t1: u64) {
+  0: write_ref($t0, $t1)
+  1: return ()
+}
+
+
+[variant baseline]
+fun m::foo($t0: &u64): u64 {
+     var $t1: u64
+  0: $t1 := read_ref($t0)
+  1: return $t1
+}
+
+
+[variant baseline]
+public fun m::test($t0: &mut 0xc0ffee::m::S, $t1: u64) {
+     var $t2: u64
+     var $t3: &u64
+     var $t4: bool
+     var $t5: u64
+     var $t6: &u64
+     var $t7: u64
+     var $t8: u64
+     var $t9: &u64
+     var $t10: &mut u64
+     var $t11: &mut u64
+  0: $t3 := borrow_field<0xc0ffee::m::S>.x($t0)
+  1: $t2 := m::foo($t3)
+  2: $t6 := borrow_field<0xc0ffee::m::S>.x($t0)
+  3: $t5 := read_ref($t6)
+  4: $t9 := borrow_field<0xc0ffee::m::S>.y($t0)
+  5: $t8 := read_ref($t9)
+  6: $t7 := *($t2, $t8)
+  7: $t4 := ==($t5, $t7)
+  8: if ($t4) goto 9 else goto 14
+  9: label L0
+ 10: $t11 := borrow_field<0xc0ffee::m::S>.x($t0)
+ 11: $t10 := m::bar($t11, $t2)
+ 12: m::baz($t10, $t1)
+ 13: goto 15
+ 14: label L1
+ 15: label L2
+ 16: return ()
+}
+
+============ after LiveVarAnalysisProcessor: ================
+
+[variant baseline]
+fun m::bar($t0: &mut u64, $t1: u64): &mut u64 {
+     var $t2: &mut u64 [unused]
+     # live vars: $t0, $t1
+  0: write_ref($t0, $t1)
+     # live vars: $t0
+  1: return $t0
+}
+
+
+[variant baseline]
+fun m::baz($t0: &mut u64, $t1: u64) {
+     # live vars: $t0, $t1
+  0: write_ref($t0, $t1)
+     # live vars:
+  1: return ()
+}
+
+
+[variant baseline]
+fun m::foo($t0: &u64): u64 {
+     var $t1: u64
+     # live vars: $t0
+  0: $t1 := read_ref($t0)
+     # live vars: $t1
+  1: return $t1
+}
+
+
+[variant baseline]
+public fun m::test($t0: &mut 0xc0ffee::m::S, $t1: u64) {
+     var $t2: u64
+     var $t3: &u64
+     var $t4: bool
+     var $t5: u64
+     var $t6: &u64 [unused]
+     var $t7: u64 [unused]
+     var $t8: u64
+     var $t9: &u64 [unused]
+     var $t10: &mut u64 [unused]
+     var $t11: &mut u64
+     # live vars: $t0, $t1
+  0: $t3 := borrow_field<0xc0ffee::m::S>.x($t0)
+     # live vars: $t0, $t1, $t3
+  1: $t2 := m::foo($t3)
+     # live vars: $t0, $t1, $t2
+  2: $t3 := borrow_field<0xc0ffee::m::S>.x($t0)
+     # live vars: $t0, $t1, $t2, $t3
+  3: $t5 := read_ref($t3)
+     # live vars: $t0, $t1, $t2, $t5
+  4: $t3 := borrow_field<0xc0ffee::m::S>.y($t0)
+     # live vars: $t0, $t1, $t2, $t3, $t5
+  5: $t8 := read_ref($t3)
+     # live vars: $t0, $t1, $t2, $t5, $t8
+  6: $t8 := *($t2, $t8)
+     # live vars: $t0, $t1, $t2, $t5, $t8
+  7: $t4 := ==($t5, $t8)
+     # live vars: $t0, $t1, $t2, $t4
+  8: if ($t4) goto 9 else goto 15
+     # live vars: $t0, $t1, $t2
+  9: label L0
+     # live vars: $t0, $t1, $t2
+ 10: $t11 := borrow_field<0xc0ffee::m::S>.x($t0)
+     # live vars: $t1, $t2, $t11
+ 11: $t11 := m::bar($t11, $t2)
+     # live vars: $t1, $t11
+ 12: m::baz($t11, $t1)
+     # live vars:
+ 13: label L2
+     # live vars:
+ 14: return ()
+     # live vars: $t0, $t1, $t2
+ 15: label L1
+     # live vars: $t0
+ 16: drop($t0)
+     # live vars:
+ 17: goto 13
+}
+
+
+============ disassembled file-format ==================
+// Move bytecode v7
+module c0ffee.m {
+struct S {
+	x: u64,
+	y: u64
+}
+
+bar(Arg0: &mut u64, Arg1: u64): &mut u64 /* def_idx: 0 */ {
+B0:
+	0: MoveLoc[1](Arg1: u64)
+	1: CopyLoc[0](Arg0: &mut u64)
+	2: WriteRef
+	3: MoveLoc[0](Arg0: &mut u64)
+	4: Ret
+}
+baz(Arg0: &mut u64, Arg1: u64) /* def_idx: 1 */ {
+B0:
+	0: MoveLoc[1](Arg1: u64)
+	1: MoveLoc[0](Arg0: &mut u64)
+	2: WriteRef
+	3: Ret
+}
+foo(Arg0: &u64): u64 /* def_idx: 2 */ {
+B0:
+	0: MoveLoc[0](Arg0: &u64)
+	1: ReadRef
+	2: Ret
+}
+public test(Arg0: &mut S, Arg1: u64) /* def_idx: 3 */ {
+L2:	loc0: u64
+L3:	loc1: u64
+B0:
+	0: CopyLoc[0](Arg0: &mut S)
+	1: ImmBorrowField[0](S.x: u64)
+	2: Call foo(&u64): u64
+	3: StLoc[2](loc0: u64)
+	4: CopyLoc[0](Arg0: &mut S)
+	5: ImmBorrowField[0](S.x: u64)
+	6: ReadRef
+	7: CopyLoc[0](Arg0: &mut S)
+	8: ImmBorrowField[1](S.y: u64)
+	9: ReadRef
+	10: StLoc[3](loc1: u64)
+	11: CopyLoc[2](loc0: u64)
+	12: MoveLoc[3](loc1: u64)
+	13: Mul
+	14: Eq
+	15: BrFalse(23)
+B1:
+	16: MoveLoc[0](Arg0: &mut S)
+	17: MutBorrowField[0](S.x: u64)
+	18: MoveLoc[2](loc0: u64)
+	19: Call bar(&mut u64, u64): &mut u64
+	20: MoveLoc[1](Arg1: u64)
+	21: Call baz(&mut u64, u64)
+B2:
+	22: Ret
+B3:
+	23: MoveLoc[0](Arg0: &mut S)
+	24: Pop
+	25: Branch(22)
+}
+}
+============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_09.move b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_09.move
new file mode 100644
index 0000000000000..33cf25c2f3f70
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_09.move
@@ -0,0 +1,26 @@
+module 0xc0ffee::m {
+    struct S {
+        x: u64,
+        y: u64,
+    }
+
+    fun foo(l: &u64): u64 {
+        *l
+    }
+
+    fun bar(r: &mut u64, i: u64): &mut u64 {
+        *r = i;
+        r
+    }
+
+    fun baz(r: &mut u64, i: u64) {
+        *r = i;
+    }
+
+    public fun test(s: &mut S, v: u64) {
+        let n = foo(&s.x);
+        if (s.x == n * s.y) {
+            baz(bar(&mut s.x, n), v);
+        }
+    }
+}
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_10.exp b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_10.exp
new file mode 100644
index 0000000000000..ff95289d51c83
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_10.exp
@@ -0,0 +1,194 @@
+============ initial bytecode ================
+
+[variant baseline]
+fun m::bar($t0: &mut u64, $t1: u64) {
+  0: write_ref($t0, $t1)
+  1: return ()
+}
+
+
+[variant baseline]
+fun m::foo($t0: &u64): u64 {
+     var $t1: u64
+  0: $t1 := read_ref($t0)
+  1: return $t1
+}
+
+
+[variant baseline]
+public fun m::test($t0: &mut 0xc0ffee::m::S, $t1: u64) {
+     var $t2: u64
+     var $t3: u64
+     var $t4: &u64
+     var $t5: u64
+     var $t6: &u64
+     var $t7: bool
+     var $t8: &mut u64
+     var $t9: u64
+     var $t10: u64
+     var $t11: u64
+     var $t12: u64
+  0: $t4 := borrow_field<0xc0ffee::m::S>.x($t0)
+  1: $t3 := read_ref($t4)
+  2: $t2 := /($t1, $t3)
+  3: $t6 := borrow_field<0xc0ffee::m::S>.y($t0)
+  4: $t5 := m::foo($t6)
+  5: label L0
+  6: $t7 := <($t2, $t5)
+  7: if ($t7) goto 8 else goto 17
+  8: label L2
+  9: $t8 := borrow_field<0xc0ffee::m::S>.z($t0)
+ 10: $t10 := 1
+ 11: $t9 := -($t2, $t10)
+ 12: m::bar($t8, $t9)
+ 13: $t12 := 1
+ 14: $t11 := +($t2, $t12)
+ 15: $t2 := infer($t11)
+ 16: goto 19
+ 17: label L3
+ 18: goto 21
+ 19: label L4
+ 20: goto 5
+ 21: label L1
+ 22: return ()
+}
+
+============ after LiveVarAnalysisProcessor: ================
+
+[variant baseline]
+fun m::bar($t0: &mut u64, $t1: u64) {
+     # live vars: $t0, $t1
+  0: write_ref($t0, $t1)
+     # live vars:
+  1: return ()
+}
+
+
+[variant baseline]
+fun m::foo($t0: &u64): u64 {
+     var $t1: u64
+     # live vars: $t0
+  0: $t1 := read_ref($t0)
+     # live vars: $t1
+  1: return $t1
+}
+
+
+[variant baseline]
+public fun m::test($t0: &mut 0xc0ffee::m::S, $t1: u64) {
+     var $t2: u64 [unused]
+     var $t3: u64
+     var $t4: &u64
+     var $t5: u64 [unused]
+     var $t6: &u64 [unused]
+     var $t7: bool
+     var $t8: &mut u64
+     var $t9: u64 [unused]
+     var $t10: u64
+     var $t11: u64 [unused]
+     var $t12: u64 [unused]
+     # live vars: $t0, $t1
+  0: $t4 := borrow_field<0xc0ffee::m::S>.x($t0)
+     # live vars: $t0, $t1, $t4
+  1: $t3 := read_ref($t4)
+     # live vars: $t0, $t1, $t3
+  2: $t1 := /($t1, $t3)
+     # live vars: $t0, $t1
+  3: $t4 := borrow_field<0xc0ffee::m::S>.y($t0)
+     # live vars: $t0, $t1, $t4
+  4: $t3 := m::foo($t4)
+     # live vars: $t0, $t1, $t3
+  5: label L0
+     # live vars: $t0, $t1, $t3
+  6: $t7 := <($t1, $t3)
+     # live vars: $t0, $t1, $t3, $t7
+  7: if ($t7) goto 8 else goto 17
+     # live vars: $t0, $t1, $t3
+  8: label L2
+     # live vars: $t0, $t1, $t3
+  9: $t8 := borrow_field<0xc0ffee::m::S>.z($t0)
+     # live vars: $t0, $t1, $t3, $t8
+ 10: $t10 := 1
+     # live vars: $t0, $t1, $t3, $t8, $t10
+ 11: $t10 := -($t1, $t10)
+     # live vars: $t0, $t1, $t3, $t8, $t10
+ 12: m::bar($t8, $t10)
+     # live vars: $t0, $t1, $t3
+ 13: $t10 := 1
+     # live vars: $t0, $t1, $t3, $t10
+ 14: $t10 := +($t1, $t10)
+     # live vars: $t0, $t3, $t10
+ 15: $t1 := move($t10)
+     # live vars: $t0, $t1, $t3
+ 16: goto 5
+     # live vars: $t0, $t1, $t3
+ 17: label L3
+     # live vars: $t0
+ 18: drop($t0)
+     # live vars:
+ 19: return ()
+}
+
+
+============ disassembled file-format ==================
+// Move bytecode v7
+module c0ffee.m {
+struct S {
+	x: u64,
+	y: u64,
+	z: u64
+}
+
+bar(Arg0: &mut u64, Arg1: u64) /* def_idx: 0 */ {
+B0:
+	0: MoveLoc[1](Arg1: u64)
+	1: MoveLoc[0](Arg0: &mut u64)
+	2: WriteRef
+	3: Ret
+}
+foo(Arg0: &u64): u64 /* def_idx: 1 */ {
+B0:
+	0: MoveLoc[0](Arg0: &u64)
+	1: ReadRef
+	2: Ret
+}
+public test(Arg0: &mut S, Arg1: u64) /* def_idx: 2 */ {
+L2:	loc0: u64
+L3:	loc1: u64
+B0:
+	0: CopyLoc[0](Arg0: &mut S)
+	1: ImmBorrowField[0](S.x: u64)
+	2: ReadRef
+	3: StLoc[2](loc0: u64)
+	4: MoveLoc[1](Arg1: u64)
+	5: MoveLoc[2](loc0: u64)
+	6: Div
+	7: StLoc[1](Arg1: u64)
+	8: CopyLoc[0](Arg0: &mut S)
+	9: ImmBorrowField[1](S.y: u64)
+	10: Call foo(&u64): u64
+	11: StLoc[2](loc0: u64)
+B1:
+	12: CopyLoc[1](Arg1: u64)
+	13: CopyLoc[2](loc0: u64)
+	14: Lt
+	15: BrFalse(27)
+B2:
+	16: CopyLoc[0](Arg0: &mut S)
+	17: MutBorrowField[2](S.z: u64)
+	18: CopyLoc[1](Arg1: u64)
+	19: LdU64(1)
+	20: Sub
+	21: Call bar(&mut u64, u64)
+	22: MoveLoc[1](Arg1: u64)
+	23: LdU64(1)
+	24: Add
+	25: StLoc[1](Arg1: u64)
+	26: Branch(12)
+B3:
+	27: MoveLoc[0](Arg0: &mut S)
+	28: Pop
+	29: Ret
+}
+}
+============ bytecode verification succeeded ========
diff --git a/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_10.move b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_10.move
new file mode 100644
index 0000000000000..037dd22d069d7
--- /dev/null
+++ b/third_party/move/move-compiler-v2/tests/eager-pushes/framework_reduced_10.move
@@ -0,0 +1,25 @@
+module 0xc0ffee::m {
+    struct S {
+        x: u64,
+        y: u64,
+        z: u64,
+    }
+
+    fun foo(l: &u64): u64 {
+        *l
+    }
+
+    fun bar(r: &mut u64, i: u64) {
+        *r = i;
+    }
+
+    public fun test(s: &mut S, i: u64) {
+        let c = i / s.x;
+        let n = foo(&s.y);
+        while (c < n) {
+            bar(&mut s.z, c - 1);
+            c = c + 1;
+        }
+    }
+
+}
diff --git a/third_party/move/move-compiler-v2/tests/testsuite.rs b/third_party/move/move-compiler-v2/tests/testsuite.rs
index 1c45527e17009..65f9c0597fb1b 100644
--- a/third_party/move/move-compiler-v2/tests/testsuite.rs
+++ b/third_party/move/move-compiler-v2/tests/testsuite.rs
@@ -726,6 +726,18 @@ const TEST_CONFIGS: Lazy<BTreeMap<&str, TestConfig>> = Lazy::new(|| {
             dump_bytecode: DumpLevel::EndStage,
             dump_bytecode_filter: None,
         },
+        TestConfig {
+            name: "eager-pushes",
+            runner: |p| run_test(p, get_config_by_name("eager-pushes")),
+            include: vec!["/eager-pushes/"],
+            exclude: vec![],
+            exp_suffix: None,
+            options: opts.clone(),
+            stop_after: StopAfter::FileFormat,
+            dump_ast: DumpLevel::None,
+            dump_bytecode: DumpLevel::EndStage,
+            dump_bytecode_filter: None,
+        },
     ];
     configs.into_iter().map(|c| (c.name, c)).collect()
 });