Make AsmAddress producing methods static

This is an intermediate step towards breaking the circular dependency
between the assembler and target lowering classes, by ensuring
AsmAddress can be created from its argument without requiring direct
access to target class member fields.

Bug: b/192890685
Change-Id: I541efec4a58dc406f17b30d477075d63cdc11e28
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/55788
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Sean Risser <srisser@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/third_party/subzero/src/IceInstX8632.cpp b/third_party/subzero/src/IceInstX8632.cpp
index 797327a..29bef3b 100644
--- a/third_party/subzero/src/IceInstX8632.cpp
+++ b/third_party/subzero/src/IceInstX8632.cpp
@@ -527,11 +527,11 @@
     if (Var->hasReg()) {
       Asm->call(Traits::getEncodedGPR(Var->getRegNum()));
     } else {
-      Asm->call(Target->stackVarToAsmAddress(Var));
+      Asm->call(Target->stackVarToAsmAddress(Var, Target));
     }
   } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(CallTarget)) {
     assert(Mem->getSegmentRegister() == X86OperandMem::DefaultSegment);
-    Asm->call(Mem->toAsmAddress(Asm, Target));
+    Asm->call(Mem->toAsmAddress(Mem, Asm, Target));
   } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(CallTarget)) {
     Asm->call(CR);
   } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(CallTarget)) {
@@ -584,12 +584,12 @@
       GPRRegister VarReg = Traits::getEncodedGPR(Var->getRegNum());
       (Asm->*(Emitter.Reg))(Ty, VarReg);
     } else {
-      AsmAddress StackAddr(Target->stackVarToAsmAddress(Var));
+      AsmAddress StackAddr(Target->stackVarToAsmAddress(Var, Target));
       (Asm->*(Emitter.Addr))(Ty, StackAddr);
     }
   } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Op)) {
     Mem->emitSegmentOverride(Asm);
-    (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm, Target));
+    (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Mem, Asm, Target));
   } else {
     llvm_unreachable("Unexpected operand type");
   }
@@ -612,13 +612,13 @@
                                : Traits::getEncodedGPR(SrcVar->getRegNum());
       (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
     } else {
-      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar);
+      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar, Target);
       (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr);
     }
   } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Src)) {
     Mem->emitSegmentOverride(Asm);
     (Asm->*(Emitter.GPRAddr))(Ty, VarReg,
-                              Mem->toAsmAddress(Asm, Target, IsLea));
+                              Mem->toAsmAddress(Mem, Asm, Target, IsLea));
   } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
     (Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Imm->getValue()));
   } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
@@ -629,7 +629,7 @@
     AssemblerFixup *Fixup = Asm->createFixup(FixupKind, Reloc);
     (Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Fixup));
   } else if (const auto *Split = llvm::dyn_cast<VariableSplit>(Src)) {
-    (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func));
+    (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Split, Func));
   } else {
     llvm_unreachable("Unexpected operand type");
   }
@@ -662,15 +662,16 @@
   auto *Target = InstX86Base::getTarget(Func);
   if (const auto *Op0Var = llvm::dyn_cast<Variable>(Op0)) {
     assert(!Op0Var->hasReg());
-    AsmAddress StackAddr(Target->stackVarToAsmAddress(Op0Var));
+    AsmAddress StackAddr(Target->stackVarToAsmAddress(Op0Var, Target));
     emitIASAddrOpTyGPR(Func, Ty, StackAddr, Op1, Emitter);
   } else if (const auto *Op0Mem = llvm::dyn_cast<X86OperandMem>(Op0)) {
     Assembler *Asm = Func->getAssembler<Assembler>();
     Op0Mem->emitSegmentOverride(Asm);
-    emitIASAddrOpTyGPR(Func, Ty, Op0Mem->toAsmAddress(Asm, Target), Op1,
+    emitIASAddrOpTyGPR(Func, Ty, Op0Mem->toAsmAddress(Op0Mem, Asm, Target), Op1,
                        Emitter);
   } else if (const auto *Split = llvm::dyn_cast<VariableSplit>(Op0)) {
-    emitIASAddrOpTyGPR(Func, Ty, Split->toAsmAddress(Func), Op1, Emitter);
+    emitIASAddrOpTyGPR(Func, Ty, Split->toAsmAddress(Split, Func), Op1,
+                       Emitter);
   } else {
     llvm_unreachable("Unexpected operand type");
   }
@@ -729,12 +730,12 @@
       XmmRegister SrcReg = Traits::getEncodedXmm(SrcVar->getRegNum());
       (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg);
     } else {
-      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar);
+      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar, Target);
       (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr);
     }
   } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Src)) {
     assert(Mem->getSegmentRegister() == X86OperandMem::DefaultSegment);
-    (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm, Target));
+    (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Mem, Asm, Target));
   } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
     (Asm->*(Emitter.XmmImm))(Ty, VarReg, AssemblerImmediate(Imm->getValue()));
   } else {
@@ -753,15 +754,14 @@
       XmmRegister SrcReg = Traits::getEncodedXmm(SrcVar->getRegNum());
       (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg);
     } else {
-      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar);
+      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar, Target);
       (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr);
     }
   } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Src)) {
     assert(Mem->getSegmentRegister() == X86OperandMem::DefaultSegment);
-    (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm, Target));
+    (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Mem, Asm, Target));
   } else if (const auto *Imm = llvm::dyn_cast<Constant>(Src)) {
-    (Asm->*(Emitter.XmmAddr))(Ty, VarReg,
-                              AsmAddress::ofConstPool(Asm, Imm));
+    (Asm->*(Emitter.XmmAddr))(Ty, VarReg, AsmAddress::ofConstPool(Asm, Imm));
   } else {
     llvm_unreachable("Unexpected operand type");
   }
@@ -781,13 +781,13 @@
       SReg_t SrcReg = srcEnc(SrcVar->getRegNum());
       (Asm->*(Emitter.RegReg))(DestTy, DestReg, SrcTy, SrcReg);
     } else {
-      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar);
+      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar, Target);
       (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy, SrcStackAddr);
     }
   } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Src)) {
     Mem->emitSegmentOverride(Asm);
     (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy,
-                              Mem->toAsmAddress(Asm, Target));
+                              Mem->toAsmAddress(Mem, Asm, Target));
   } else {
     llvm_unreachable("Unexpected operand type");
   }
@@ -810,13 +810,13 @@
       SReg_t SrcReg = srcEnc(SrcVar->getRegNum());
       (Asm->*(Emitter.RegRegImm))(DispatchTy, DestReg, SrcReg, Imm);
     } else {
-      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar);
+      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar, Target);
       (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, SrcStackAddr, Imm);
     }
   } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Src0)) {
     Mem->emitSegmentOverride(Asm);
     (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg,
-                                 Mem->toAsmAddress(Asm, Target), Imm);
+                                 Mem->toAsmAddress(Mem, Asm, Target), Imm);
   } else {
     llvm_unreachable("Unexpected operand type");
   }
