diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp @@ -267,15 +267,42 @@ // Replace tee instructions with local.tee. The difference is that tee // instructions have two defs, while local.tee instructions have one def // and an index of a local to write to. + // + // - Before: + // TeeReg, Reg = TEE DefReg + // INST ..., TeeReg, ... + // INST ..., Reg, ... + // INST ..., Reg, ... + // * DefReg: may or may not stackified + // * Reg: not stackified + // * TeeReg: stackified + // + // - After (when DefReg is already stackified): + // TeeReg = LOCAL_TEE LocalId1, DefReg + // INST ..., TeeReg, ... + // INST ..., Reg, ... + // INST ..., Reg, ... + // * Reg: mapped to LocalId1 + // * TeeReg: stackified + // + // - After (when DefReg is not stackified): + // NewReg = LOCAL_GET LocalId1 + // TeeReg = LOCAL_TEE LocalId2, NewReg + // INST ..., TeeReg, ... + // INST ..., Reg, ... + // INST ..., Reg, ... + // * DefReg: mapped to LocalId1 + // * Reg: mapped to LocalId2 + // * TeeReg: stackified if (WebAssembly::isTee(MI.getOpcode())) { assert(MFI.isVRegStackified(MI.getOperand(0).getReg())); assert(!MFI.isVRegStackified(MI.getOperand(1).getReg())); - Register OldReg = MI.getOperand(2).getReg(); - const TargetRegisterClass *RC = MRI.getRegClass(OldReg); + Register DefReg = MI.getOperand(2).getReg(); + const TargetRegisterClass *RC = MRI.getRegClass(DefReg); // Stackify the input if it isn't stackified yet. - if (!MFI.isVRegStackified(OldReg)) { - unsigned LocalId = getLocalId(Reg2Local, MFI, CurLocal, OldReg); + if (!MFI.isVRegStackified(DefReg)) { + unsigned LocalId = getLocalId(Reg2Local, MFI, CurLocal, DefReg); Register NewReg = MRI.createVirtualRegister(RC); unsigned Opc = getLocalGetOpcode(RC); BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(Opc), NewReg)