@@ -833,17 +833,18 @@
         (Asm->*(Emitter.XmmXmm))(DestReg,
                                  Traits::getEncodedXmm(SrcVar->getRegNum()));
       } else {
-        AsmAddress StackAddr(Target->stackVarToAsmAddress(SrcVar));
+        AsmAddress StackAddr(Target->stackVarToAsmAddress(SrcVar, Target));
         (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr);
       }
     } else if (const auto *SrcMem = llvm::dyn_cast<X86OperandMem>(Src)) {
       assert(SrcMem->getSegmentRegister() == X86OperandMem::DefaultSegment);
-      (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm, Target));
+      (Asm->*(Emitter.XmmAddr))(DestReg,
+                                SrcMem->toAsmAddress(SrcMem, Asm, Target));
     } else {
       llvm_unreachable("Unexpected operand type");
     }
   } else {
-    AsmAddress StackAddr(Target->stackVarToAsmAddress(Dest));
+    AsmAddress StackAddr(Target->stackVarToAsmAddress(Dest, Target));
     // Src must be a register in this case.
     const auto *SrcVar = llvm::cast<Variable>(Src);
     assert(SrcVar->hasReg());
@@ -1308,13 +1309,13 @@
     } else {
       Asm->cmov(SrcTy, Condition,
                 Traits::getEncodedGPR(this->getDest()->getRegNum()),
-                Target->stackVarToAsmAddress(SrcVar));
+                Target->stackVarToAsmAddress(SrcVar, Target));
     }
   } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Src)) {
     assert(Mem->getSegmentRegister() == X86OperandMem::DefaultSegment);
     Asm->cmov(SrcTy, Condition,
               Traits::getEncodedGPR(this->getDest()->getRegNum()),
-              Mem->toAsmAddress(Asm, Target));
+              Mem->toAsmAddress(Mem, Asm, Target));
   } else {
     llvm_unreachable("Unexpected operand type");
   }
@@ -1361,7 +1362,7 @@
                Traits::getEncodedXmm(this->getDest()->getRegNum()),
                Traits::getEncodedXmm(SrcVar->getRegNum()), Condition);
   } else {
-    AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar);
+    AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar, Target);
     Asm->cmpps(this->getDest()->getType(),
                Traits::getEncodedXmm(this->getDest()->getRegNum()),
                SrcStackAddr, Condition);
@@ -1404,7 +1405,7 @@
   auto *Target = InstX86Base::getTarget(Func);
   const auto Mem = llvm::cast<X86OperandMem>(this->getSrc(0));
   assert(Mem->getSegmentRegister() == X86OperandMem::DefaultSegment);
-  const AsmAddress Addr = Mem->toAsmAddress(Asm, Target);
+  const AsmAddress Addr = Mem->toAsmAddress(Mem, Asm, Target);
   const auto *VarReg = llvm::cast<Variable>(this->getSrc(2));
   assert(VarReg->hasReg());
   const GPRRegister Reg = Traits::getEncodedGPR(VarReg->getRegNum());
@@ -1442,7 +1443,7 @@
   const auto Mem = llvm::cast<X86OperandMem>(this->getSrc(0));
   assert(Mem->getSegmentRegister() == X86OperandMem::DefaultSegment);
   auto *Target = InstX86Base::getTarget(Func);
-  const AsmAddress Addr = Mem->toAsmAddress(Asm, Target);
+  const AsmAddress Addr = Mem->toAsmAddress(Mem, Asm, Target);
   Asm->cmpxchg8b(Addr, this->Locked);
 }
 
@@ -1794,12 +1795,12 @@
     auto *Target = InstX86Base::getTarget(Func);
     if (const auto *DestVar = llvm::dyn_cast<Variable>(Dest)) {
       assert(!DestVar->hasReg());
-      AsmAddress StackAddr(Target->stackVarToAsmAddress(DestVar));
+      AsmAddress StackAddr(Target->stackVarToAsmAddress(DestVar, Target));
       Asm->movss(DestTy, StackAddr, SrcReg);
     } else {
       const auto DestMem = llvm::cast<X86OperandMem>(Dest);
       assert(DestMem->getSegmentRegister() == X86OperandMem::DefaultSegment);
-      Asm->movss(DestTy, DestMem->toAsmAddress(Asm, Target), SrcReg);
+      Asm->movss(DestTy, DestMem->toAsmAddress(DestMem, Asm, Target), SrcReg);
     }
     return;
   } else {
@@ -1841,7 +1842,7 @@
   assert(DestMem->getSegmentRegister() == X86OperandMem::DefaultSegment);
   assert(SrcVar->hasReg());
   auto *Target = InstX86Base::getTarget(Func);
-  Asm->movups(DestMem->toAsmAddress(Asm, Target),
+  Asm->movups(DestMem->toAsmAddress(DestMem, Asm, Target),
               Traits::getEncodedXmm(SrcVar->getRegNum()));
 }
 
@@ -1878,7 +1879,7 @@
   assert(DestMem->getSegmentRegister() == X86OperandMem::DefaultSegment);
   assert(SrcVar->hasReg());
   auto *Target = InstX86Base::getTarget(Func);
-  Asm->movq(DestMem->toAsmAddress(Asm, Target),
+  Asm->movq(DestMem->toAsmAddress(DestMem, Asm, Target),
             Traits::getEncodedXmm(SrcVar->getRegNum()));
 }
 
@@ -1915,7 +1916,7 @@
   assert(DestMem->getSegmentRegister() == X86OperandMem::DefaultSegment);
   assert(SrcVar->hasReg());
   auto *Target = InstX86Base::getTarget(Func);
-  Asm->movd(SrcVar->getType(), DestMem->toAsmAddress(Asm, Target),
+  Asm->movd(SrcVar->getType(), DestMem->toAsmAddress(DestMem, Asm, Target),
             Traits::getEncodedXmm(SrcVar->getRegNum()));
 }
 
@@ -2067,7 +2068,7 @@
   } else {
     // Dest must be Stack and Src *could* be a register. Use Src's type to
     // decide on the emitters.
-    AsmAddress StackAddr(Target->stackVarToAsmAddress(Dest));
+    AsmAddress StackAddr(Target->stackVarToAsmAddress(Dest, Target));
     if (isScalarFloatingType(SrcTy)) {
       // Src must be a register.
       const auto *SrcVar = llvm::cast<Variable>(Src);
@@ -2133,7 +2134,7 @@
         Asm->movd(SrcVar->getType(), DestReg,
                   Traits::getEncodedGPR(SrcVar->getRegNum()));
       } else {
-        AsmAddress StackAddr(Target->stackVarToAsmAddress(SrcVar));
+        AsmAddress StackAddr(Target->stackVarToAsmAddress(SrcVar, Target));
         Asm->movd(SrcVar->getType(), DestReg, StackAddr);
       }
     } else {
@@ -2148,7 +2149,7 @@
         Asm->movd(Dest->getType(), Traits::getEncodedGPR(Dest->getRegNum()),
                   SrcReg);
       } else {
-        AsmAddress StackAddr(Target->stackVarToAsmAddress(Dest));
+        AsmAddress StackAddr(Target->stackVarToAsmAddress(Dest, Target));
         Asm->movd(Dest->getType(), StackAddr, SrcReg);
       }
     }
@@ -2156,7 +2157,7 @@
     assert(Dest->hasReg());
     XmmRegister DestReg = Traits::getEncodedXmm(Dest->getRegNum());
     auto *Mem = llvm::cast<X86OperandMem>(this->getSrc(0));
-    Asm->movd(Mem->getType(), DestReg, Mem->toAsmAddress(Asm, Target));
+    Asm->movd(Mem->getType(), DestReg, Mem->toAsmAddress(Mem, Asm, Target));
   }
 }
 
@@ -2324,12 +2325,12 @@
       Asm->movss(Ty, StackSlot, Traits::getEncodedXmm(Var->getRegNum()));
       Asm->fld(Ty, StackSlot);
     } else {
-      AsmAddress StackAddr(Target->stackVarToAsmAddress(Var));
+      AsmAddress StackAddr(Target->stackVarToAsmAddress(Var, Target));
       Asm->fld(Ty, StackAddr);
     }
   } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Src)) {
     assert(Mem->getSegmentRegister() == X86OperandMem::DefaultSegment);
-    Asm->fld(Ty, Mem->toAsmAddress(Asm, Target));
+    Asm->fld(Ty, Mem->toAsmAddress(Mem, Asm, Target));
   } else if (const auto *Imm = llvm::dyn_cast<Constant>(Src)) {
     Asm->fld(Ty, AsmAddress::ofConstPool(Asm, Imm));
   } else {
@@ -2397,7 +2398,7 @@
   auto *Target = InstX86Base::getTarget(Func);
   Type Ty = Dest->getType();
   if (!Dest->hasReg()) {
-    AsmAddress StackAddr(Target->stackVarToAsmAddress(Dest));
+    AsmAddress StackAddr(Target->stackVarToAsmAddress(Dest, Target));
     Asm->fstp(Ty, StackAddr);
   } else {
     // Dest is a physical (xmm) register, so st(0) needs to go through memory.
@@ -2552,7 +2553,7 @@
     Asm->popl(Traits::getEncodedGPR(this->getDest()->getRegNum()));
   } else {
     auto *Target = InstX86Base::getTarget(Func);
-    Asm->popl(Target->stackVarToAsmAddress(this->getDest()));
+    Asm->popl(Target->stackVarToAsmAddress(this->getDest(), Target));
   }
 }
 
@@ -2644,7 +2645,8 @@
     Asm->setcc(Condition,
                Traits::getEncodedByteReg(this->getDest()->getRegNum()));
   else
-    Asm->setcc(Condition, Target->stackVarToAsmAddress(this->getDest()));
+    Asm->setcc(Condition,
+               Target->stackVarToAsmAddress(this->getDest(), Target));
   return;
 }
 
@@ -2679,7 +2681,7 @@
   const auto Mem = llvm::cast<X86OperandMem>(this->getSrc(0));
   assert(Mem->getSegmentRegister() == X86OperandMem::DefaultSegment);
   auto *Target = InstX86Base::getTarget(Func);
-  const AsmAddress Addr = Mem->toAsmAddress(Asm, Target);
+  const AsmAddress Addr = Mem->toAsmAddress(Mem, Asm, Target);
   const auto *VarReg = llvm::cast<Variable>(this->getSrc(1));
   assert(VarReg->hasReg());
   const GPRRegister Reg = Traits::getEncodedGPR(VarReg->getRegNum());
@@ -2728,7 +2730,7 @@
   const auto *Mem = llvm::cast<X86OperandMem>(this->getSrc(0));
   assert(Mem->getSegmentRegister() == X86OperandMem::DefaultSegment);
   auto *Target = InstX86Base::getTarget(Func);
-  const AsmAddress Addr = Mem->toAsmAddress(Asm, Target);
+  const AsmAddress Addr = Mem->toAsmAddress(Mem, Asm, Target);
   Asm->xchg(Ty, Addr, Reg1);
 }
 
@@ -3006,27 +3008,27 @@
 }
 
 AsmAddress TargetX8632Traits::X86OperandMem::toAsmAddress(
-    TargetX8632Traits::Assembler *Asm,
-    const Ice::TargetLowering *TargetLowering, bool /*IsLeaAddr*/) const {
+    const X86OperandMem *Mem, TargetX8632Traits::Assembler *Asm,
+    const Ice::TargetLowering *TargetLowering, bool /*IsLeaAddr*/) {
   const auto *Target =
       static_cast<const ::Ice::X8632::TargetX8632 *>(TargetLowering);
-  validateMemOperandPIC(this);
+  validateMemOperandPIC(Mem);
   int32_t Disp = 0;
-  if (getBase() && getBase()->isRematerializable()) {
-    Disp += getRematerializableOffset(getBase(), Target);
+  if (Mem->getBase() && Mem->getBase()->isRematerializable()) {
+    Disp += getRematerializableOffset(Mem->getBase(), Target);
   }
   // The index should never be rematerializable.  But if we ever allow it, then
   // we should make sure the rematerialization offset is shifted by the Shift
   // value.
-  if (getIndex())
-    assert(!getIndex()->isRematerializable());
+  if (Mem->getIndex())
+    assert(!Mem->getIndex()->isRematerializable());
   AssemblerFixup *Fixup = nullptr;
   // Determine the offset (is it relocatable?)
-  if (getOffset()) {
-    if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) {
+  if (Mem->getOffset()) {
+    if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(Mem->getOffset())) {
       Disp += static_cast<int32_t>(CI->getValue());
     } else if (const auto CR =
-                   llvm::dyn_cast<ConstantRelocatable>(getOffset())) {
+                   llvm::dyn_cast<ConstantRelocatable>(Mem->getOffset())) {
       Disp += CR->getOffset();
       Fixup = Asm->createFixup(Target->getAbsFixup(), CR);
     } else {
@@ -3035,29 +3037,28 @@
   }
 
   // Now convert to the various possible forms.
-  if (getBase() && getIndex()) {
-    return AsmAddress(getEncodedGPR(getBase()->getRegNum()),
-                      getEncodedGPR(getIndex()->getRegNum()),
-                      X8632::Traits::ScaleFactor(getShift()), Disp, Fixup);
-  } else if (getBase()) {
-    return AsmAddress(getEncodedGPR(getBase()->getRegNum()),
-                                     Disp, Fixup);
-  } else if (getIndex()) {
-    return AsmAddress(getEncodedGPR(getIndex()->getRegNum()),
-                                     X8632::Traits::ScaleFactor(getShift()),
-                                     Disp, Fixup);
+  if (Mem->getBase() && Mem->getIndex()) {
+    return AsmAddress(getEncodedGPR(Mem->getBase()->getRegNum()),
+                      getEncodedGPR(Mem->getIndex()->getRegNum()),
+                      X8632::Traits::ScaleFactor(Mem->getShift()), Disp, Fixup);
+  } else if (Mem->getBase()) {
+    return AsmAddress(getEncodedGPR(Mem->getBase()->getRegNum()), Disp, Fixup);
+  } else if (Mem->getIndex()) {
+    return AsmAddress(getEncodedGPR(Mem->getIndex()->getRegNum()),
+                      X8632::Traits::ScaleFactor(Mem->getShift()), Disp, Fixup);
   } else {
     return AsmAddress(Disp, Fixup);
   }
 }
 
 AsmAddress
-TargetX8632Traits::VariableSplit::toAsmAddress(const Cfg *Func) const {
-  assert(!Var->hasReg());
+TargetX8632Traits::VariableSplit::toAsmAddress(const VariableSplit *Split,
+                                               const Cfg *Func) {
+  assert(!Split->getVar()->hasReg());
   const ::Ice::TargetLowering *Target = Func->getTarget();
-  int32_t Offset = Var->getStackOffset() + getOffset();
-  return AsmAddress(getEncodedGPR(Target->getFrameOrStackReg()),
-                                   Offset, AssemblerFixup::NoFixup);
+  int32_t Offset = Split->getVar()->getStackOffset() + Split->getOffset();
+  return AsmAddress(getEncodedGPR(Target->getFrameOrStackReg()), Offset,
+                    AssemblerFixup::NoFixup);
 }
 
 void TargetX8632Traits::VariableSplit::emit(const Cfg *Func) const {
diff --git a/third_party/subzero/src/IceInstX8664.cpp b/third_party/subzero/src/IceInstX8664.cpp
index 9a04fdf..4f5a53a 100644
--- a/third_party/subzero/src/IceInstX8664.cpp
+++ b/third_party/subzero/src/IceInstX8664.cpp
@@ -527,11 +527,11 @@
     if (Var->hasReg()) {
       Asm->call(Traits::getEncodedGPR(Var->getRegNum()));
     } else {
-      Asm->call(Target->stackVarToAsmAddress(Var));
+      Asm->call(Target->stackVarToAsmAddress(Var, Target));
     }
   } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(CallTarget)) {
     assert(Mem->getSegmentRegister() == X86OperandMem::DefaultSegment);
-    Asm->call(Mem->toAsmAddress(Asm, Target));
+    Asm->call(Mem->toAsmAddress(Mem, Asm, Target));
   } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(CallTarget)) {
     Asm->call(CR);
   } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(CallTarget)) {
@@ -584,12 +584,12 @@
       GPRRegister VarReg = Traits::getEncodedGPR(Var->getRegNum());
       (Asm->*(Emitter.Reg))(Ty, VarReg);
     } else {
-      AsmAddress StackAddr(Target->stackVarToAsmAddress(Var));
+      AsmAddress StackAddr(Target->stackVarToAsmAddress(Var, Target));
       (Asm->*(Emitter.Addr))(Ty, StackAddr);
     }
   } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Op)) {
     Mem->emitSegmentOverride(Asm);
-    (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm, Target));
+    (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Mem, Asm, Target));
   } else {
     llvm_unreachable("Unexpected operand type");
   }
@@ -612,13 +612,13 @@
                                : Traits::getEncodedGPR(SrcVar->getRegNum());
       (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
     } else {
-      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar);
+      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar, Target);
       (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr);
     }
   } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Src)) {
     Mem->emitSegmentOverride(Asm);
     (Asm->*(Emitter.GPRAddr))(Ty, VarReg,
-                              Mem->toAsmAddress(Asm, Target, IsLea));
+                              Mem->toAsmAddress(Mem, Asm, Target, IsLea));
   } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
     (Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Imm->getValue()));
   } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger64>(Src)) {
@@ -631,8 +631,6 @@
                                : Traits::TargetLowering::getAbsFixup();
     AssemblerFixup *Fixup = Asm->createFixup(FixupKind, Reloc);
     (Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Fixup));
-  } else if (const auto *Split = llvm::dyn_cast<VariableSplit>(Src)) {
-    (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func));
   } else {
     llvm_unreachable("Unexpected operand type");
   }
@@ -668,15 +666,13 @@
   auto *Target = InstX86Base::getTarget(Func);
   if (const auto *Op0Var = llvm::dyn_cast<Variable>(Op0)) {
     assert(!Op0Var->hasReg());
-    AsmAddress StackAddr(Target->stackVarToAsmAddress(Op0Var));
+    AsmAddress StackAddr(Target->stackVarToAsmAddress(Op0Var, Target));
     emitIASAddrOpTyGPR(Func, Ty, StackAddr, Op1, Emitter);
   } else if (const auto *Op0Mem = llvm::dyn_cast<X86OperandMem>(Op0)) {
     Assembler *Asm = Func->getAssembler<Assembler>();
     Op0Mem->emitSegmentOverride(Asm);
-    emitIASAddrOpTyGPR(Func, Ty, Op0Mem->toAsmAddress(Asm, Target), Op1,
+    emitIASAddrOpTyGPR(Func, Ty, Op0Mem->toAsmAddress(Op0Mem, Asm, Target), Op1,
                        Emitter);
-  } else if (const auto *Split = llvm::dyn_cast<VariableSplit>(Op0)) {
-    emitIASAddrOpTyGPR(Func, Ty, Split->toAsmAddress(Func), Op1, Emitter);
   } else {
     llvm_unreachable("Unexpected operand type");
   }
@@ -738,12 +734,12 @@
       XmmRegister SrcReg = Traits::getEncodedXmm(SrcVar->getRegNum());
       (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg);
     } else {
-      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar);
+      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar, Target);
       (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr);
     }
   } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Src)) {
     assert(Mem->getSegmentRegister() == X86OperandMem::DefaultSegment);
-    (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm, Target));
+    (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Mem, Asm, Target));
   } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
     (Asm->*(Emitter.XmmImm))(Ty, VarReg, AssemblerImmediate(Imm->getValue()));
   } else {
@@ -762,15 +758,14 @@
       XmmRegister SrcReg = Traits::getEncodedXmm(SrcVar->getRegNum());
       (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg);
     } else {
-      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar);
+      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar, Target);
       (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr);
     }
   } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Src)) {
     assert(Mem->getSegmentRegister() == X86OperandMem::DefaultSegment);
-    (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm, Target));
+    (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Mem, Asm, Target));
   } else if (const auto *Imm = llvm::dyn_cast<Constant>(Src)) {
-    (Asm->*(Emitter.XmmAddr))(Ty, VarReg,
-                              AsmAddress::ofConstPool(Asm, Imm));
+    (Asm->*(Emitter.XmmAddr))(Ty, VarReg, AsmAddress::ofConstPool(Asm, Imm));
   } else {
     llvm_unreachable("Unexpected operand type");
   }
@@ -790,13 +785,13 @@
       SReg_t SrcReg = srcEnc(SrcVar->getRegNum());
       (Asm->*(Emitter.RegReg))(DestTy, DestReg, SrcTy, SrcReg);
     } else {
-      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar);
+      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar, Target);
       (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy, SrcStackAddr);
     }
   } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Src)) {
     Mem->emitSegmentOverride(Asm);
     (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy,
-                              Mem->toAsmAddress(Asm, Target));
+                              Mem->toAsmAddress(Mem, Asm, Target));
   } else {
     llvm_unreachable("Unexpected operand type");
   }
@@ -819,13 +814,13 @@
       SReg_t SrcReg = srcEnc(SrcVar->getRegNum());
       (Asm->*(Emitter.RegRegImm))(DispatchTy, DestReg, SrcReg, Imm);
     } else {
-      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar);
+      AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar, Target);
       (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, SrcStackAddr, Imm);
     }
   } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Src0)) {
     Mem->emitSegmentOverride(Asm);
     (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg,
-                                 Mem->toAsmAddress(Asm, Target), Imm);
+                                 Mem->toAsmAddress(Mem, Asm, Target), Imm);
   } else {
     llvm_unreachable("Unexpected operand type");
   }
@@ -842,17 +837,18 @@
         (Asm->*(Emitter.XmmXmm))(DestReg,
                                  Traits::getEncodedXmm(SrcVar->getRegNum()));
       } else {
-        AsmAddress StackAddr(Target->stackVarToAsmAddress(SrcVar));
+        AsmAddress StackAddr(Target->stackVarToAsmAddress(SrcVar, Target));
         (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr);
       }
     } else if (const auto *SrcMem = llvm::dyn_cast<X86OperandMem>(Src)) {
       assert(SrcMem->getSegmentRegister() == X86OperandMem::DefaultSegment);
-      (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm, Target));
+      (Asm->*(Emitter.XmmAddr))(DestReg,
+                                SrcMem->toAsmAddress(SrcMem, Asm, Target));
     } else {
       llvm_unreachable("Unexpected operand type");
     }
   } else {
-    AsmAddress StackAddr(Target->stackVarToAsmAddress(Dest));
+    AsmAddress StackAddr(Target->stackVarToAsmAddress(Dest, Target));
     // Src must be a register in this case.
     const auto *SrcVar = llvm::cast<Variable>(Src);
     assert(SrcVar->hasReg());
@@ -1327,13 +1323,13 @@
     } else {
       Asm->cmov(SrcTy, Condition,
                 Traits::getEncodedGPR(this->getDest()->getRegNum()),
-                Target->stackVarToAsmAddress(SrcVar));
+                Target->stackVarToAsmAddress(SrcVar, Target));
     }
   } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Src)) {
     assert(Mem->getSegmentRegister() == X86OperandMem::DefaultSegment);
     Asm->cmov(SrcTy, Condition,
               Traits::getEncodedGPR(this->getDest()->getRegNum()),
-              Mem->toAsmAddress(Asm, Target));
+              Mem->toAsmAddress(Mem, Asm, Target));
   } else {
     llvm_unreachable("Unexpected operand type");
   }
@@ -1380,7 +1376,7 @@
                Traits::getEncodedXmm(this->getDest()->getRegNum()),
                Traits::getEncodedXmm(SrcVar->getRegNum()), Condition);
   } else {
-    AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar);
+    AsmAddress SrcStackAddr = Target->stackVarToAsmAddress(SrcVar, Target);
     Asm->cmpps(this->getDest()->getType(),
                Traits::getEncodedXmm(this->getDest()->getRegNum()),
                SrcStackAddr, Condition);
@@ -1423,7 +1419,7 @@
   auto *Target = InstX86Base::getTarget(Func);
   const auto Mem = llvm::cast<X86OperandMem>(this->getSrc(0));
   assert(Mem->getSegmentRegister() == X86OperandMem::DefaultSegment);
-  const AsmAddress Addr = Mem->toAsmAddress(Asm, Target);
+  const AsmAddress Addr = Mem->toAsmAddress(Mem, Asm, Target);
   const auto *VarReg = llvm::cast<Variable>(this->getSrc(2));
   assert(VarReg->hasReg());
   const GPRRegister Reg = Traits::getEncodedGPR(VarReg->getRegNum());
@@ -1461,7 +1457,7 @@
   const auto Mem = llvm::cast<X86OperandMem>(this->getSrc(0));
   assert(Mem->getSegmentRegister() == X86OperandMem::DefaultSegment);
   auto *Target = InstX86Base::getTarget(Func);
-  const AsmAddress Addr = Mem->toAsmAddress(Asm, Target);
+  const AsmAddress Addr = Mem->toAsmAddress(Mem, Asm, Target);
   Asm->cmpxchg8b(Addr, this->Locked);
 }
 
@@ -1813,12 +1809,12 @@
     auto *Target = InstX86Base::getTarget(Func);
     if (const auto *DestVar = llvm::dyn_cast<Variable>(Dest)) {
       assert(!DestVar->hasReg());
-      AsmAddress StackAddr(Target->stackVarToAsmAddress(DestVar));
+      AsmAddress StackAddr(Target->stackVarToAsmAddress(DestVar, Target));
       Asm->movss(DestTy, StackAddr, SrcReg);
     } else {
       const auto DestMem = llvm::cast<X86OperandMem>(Dest);
       assert(DestMem->getSegmentRegister() == X86OperandMem::DefaultSegment);
-      Asm->movss(DestTy, DestMem->toAsmAddress(Asm, Target), SrcReg);
+      Asm->movss(DestTy, DestMem->toAsmAddress(DestMem, Asm, Target), SrcReg);
     }
     return;
   } else {
@@ -1860,7 +1856,7 @@
   assert(DestMem->getSegmentRegister() == X86OperandMem::DefaultSegment);
   assert(SrcVar->hasReg());
   auto *Target = InstX86Base::getTarget(Func);
-  Asm->movups(DestMem->toAsmAddress(Asm, Target),
+  Asm->movups(DestMem->toAsmAddress(DestMem, Asm, Target),
               Traits::getEncodedXmm(SrcVar->getRegNum()));
 }
 
@@ -1897,7 +1893,7 @@
   assert(DestMem->getSegmentRegister() == X86OperandMem::DefaultSegment);
   assert(SrcVar->hasReg());
   auto *Target = InstX86Base::getTarget(Func);
-  Asm->movq(DestMem->toAsmAddress(Asm, Target),
+  Asm->movq(DestMem->toAsmAddress(DestMem, Asm, Target),
             Traits::getEncodedXmm(SrcVar->getRegNum()));
 }
 
@@ -1934,7 +1930,7 @@
   assert(DestMem->getSegmentRegister() == X86OperandMem::DefaultSegment);
   assert(SrcVar->hasReg());
   auto *Target = InstX86Base::getTarget(Func);
-  Asm->movd(SrcVar->getType(), DestMem->toAsmAddress(Asm, Target),
+  Asm->movd(SrcVar->getType(), DestMem->toAsmAddress(DestMem, Asm, Target),
             Traits::getEncodedXmm(SrcVar->getRegNum()));
 }
 
@@ -2100,7 +2096,7 @@
   } else {
     // Dest must be Stack and Src *could* be a register. Use Src's type to
     // decide on the emitters.
-    AsmAddress StackAddr(Target->stackVarToAsmAddress(Dest));
+    AsmAddress StackAddr(Target->stackVarToAsmAddress(Dest, Target));
     if (isScalarFloatingType(SrcTy)) {
       // Src must be a register.
       const auto *SrcVar = llvm::cast<Variable>(Src);
@@ -2166,7 +2162,7 @@
         Asm->movd(SrcVar->getType(), DestReg,
                   Traits::getEncodedGPR(SrcVar->getRegNum()));
       } else {
-        AsmAddress StackAddr(Target->stackVarToAsmAddress(SrcVar));
+        AsmAddress StackAddr(Target->stackVarToAsmAddress(SrcVar, Target));
         Asm->movd(SrcVar->getType(), DestReg, StackAddr);
       }
     } else {
@@ -2181,7 +2177,7 @@
         Asm->movd(Dest->getType(), Traits::getEncodedGPR(Dest->getRegNum()),
                   SrcReg);
       } else {
-        AsmAddress StackAddr(Target->stackVarToAsmAddress(Dest));
+        AsmAddress StackAddr(Target->stackVarToAsmAddress(Dest, Target));
         Asm->movd(Dest->getType(), StackAddr, SrcReg);
       }
     }
@@ -2189,7 +2185,7 @@
     assert(Dest->hasReg());
     XmmRegister DestReg = Traits::getEncodedXmm(Dest->getRegNum());
     auto *Mem = llvm::cast<X86OperandMem>(this->getSrc(0));
-    Asm->movd(Mem->getType(), DestReg, Mem->toAsmAddress(Asm, Target));
+    Asm->movd(Mem->getType(), DestReg, Mem->toAsmAddress(Mem, Asm, Target));
   }
 }
 
@@ -2494,7 +2490,7 @@
     Asm->popl(Traits::getEncodedGPR(this->getDest()->getRegNum()));
   } else {
     auto *Target = InstX86Base::getTarget(Func);
-    Asm->popl(Target->stackVarToAsmAddress(this->getDest()));
+    Asm->popl(Target->stackVarToAsmAddress(this->getDest(), Target));
   }
 }
 
@@ -2586,7 +2582,8 @@
     Asm->setcc(Condition,
                Traits::getEncodedByteReg(this->getDest()->getRegNum()));
   else
-    Asm->setcc(Condition, Target->stackVarToAsmAddress(this->getDest()));
+    Asm->setcc(Condition,
+               Target->stackVarToAsmAddress(this->getDest(), Target));
   return;
 }
 
@@ -2621,7 +2618,7 @@
   const auto Mem = llvm::cast<X86OperandMem>(this->getSrc(0));
   assert(Mem->getSegmentRegister() == X86OperandMem::DefaultSegment);
   auto *Target = InstX86Base::getTarget(Func);
-  const AsmAddress Addr = Mem->toAsmAddress(Asm, Target);
+  const AsmAddress Addr = Mem->toAsmAddress(Mem, Asm, Target);
   const auto *VarReg = llvm::cast<Variable>(this->getSrc(1));
   assert(VarReg->hasReg());
   const GPRRegister Reg = Traits::getEncodedGPR(VarReg->getRegNum());
@@ -2670,7 +2667,7 @@
   const auto *Mem = llvm::cast<X86OperandMem>(this->getSrc(0));
   assert(Mem->getSegmentRegister() == X86OperandMem::DefaultSegment);
   auto *Target = InstX86Base::getTarget(Func);
-  const AsmAddress Addr = Mem->toAsmAddress(Asm, Target);
+  const AsmAddress Addr = Mem->toAsmAddress(Mem, Asm, Target);
   Asm->xchg(Ty, Addr, Reg1);
 }
 
@@ -2932,28 +2929,27 @@
 }
 
 AsmAddress TargetX8664Traits::X86OperandMem::toAsmAddress(
-    TargetX8664Traits::Assembler *Asm,
-    const Ice::TargetLowering *TargetLowering, bool IsLeaAddr) const {
+    const X86OperandMem *Mem, TargetX8664Traits::Assembler *Asm,
+    const Ice::TargetLowering *TargetLowering, bool IsLeaAddr) {
   (void)IsLeaAddr;
   const auto *Target =
       static_cast<const ::Ice::X8664::TargetX8664 *>(TargetLowering);
   int32_t Disp = 0;
-  if (getBase() && getBase()->isRematerializable()) {
-    Disp += getRematerializableOffset(getBase(), Target);
+  if (Mem->getBase() && Mem->getBase()->isRematerializable()) {
+    Disp += getRematerializableOffset(Mem->getBase(), Target);
   }
-  if (getIndex() != nullptr) {
-    assert(!getIndex()->isRematerializable());
-  }
+  assert(!Mem->getIndex() || !Mem->getIndex()->isRematerializable());
 
   AssemblerFixup *Fixup = nullptr;
   // Determine the offset (is it relocatable?)
-  if (getOffset() != nullptr) {
-    if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) {
+  if (Mem->getOffset() != nullptr) {
+    if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(Mem->getOffset())) {
       Disp += static_cast<int32_t>(CI->getValue());
     } else if (const auto *CR =
-                   llvm::dyn_cast<ConstantRelocatable>(getOffset())) {
+                   llvm::dyn_cast<ConstantRelocatable>(Mem->getOffset())) {
       const auto FixupKind =
-          (getBase() != nullptr || getIndex() != nullptr) ? FK_Abs : FK_PcRel;
+          (Mem->getBase() != nullptr || Mem->getIndex() != nullptr) ? FK_Abs
+                                                                    : FK_PcRel;
       const RelocOffsetT DispAdjustment = FixupKind == FK_PcRel ? 4 : 0;
       Fixup = Asm->createFixup(FixupKind, CR);
       Fixup->set_addend(-DispAdjustment);
@@ -2964,22 +2960,19 @@
   }
 
   // Now convert to the various possible forms.
-  if (getBase() && getIndex()) {
-    return AsmAddress(getEncodedGPR(getBase()->getRegNum()),
-                                  getEncodedGPR(getIndex()->getRegNum()),
-                                  X8664::Traits::ScaleFactor(getShift()), Disp,
-                                  Fixup);
+  if (Mem->getBase() && Mem->getIndex()) {
+    return AsmAddress(getEncodedGPR(Mem->getBase()->getRegNum()),
+                      getEncodedGPR(Mem->getIndex()->getRegNum()),
+                      X8664::Traits::ScaleFactor(Mem->getShift()), Disp, Fixup);
   }
 
-  if (getBase()) {
-    return AsmAddress(getEncodedGPR(getBase()->getRegNum()), Disp,
-                                  Fixup);
+  if (Mem->getBase()) {
+    return AsmAddress(getEncodedGPR(Mem->getBase()->getRegNum()), Disp, Fixup);
   }
 
-  if (getIndex()) {
-    return AsmAddress(getEncodedGPR(getIndex()->getRegNum()),
-                                  X8664::Traits::ScaleFactor(getShift()), Disp,
-                                  Fixup);
+  if (Mem->getIndex()) {
+    return AsmAddress(getEncodedGPR(Mem->getIndex()->getRegNum()),
+                      X8664::Traits::ScaleFactor(Mem->getShift()), Disp, Fixup);
   }
 
   if (Fixup == nullptr) {
@@ -2989,48 +2982,5 @@
   return AsmAddress::RipRelative(Disp, Fixup);
 }
 
-AsmAddress
-TargetX8664Traits::VariableSplit::toAsmAddress(const Cfg *Func) const {
-  assert(!Var->hasReg());
-  const ::Ice::TargetLowering *Target = Func->getTarget();
-  int32_t Offset = Var->getStackOffset() + getOffset();
-  return AsmAddress(getEncodedGPR(Target->getFrameOrStackReg()),
-                                Offset, AssemblerFixup::NoFixup);
-}
-
-void TargetX8664Traits::VariableSplit::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(!Var->hasReg());
-  // The following is copied/adapted from TargetX8664::emitVariable().
-  const ::Ice::TargetLowering *Target = Func->getTarget();
-  constexpr Type Ty = IceType_i32;
-  int32_t Offset = Var->getStackOffset() + getOffset();
-  if (Offset)
-    Str << Offset;
-  Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")";
-}
-
-void TargetX8664Traits::VariableSplit::dump(const Cfg *Func,
-                                            Ostream &Str) const {
-  if (!BuildDefs::dump())
-    return;
-  switch (Part) {
-  case Low:
-    Str << "low";
-    break;
-  case High:
-    Str << "high";
-    break;
-  }
-  Str << "(";
-  if (Func)
-    Var->dump(Func);
-  else
-    Var->dump(Str);
-  Str << ")";
-}
-
 } // namespace X8664
 } // end of namespace Ice
diff --git a/third_party/subzero/src/IceInstX8664.h b/third_party/subzero/src/IceInstX8664.h
index 22946ae..5e29545 100644
--- a/third_party/subzero/src/IceInstX8664.h
+++ b/third_party/subzero/src/IceInstX8664.h
@@ -37,7 +37,6 @@
 using AsmAddress = typename Traits::AsmAddress;
 using X86Operand = typename Traits::X86Operand;
 using X86OperandMem = typename Traits::X86OperandMem;
-using VariableSplit = typename Traits::VariableSplit;
 
 using GPRRegister = typename Traits::RegisterSet::GPRRegister;
 using RegisterSet = typename Traits::RegisterSet;
diff --git a/third_party/subzero/src/IceTargetLoweringX8632.cpp b/third_party/subzero/src/IceTargetLoweringX8632.cpp
index a6c89cb..abf47ae 100644
--- a/third_party/subzero/src/IceTargetLoweringX8632.cpp
+++ b/third_party/subzero/src/IceTargetLoweringX8632.cpp
@@ -871,13 +871,14 @@
   Str << "(%" << getRegName(BaseRegNum, FrameSPTy) << ")";
 }
 
-AsmAddress TargetX8632::stackVarToAsmAddress(const Variable *Var) const {
+AsmAddress TargetX8632::stackVarToAsmAddress(const Variable *Var,
+                                             const TargetX8632 *Target) {
   if (Var->hasReg())
     llvm::report_fatal_error("Stack Variable has a register assigned");
   if (Var->mustHaveReg()) {
     llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName() +
                              ") has no register assigned - function " +
-                             Func->getFunctionName());
+                             Target->getFunc()->getFunctionName());
   }
   int32_t Offset = Var->getStackOffset();
   auto BaseRegNum = Var->getBaseRegNum();
@@ -885,11 +886,11 @@
     // If the stack pointer needs alignment, we must use the frame pointer for
     // arguments. For locals, getFrameOrStackReg will return the stack pointer
     // in this case.
-    if (needsStackPointerAlignment() && Var->getIsArg()) {
-      assert(hasFramePointer());
-      BaseRegNum = getFrameReg();
+    if (Target->needsStackPointerAlignment() && Var->getIsArg()) {
+      assert(Target->hasFramePointer());
+      BaseRegNum = Target->getFrameReg();
     } else {
-      BaseRegNum = getFrameOrStackReg();
+      BaseRegNum = Target->getFrameOrStackReg();
     }
   }
   return AsmAddress(Traits::getEncodedGPR(BaseRegNum), Offset,
diff --git a/third_party/subzero/src/IceTargetLoweringX8632.h b/third_party/subzero/src/IceTargetLoweringX8632.h
index 8272ebe..9976e1c 100644
--- a/third_party/subzero/src/IceTargetLoweringX8632.h
+++ b/third_party/subzero/src/IceTargetLoweringX8632.h
@@ -272,7 +272,8 @@
                               size_t BasicFrameOffset, size_t StackAdjBytes,
                               size_t &InArgsSizeBytes);
   void addEpilog(CfgNode *Node) override;
-  AsmAddress stackVarToAsmAddress(const Variable *Var) const;
+  static AsmAddress stackVarToAsmAddress(const Variable *Var,
+                                         const TargetX8632 *Target);
 
   Operand *legalizeUndef(Operand *From, RegNumT RegNum = RegNumT());
 
diff --git a/third_party/subzero/src/IceTargetLoweringX8632Traits.h b/third_party/subzero/src/IceTargetLoweringX8632Traits.h
index bf450d9..a662331 100644
--- a/third_party/subzero/src/IceTargetLoweringX8632Traits.h
+++ b/third_party/subzero/src/IceTargetLoweringX8632Traits.h
@@ -116,7 +116,8 @@
     AssemblerFixup *fixup() const { return fixup_; }
 
   protected:
-    AsmOperand() : fixup_(nullptr), length_(0) {} // Needed by subclass AsmAddress.
+    AsmOperand()
+        : fixup_(nullptr), length_(0) {} // Needed by subclass AsmAddress.
 
     void SetModRM(int mod, GPRRegister rm) {
       assert((mod & ~3) == 0);
@@ -201,7 +202,7 @@
     }
 
     AsmAddress(GPRRegister Index, ScaleFactor Scale, int32_t Disp,
-            AssemblerFixup *Fixup) {
+               AssemblerFixup *Fixup) {
       assert(Index != RegX8632::Encoded_Reg_esp); // Illegal addressing mode.
       SetModRM(0, RegX8632::Encoded_Reg_esp);
       SetSIB(Scale, Index, RegX8632::Encoded_Reg_ebp);
@@ -211,7 +212,7 @@
     }
 
     AsmAddress(GPRRegister Base, GPRRegister Index, ScaleFactor Scale,
-            int32_t Disp, AssemblerFixup *Fixup) {
+               int32_t Disp, AssemblerFixup *Fixup) {
       assert(Index != RegX8632::Encoded_Reg_esp); // Illegal addressing mode.
       if (Fixup == nullptr && Disp == 0 && Base != RegX8632::Encoded_Reg_ebp) {
         SetModRM(0, RegX8632::Encoded_Reg_esp);
@@ -784,8 +785,9 @@
     SegmentRegisters getSegmentRegister() const { return SegmentReg; }
     void emitSegmentOverride(Assembler *Asm) const;
     bool getIsRebased() const { return IsRebased; }
-    AsmAddress toAsmAddress(Assembler *Asm, const Ice::TargetLowering *Target,
-                         bool LeaAddr = false) const;
+    static AsmAddress toAsmAddress(const X86OperandMem *Mem, Assembler *Asm,
+                                   const Ice::TargetLowering *Target,
+                                   bool LeaAddr = false);
 
     void emit(const Cfg *Func) const override;
     using X86Operand::dump;
@@ -826,9 +828,10 @@
       return new (Func->allocate<VariableSplit>())
           VariableSplit(Func, Var, Part);
     }
+    const Variable *getVar() const { return Var; }
     int32_t getOffset() const { return Part == High ? 4 : 0; }
 
-    AsmAddress toAsmAddress(const Cfg *Func) const;
+    static AsmAddress toAsmAddress(const VariableSplit *Split, const Cfg *Func);
     void emit(const Cfg *Func) const override;
     using X86Operand::dump;
     void dump(const Cfg *Func, Ostream &Str) const override;
diff --git a/third_party/subzero/src/IceTargetLoweringX8664.cpp b/third_party/subzero/src/IceTargetLoweringX8664.cpp
index 4828a15..07c9fa4 100644
--- a/third_party/subzero/src/IceTargetLoweringX8664.cpp
+++ b/third_party/subzero/src/IceTargetLoweringX8664.cpp
@@ -885,13 +885,14 @@
   Str << "(%" << getRegName(BaseRegNum, FrameSPTy) << ")";
 }
 
-AsmAddress TargetX8664::stackVarToAsmAddress(const Variable *Var) const {
+AsmAddress TargetX8664::stackVarToAsmAddress(const Variable *Var,
+                                             const TargetX8664 *Target) {
   if (Var->hasReg())
     llvm::report_fatal_error("Stack Variable has a register assigned");
   if (Var->mustHaveReg()) {
     llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName() +
                              ") has no register assigned - function " +
-                             Func->getFunctionName());
+                             Target->getFunc()->getFunctionName());
   }
   int32_t Offset = Var->getStackOffset();
   auto BaseRegNum = Var->getBaseRegNum();
@@ -899,11 +900,11 @@
     // If the stack pointer needs alignment, we must use the frame pointer for
     // arguments. For locals, getFrameOrStackReg will return the stack pointer
     // in this case.
-    if (needsStackPointerAlignment() && Var->getIsArg()) {
-      assert(hasFramePointer());
-      BaseRegNum = getFrameReg();
+    if (Target->needsStackPointerAlignment() && Var->getIsArg()) {
+      assert(Target->hasFramePointer());
+      BaseRegNum = Target->getFrameReg();
     } else {
-      BaseRegNum = getFrameOrStackReg();
+      BaseRegNum = Target->getFrameOrStackReg();
     }
   }
   return AsmAddress(Traits::getEncodedGPR(BaseRegNum), Offset,
diff --git a/third_party/subzero/src/IceTargetLoweringX8664.h b/third_party/subzero/src/IceTargetLoweringX8664.h
index 1c98f5d..9ea7bfb 100644
--- a/third_party/subzero/src/IceTargetLoweringX8664.h
+++ b/third_party/subzero/src/IceTargetLoweringX8664.h
@@ -268,7 +268,8 @@
                               size_t BasicFrameOffset, size_t StackAdjBytes,
                               size_t &InArgsSizeBytes);
   void addEpilog(CfgNode *Node) override;
-  AsmAddress stackVarToAsmAddress(const Variable *Var) const;
+  static AsmAddress stackVarToAsmAddress(const Variable *Var,
+                                         const TargetX8664 *Target);
 
   Operand *legalizeUndef(Operand *From, RegNumT RegNum = RegNumT());
 
diff --git a/third_party/subzero/src/IceTargetLoweringX8664Traits.h b/third_party/subzero/src/IceTargetLoweringX8664Traits.h
index ce79fb9..eba550f 100644
--- a/third_party/subzero/src/IceTargetLoweringX8664Traits.h
+++ b/third_party/subzero/src/IceTargetLoweringX8664Traits.h
@@ -207,7 +207,7 @@
     }
 
     AsmAddress(GPRRegister Index, ScaleFactor Scale, int32_t Disp,
-            AssemblerFixup *Fixup) {
+               AssemblerFixup *Fixup) {
       assert(Index != RegX8664::Encoded_Reg_rsp); // Illegal addressing mode.
       SetModRM(0, RegX8664::Encoded_Reg_rsp);
       SetSIB(Scale, Index, RegX8664::Encoded_Reg_rbp);
@@ -217,7 +217,7 @@
     }
 
     AsmAddress(GPRRegister Base, GPRRegister Index, ScaleFactor Scale,
-            int32_t Disp, AssemblerFixup *Fixup) {
+               int32_t Disp, AssemblerFixup *Fixup) {
       assert(Index != RegX8664::Encoded_Reg_rsp); // Illegal addressing mode.
       if (Fixup == nullptr && Disp == 0 &&
           (Base & 7) != RegX8664::Encoded_Reg_rbp) {
@@ -866,8 +866,9 @@
     SegmentRegisters getSegmentRegister() const { return DefaultSegment; }
     void emitSegmentOverride(Assembler *) const {}
     bool getIsRebased() const { return IsRebased; }
-    AsmAddress toAsmAddress(Assembler *Asm, const Ice::TargetLowering *Target,
-                         bool IsLeaAddr = false) const;
+    static AsmAddress toAsmAddress(const X86OperandMem *Mem, Assembler *Asm,
+                                   const Ice::TargetLowering *Target,
+                                   bool IsLeaAddr = false);
 
     void emit(const Cfg *Func) const override;
     using X86Operand::dump;
@@ -888,48 +889,6 @@
     const bool IsRebased;
   };
 
-  /// VariableSplit is a way to treat an f64 memory location as a pair of i32
-  /// locations (Low and High). This is needed for some cases of the Bitcast
-  /// instruction. Since it's not possible for integer registers to access the
-  /// XMM registers and vice versa, the lowering forces the f64 to be spilled to
-  /// the stack and then accesses through the VariableSplit.
-  // TODO(jpp): remove references to VariableSplit from IceInstX86Base as 64bit
-  // targets can natively handle these.
-  class VariableSplit : public X86Operand {
-    VariableSplit() = delete;
-    VariableSplit(const VariableSplit &) = delete;
-    VariableSplit &operator=(const VariableSplit &) = delete;
-
-  public:
-    enum Portion { Low, High };
-    static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) {
-      return new (Func->allocate<VariableSplit>())
-          VariableSplit(Func, Var, Part);
-    }
-    int32_t getOffset() const { return Part == High ? 4 : 0; }
-
-    AsmAddress toAsmAddress(const Cfg *Func) const;
-    void emit(const Cfg *Func) const override;
-    using X86Operand::dump;
-    void dump(const Cfg *Func, Ostream &Str) const override;
-
-    static bool classof(const Operand *Operand) {
-      return Operand->getKind() == static_cast<OperandKind>(kSplit);
-    }
-
-  private:
-    VariableSplit(Cfg *Func, Variable *Var, Portion Part)
-        : X86Operand(kSplit, IceType_i32), Var(Var), Part(Part) {
-      assert(Var->getType() == IceType_f64);
-      Vars = Func->allocateArrayOf<Variable *>(1);
-      Vars[0] = Var;
-      NumVars = 1;
-    }
-
-    Variable *Var;
-    Portion Part;
-  };
-
   // Note: The following data structures are defined in IceInstX8664.cpp.
 
   static const struct InstBrAttributesType {