[llvm] r216879 - [asan-assembly-instrumentation] Prologue and epilogue are moved out from InstrumentMemOperand().

Evgeniy Stepanov eugeni.stepanov at gmail.com
Fri Apr 17 17:15:42 PDT 2015


It is not actively used but we plan to return to it soon; it's
actually very close to being useful.
I can take a look at this issue next week.


On Fri, Apr 17, 2015 at 5:07 PM, Pete Cooper <peter_cooper at apple.com> wrote:
> The email to Yuri bounced.
>
> Adding Kostya as the code owner of ASan.
>
> Kostya, is the assembly level asan instrumentation in use?  I don’t know much about asan so i don’t know if this code is still needed or not.  Its causing a pretty bad layering violation.
>
> Thanks,
> Pete
>> On Apr 17, 2015, at 4:39 PM, Pete Cooper <peter_cooper at apple.com> wrote:
>>
>> Hi Yuri
>>
>> Sorry for resurrecting such an old commit.
>>
>> This commit (and perhaps others) has introduced a pretty bad layering violation to the X86 backend.  You’ve made the MC layer AsmParser depend on CodeGen which causes all of the IR to be pulled in to tools like llvm-mc.
>>
>> Can you please find a way to fix up the code to avoid using anything from CodeGen in AsmParser.
>>
>> Thanks,
>> Pete
>>> On Sep 1, 2014, at 5:51 AM, Yuri Gorshenin <ygorshenin at google.com> wrote:
>>>
>>> Author: ygorshenin
>>> Date: Mon Sep  1 07:51:00 2014
>>> New Revision: 216879
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=216879&view=rev
>>> Log:
>>> [asan-assembly-instrumentation] Prologue and epilogue are moved out from InstrumentMemOperand().
>>>
>>> Reviewers: eugenis
>>>
>>> Subscribers: llvm-commits
>>>
>>> Differential revision: http://reviews.llvm.org/D4923
>>>
>>> Modified:
>>>   llvm/trunk/lib/Target/X86/AsmParser/CMakeLists.txt
>>>   llvm/trunk/lib/Target/X86/AsmParser/LLVMBuild.txt
>>>   llvm/trunk/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp
>>>   llvm/trunk/lib/Target/X86/AsmParser/X86AsmInstrumentation.h
>>>   llvm/trunk/test/Instrumentation/AddressSanitizer/X86/asm_mov.ll
>>>   llvm/trunk/test/Instrumentation/AddressSanitizer/X86/asm_rep_movs.ll
>>>
>>> Modified: llvm/trunk/lib/Target/X86/AsmParser/CMakeLists.txt
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/CMakeLists.txt?rev=216879&r1=216878&r2=216879&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Target/X86/AsmParser/CMakeLists.txt (original)
>>> +++ llvm/trunk/lib/Target/X86/AsmParser/CMakeLists.txt Mon Sep  1 07:51:00 2014
>>> @@ -1,4 +1,7 @@
>>> add_llvm_library(LLVMX86AsmParser
>>>  X86AsmInstrumentation.cpp
>>>  X86AsmParser.cpp
>>> +
>>> +  LINK_LIBS
>>> +  LLVMX86CodeGen
>>>  )
>>>
>>> Modified: llvm/trunk/lib/Target/X86/AsmParser/LLVMBuild.txt
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/LLVMBuild.txt?rev=216879&r1=216878&r2=216879&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Target/X86/AsmParser/LLVMBuild.txt (original)
>>> +++ llvm/trunk/lib/Target/X86/AsmParser/LLVMBuild.txt Mon Sep  1 07:51:00 2014
>>> @@ -19,5 +19,5 @@
>>> type = Library
>>> name = X86AsmParser
>>> parent = X86
>>> -required_libraries = MC MCParser Support X86Desc X86Info
>>> +required_libraries = MC MCParser Support X86CodeGen X86Desc X86Info
>>> add_to_library_groups = X86
>>>
>>> Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp?rev=216879&r1=216878&r2=216879&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp (original)
>>> +++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp Mon Sep  1 07:51:00 2014
>>> @@ -10,8 +10,10 @@
>>> #include "MCTargetDesc/X86BaseInfo.h"
>>> #include "X86AsmInstrumentation.h"
>>> #include "X86Operand.h"
>>> +#include "X86RegisterInfo.h"
>>> #include "llvm/ADT/StringExtras.h"
>>> #include "llvm/ADT/Triple.h"
>>> +#include "llvm/CodeGen/MachineValueType.h"
>>> #include "llvm/IR/Function.h"
>>> #include "llvm/MC/MCContext.h"
>>> #include "llvm/MC/MCInst.h"
>>> @@ -36,6 +38,8 @@ bool IsStackReg(unsigned Reg) {
>>>  return Reg == X86::RSP || Reg == X86::ESP || Reg == X86::SP;
>>> }
>>>
>>> +bool IsSmallMemAccess(unsigned AccessSize) { return AccessSize < 8; }
>>> +
>>> std::string FuncName(unsigned AccessSize, bool IsWrite) {
>>>  return std::string("__asan_report_") + (IsWrite ? "store" : "load") +
>>>         utostr(AccessSize);
>>> @@ -43,6 +47,29 @@ std::string FuncName(unsigned AccessSize
>>>
>>> class X86AddressSanitizer : public X86AsmInstrumentation {
>>> public:
>>> +  struct RegisterContext {
>>> +    RegisterContext(unsigned AddressReg, unsigned ShadowReg,
>>> +                    unsigned ScratchReg)
>>> +        : AddressReg(AddressReg), ShadowReg(ShadowReg), ScratchReg(ScratchReg) {
>>> +    }
>>> +
>>> +    unsigned addressReg(MVT::SimpleValueType VT) const {
>>> +      return getX86SubSuperRegister(AddressReg, VT);
>>> +    }
>>> +
>>> +    unsigned shadowReg(MVT::SimpleValueType VT) const {
>>> +      return getX86SubSuperRegister(ShadowReg, VT);
>>> +    }
>>> +
>>> +    unsigned scratchReg(MVT::SimpleValueType VT) const {
>>> +      return getX86SubSuperRegister(ScratchReg, VT);
>>> +    }
>>> +
>>> +    const unsigned AddressReg;
>>> +    const unsigned ShadowReg;
>>> +    const unsigned ScratchReg;
>>> +  };
>>> +
>>>  X86AddressSanitizer(const MCSubtargetInfo &STI)
>>>      : X86AsmInstrumentation(STI), RepPrefix(false) {}
>>>  virtual ~X86AddressSanitizer() {}
>>> @@ -65,51 +92,61 @@ public:
>>>  }
>>>
>>>  // Should be implemented differently in x86_32 and x86_64 subclasses.
>>> -  virtual void InstrumentMemOperandSmallImpl(X86Operand &Op,
>>> -                                             unsigned AccessSize, bool IsWrite,
>>> -                                             MCContext &Ctx,
>>> -                                             MCStreamer &Out) = 0;
>>> -  virtual void InstrumentMemOperandLargeImpl(X86Operand &Op,
>>> -                                             unsigned AccessSize, bool IsWrite,
>>> -                                             MCContext &Ctx,
>>> -                                             MCStreamer &Out) = 0;
>>> +  virtual void StoreFlags(MCStreamer &Out) = 0;
>>> +
>>> +  virtual void RestoreFlags(MCStreamer &Out) = 0;
>>> +
>>> +  // Adjusts up stack and saves all registers used in instrumentation.
>>> +  virtual void InstrumentMemOperandPrologue(const RegisterContext &RegCtx,
>>> +                                            MCContext &Ctx,
>>> +                                            MCStreamer &Out) = 0;
>>> +
>>> +  // Restores all registers used in instrumentation and adjusts stack.
>>> +  virtual void InstrumentMemOperandEpilogue(const RegisterContext &RegCtx,
>>> +                                            MCContext &Ctx,
>>> +                                            MCStreamer &Out) = 0;
>>> +
>>> +  virtual void InstrumentMemOperandSmall(X86Operand &Op, unsigned AccessSize,
>>> +                                         bool IsWrite,
>>> +                                         const RegisterContext &RegCtx,
>>> +                                         MCContext &Ctx, MCStreamer &Out) = 0;
>>> +  virtual void InstrumentMemOperandLarge(X86Operand &Op, unsigned AccessSize,
>>> +                                         bool IsWrite,
>>> +                                         const RegisterContext &RegCtx,
>>> +                                         MCContext &Ctx, MCStreamer &Out) = 0;
>>> +
>>>  virtual void InstrumentMOVSImpl(unsigned AccessSize, MCContext &Ctx,
>>>                                  MCStreamer &Out) = 0;
>>>
>>> -  void InstrumentMemOperand(MCParsedAsmOperand &Op, unsigned AccessSize,
>>> -                            bool IsWrite, MCContext &Ctx, MCStreamer &Out);
>>> +  void InstrumentMemOperand(X86Operand &Op, unsigned AccessSize, bool IsWrite,
>>> +                            const RegisterContext &RegCtx, MCContext &Ctx,
>>> +                            MCStreamer &Out);
>>>  void InstrumentMOVSBase(unsigned DstReg, unsigned SrcReg, unsigned CntReg,
>>>                          unsigned AccessSize, MCContext &Ctx, MCStreamer &Out);
>>> +
>>>  void InstrumentMOVS(const MCInst &Inst, OperandVector &Operands,
>>>                      MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out);
>>>  void InstrumentMOV(const MCInst &Inst, OperandVector &Operands,
>>>                     MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out);
>>>
>>> +protected:
>>>  void EmitLabel(MCStreamer &Out, MCSymbol *Label) { Out.EmitLabel(Label); }
>>>
>>> -protected:
>>>  // True when previous instruction was actually REP prefix.
>>>  bool RepPrefix;
>>> };
>>>
>>> -void X86AddressSanitizer::InstrumentMemOperand(MCParsedAsmOperand &Op,
>>> -                                               unsigned AccessSize,
>>> -                                               bool IsWrite, MCContext &Ctx,
>>> -                                               MCStreamer &Out) {
>>> +void X86AddressSanitizer::InstrumentMemOperand(
>>> +    X86Operand &Op, unsigned AccessSize, bool IsWrite,
>>> +    const RegisterContext &RegCtx, MCContext &Ctx, MCStreamer &Out) {
>>>  assert(Op.isMem() && "Op should be a memory operand.");
>>>  assert((AccessSize & (AccessSize - 1)) == 0 && AccessSize <= 16 &&
>>>         "AccessSize should be a power of two, less or equal than 16.");
>>> -
>>> -  X86Operand &MemOp = static_cast<X86Operand &>(Op);
>>> -  // FIXME: get rid of this limitation.
>>> -  if (IsStackReg(MemOp.getMemBaseReg()) || IsStackReg(MemOp.getMemIndexReg()))
>>> -    return;
>>> -
>>>  // FIXME: take into account load/store alignment.
>>> -  if (AccessSize < 8)
>>> -    InstrumentMemOperandSmallImpl(MemOp, AccessSize, IsWrite, Ctx, Out);
>>> +  if (IsSmallMemAccess(AccessSize))
>>> +    InstrumentMemOperandSmall(Op, AccessSize, IsWrite, RegCtx, Ctx, Out);
>>>  else
>>> -    InstrumentMemOperandLargeImpl(MemOp, AccessSize, IsWrite, Ctx, Out);
>>> +    InstrumentMemOperandLarge(Op, AccessSize, IsWrite, RegCtx, Ctx, Out);
>>> }
>>>
>>> void X86AddressSanitizer::InstrumentMOVSBase(unsigned DstReg, unsigned SrcReg,
>>> @@ -118,16 +155,20 @@ void X86AddressSanitizer::InstrumentMOVS
>>>                                             MCContext &Ctx, MCStreamer &Out) {
>>>  // FIXME: check whole ranges [DstReg .. DstReg + AccessSize * (CntReg - 1)]
>>>  // and [SrcReg .. SrcReg + AccessSize * (CntReg - 1)].
>>> +  RegisterContext RegCtx(X86::RDX /* AddressReg */, X86::RAX /* ShadowReg */,
>>> +                         IsSmallMemAccess(AccessSize)
>>> +                             ? X86::RBX
>>> +                             : X86::NoRegister /* ScratchReg */);
>>>
>>> -  // FIXME: extract prolog and epilogue from InstrumentMemOperand()
>>> -  // and optimize this sequence of InstrumentMemOperand() calls.
>>> +  InstrumentMemOperandPrologue(RegCtx, Ctx, Out);
>>>
>>>  // Test (%SrcReg)
>>>  {
>>>    const MCExpr *Disp = MCConstantExpr::Create(0, Ctx);
>>>    std::unique_ptr<X86Operand> Op(X86Operand::CreateMem(
>>>        0, Disp, SrcReg, 0, AccessSize, SMLoc(), SMLoc()));
>>> -    InstrumentMemOperand(*Op, AccessSize, false /* IsWrite */, Ctx, Out);
>>> +    InstrumentMemOperand(*Op, AccessSize, false /* IsWrite */, RegCtx, Ctx,
>>> +                         Out);
>>>  }
>>>
>>>  // Test -1(%SrcReg, %CntReg, AccessSize)
>>> @@ -135,7 +176,8 @@ void X86AddressSanitizer::InstrumentMOVS
>>>    const MCExpr *Disp = MCConstantExpr::Create(-1, Ctx);
>>>    std::unique_ptr<X86Operand> Op(X86Operand::CreateMem(
>>>        0, Disp, SrcReg, CntReg, AccessSize, SMLoc(), SMLoc()));
>>> -    InstrumentMemOperand(*Op, AccessSize, false /* IsWrite */, Ctx, Out);
>>> +    InstrumentMemOperand(*Op, AccessSize, false /* IsWrite */, RegCtx, Ctx,
>>> +                         Out);
>>>  }
>>>
>>>  // Test (%DstReg)
>>> @@ -143,7 +185,7 @@ void X86AddressSanitizer::InstrumentMOVS
>>>    const MCExpr *Disp = MCConstantExpr::Create(0, Ctx);
>>>    std::unique_ptr<X86Operand> Op(X86Operand::CreateMem(
>>>        0, Disp, DstReg, 0, AccessSize, SMLoc(), SMLoc()));
>>> -    InstrumentMemOperand(*Op, AccessSize, true /* IsWrite */, Ctx, Out);
>>> +    InstrumentMemOperand(*Op, AccessSize, true /* IsWrite */, RegCtx, Ctx, Out);
>>>  }
>>>
>>>  // Test -1(%DstReg, %CntReg, AccessSize)
>>> @@ -151,8 +193,10 @@ void X86AddressSanitizer::InstrumentMOVS
>>>    const MCExpr *Disp = MCConstantExpr::Create(-1, Ctx);
>>>    std::unique_ptr<X86Operand> Op(X86Operand::CreateMem(
>>>        0, Disp, DstReg, CntReg, AccessSize, SMLoc(), SMLoc()));
>>> -    InstrumentMemOperand(*Op, AccessSize, true /* IsWrite */, Ctx, Out);
>>> +    InstrumentMemOperand(*Op, AccessSize, true /* IsWrite */, RegCtx, Ctx, Out);
>>>  }
>>> +
>>> +  InstrumentMemOperandEpilogue(RegCtx, Ctx, Out);
>>> }
>>>
>>> void X86AddressSanitizer::InstrumentMOVS(const MCInst &Inst,
>>> @@ -221,11 +265,26 @@ void X86AddressSanitizer::InstrumentMOV(
>>>  }
>>>
>>>  const bool IsWrite = MII.get(Inst.getOpcode()).mayStore();
>>> +  RegisterContext RegCtx(X86::RDI /* AddressReg */, X86::RAX /* ShadowReg */,
>>> +                         IsSmallMemAccess(AccessSize)
>>> +                             ? X86::RCX
>>> +                             : X86::NoRegister /* ScratchReg */);
>>> +
>>>  for (unsigned Ix = 0; Ix < Operands.size(); ++Ix) {
>>>    assert(Operands[Ix]);
>>>    MCParsedAsmOperand &Op = *Operands[Ix];
>>> -    if (Op.isMem())
>>> -      InstrumentMemOperand(Op, AccessSize, IsWrite, Ctx, Out);
>>> +    if (Op.isMem()) {
>>> +      X86Operand &MemOp = static_cast<X86Operand &>(Op);
>>> +      // FIXME: get rid of this limitation.
>>> +      if (IsStackReg(MemOp.getMemBaseReg()) ||
>>> +          IsStackReg(MemOp.getMemIndexReg())) {
>>> +        continue;
>>> +      }
>>> +
>>> +      InstrumentMemOperandPrologue(RegCtx, Ctx, Out);
>>> +      InstrumentMemOperand(MemOp, AccessSize, IsWrite, RegCtx, Ctx, Out);
>>> +      InstrumentMemOperandEpilogue(RegCtx, Ctx, Out);
>>> +    }
>>>  }
>>> }
>>>
>>> @@ -237,20 +296,58 @@ public:
>>>      : X86AddressSanitizer(STI) {}
>>>  virtual ~X86AddressSanitizer32() {}
>>>
>>> -  virtual void InstrumentMemOperandSmallImpl(X86Operand &Op,
>>> -                                             unsigned AccessSize, bool IsWrite,
>>> -                                             MCContext &Ctx,
>>> -                                             MCStreamer &Out) override;
>>> -  virtual void InstrumentMemOperandLargeImpl(X86Operand &Op,
>>> -                                             unsigned AccessSize, bool IsWrite,
>>> -                                             MCContext &Ctx,
>>> -                                             MCStreamer &Out) override;
>>> +  virtual void StoreFlags(MCStreamer &Out) override {
>>> +    EmitInstruction(Out, MCInstBuilder(X86::PUSHF32));
>>> +  }
>>> +
>>> +  virtual void RestoreFlags(MCStreamer &Out) override {
>>> +    EmitInstruction(Out, MCInstBuilder(X86::POPF32));
>>> +  }
>>> +
>>> +  virtual void InstrumentMemOperandPrologue(const RegisterContext &RegCtx,
>>> +                                            MCContext &Ctx,
>>> +                                            MCStreamer &Out) override {
>>> +    EmitInstruction(
>>> +        Out, MCInstBuilder(X86::PUSH32r).addReg(RegCtx.addressReg(MVT::i32)));
>>> +    EmitInstruction(
>>> +        Out, MCInstBuilder(X86::PUSH32r).addReg(RegCtx.shadowReg(MVT::i32)));
>>> +    if (RegCtx.ScratchReg != X86::NoRegister) {
>>> +      EmitInstruction(
>>> +          Out, MCInstBuilder(X86::PUSH32r).addReg(RegCtx.scratchReg(MVT::i32)));
>>> +    }
>>> +    StoreFlags(Out);
>>> +  }
>>> +
>>> +  virtual void InstrumentMemOperandEpilogue(const RegisterContext &RegCtx,
>>> +                                            MCContext &Ctx,
>>> +                                            MCStreamer &Out) override {
>>> +    RestoreFlags(Out);
>>> +    if (RegCtx.ScratchReg != X86::NoRegister) {
>>> +      EmitInstruction(
>>> +          Out, MCInstBuilder(X86::POP32r).addReg(RegCtx.scratchReg(MVT::i32)));
>>> +    }
>>> +    EmitInstruction(
>>> +        Out, MCInstBuilder(X86::POP32r).addReg(RegCtx.shadowReg(MVT::i32)));
>>> +    EmitInstruction(
>>> +        Out, MCInstBuilder(X86::POP32r).addReg(RegCtx.addressReg(MVT::i32)));
>>> +  }
>>> +
>>> +  virtual void InstrumentMemOperandSmall(X86Operand &Op, unsigned AccessSize,
>>> +                                         bool IsWrite,
>>> +                                         const RegisterContext &RegCtx,
>>> +                                         MCContext &Ctx,
>>> +                                         MCStreamer &Out) override;
>>> +  virtual void InstrumentMemOperandLarge(X86Operand &Op, unsigned AccessSize,
>>> +                                         bool IsWrite,
>>> +                                         const RegisterContext &RegCtx,
>>> +                                         MCContext &Ctx,
>>> +                                         MCStreamer &Out) override;
>>>  virtual void InstrumentMOVSImpl(unsigned AccessSize, MCContext &Ctx,
>>>                                  MCStreamer &Out) override;
>>>
>>> private:
>>> -  void EmitCallAsanReport(MCContext &Ctx, MCStreamer &Out, unsigned AccessSize,
>>> -                          bool IsWrite, unsigned AddressReg) {
>>> +  void EmitCallAsanReport(unsigned AccessSize, bool IsWrite, MCContext &Ctx,
>>> +                          MCStreamer &Out, const RegisterContext &RegCtx) {
>>>    EmitInstruction(Out, MCInstBuilder(X86::CLD));
>>>    EmitInstruction(Out, MCInstBuilder(X86::MMX_EMMS));
>>>
>>> @@ -258,7 +355,8 @@ private:
>>>                             .addReg(X86::ESP)
>>>                             .addReg(X86::ESP)
>>>                             .addImm(-16));
>>> -    EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(AddressReg));
>>> +    EmitInstruction(
>>> +        Out, MCInstBuilder(X86::PUSH32r).addReg(RegCtx.addressReg(MVT::i32)));
>>>
>>>    const std::string &Fn = FuncName(AccessSize, IsWrite);
>>>    MCSymbol *FnSym = Ctx.GetOrCreateSymbol(StringRef(Fn));
>>> @@ -268,52 +366,54 @@ private:
>>>  }
>>> };
>>>
>>> -void X86AddressSanitizer32::InstrumentMemOperandSmallImpl(X86Operand &Op,
>>> -                                                          unsigned AccessSize,
>>> -                                                          bool IsWrite,
>>> -                                                          MCContext &Ctx,
>>> -                                                          MCStreamer &Out) {
>>> -  EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::EAX));
>>> -  EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::ECX));
>>> -  EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::EDX));
>>> -  EmitInstruction(Out, MCInstBuilder(X86::PUSHF32));
>>> +void X86AddressSanitizer32::InstrumentMemOperandSmall(
>>> +    X86Operand &Op, unsigned AccessSize, bool IsWrite,
>>> +    const RegisterContext &RegCtx, MCContext &Ctx, MCStreamer &Out) {
>>> +  unsigned AddressRegI32 = RegCtx.addressReg(MVT::i32);
>>> +  unsigned ShadowRegI32 = RegCtx.shadowReg(MVT::i32);
>>> +  unsigned ShadowRegI8 = RegCtx.shadowReg(MVT::i8);
>>> +
>>> +  assert(RegCtx.ScratchReg != X86::NoRegister);
>>> +  unsigned ScratchRegI32 = RegCtx.scratchReg(MVT::i32);
>>>
>>>  {
>>>    MCInst Inst;
>>>    Inst.setOpcode(X86::LEA32r);
>>> -    Inst.addOperand(MCOperand::CreateReg(X86::EAX));
>>> +    Inst.addOperand(MCOperand::CreateReg(AddressRegI32));
>>>    Op.addMemOperands(Inst, 5);
>>>    EmitInstruction(Out, Inst);
>>>  }
>>>
>>> -  EmitInstruction(
>>> -      Out, MCInstBuilder(X86::MOV32rr).addReg(X86::ECX).addReg(X86::EAX));
>>> -  EmitInstruction(
>>> -      Out,
>>> -      MCInstBuilder(X86::SHR32ri).addReg(X86::ECX).addReg(X86::ECX).addImm(3));
>>> +  EmitInstruction(Out, MCInstBuilder(X86::MOV32rr).addReg(ShadowRegI32).addReg(
>>> +                           AddressRegI32));
>>> +  EmitInstruction(Out, MCInstBuilder(X86::SHR32ri)
>>> +                           .addReg(ShadowRegI32)
>>> +                           .addReg(ShadowRegI32)
>>> +                           .addImm(3));
>>>
>>>  {
>>>    MCInst Inst;
>>>    Inst.setOpcode(X86::MOV8rm);
>>> -    Inst.addOperand(MCOperand::CreateReg(X86::CL));
>>> +    Inst.addOperand(MCOperand::CreateReg(ShadowRegI8));
>>>    const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
>>>    std::unique_ptr<X86Operand> Op(
>>> -        X86Operand::CreateMem(0, Disp, X86::ECX, 0, 1, SMLoc(), SMLoc()));
>>> +        X86Operand::CreateMem(0, Disp, ShadowRegI32, 0, 1, SMLoc(), SMLoc()));
>>>    Op->addMemOperands(Inst, 5);
>>>    EmitInstruction(Out, Inst);
>>>  }
>>>
>>> -  EmitInstruction(Out,
>>> -                  MCInstBuilder(X86::TEST8rr).addReg(X86::CL).addReg(X86::CL));
>>> +  EmitInstruction(
>>> +      Out, MCInstBuilder(X86::TEST8rr).addReg(ShadowRegI8).addReg(ShadowRegI8));
>>>  MCSymbol *DoneSym = Ctx.CreateTempSymbol();
>>>  const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx);
>>>  EmitInstruction(Out, MCInstBuilder(X86::JE_4).addExpr(DoneExpr));
>>>
>>> -  EmitInstruction(
>>> -      Out, MCInstBuilder(X86::MOV32rr).addReg(X86::EDX).addReg(X86::EAX));
>>> -  EmitInstruction(
>>> -      Out,
>>> -      MCInstBuilder(X86::AND32ri).addReg(X86::EDX).addReg(X86::EDX).addImm(7));
>>> +  EmitInstruction(Out, MCInstBuilder(X86::MOV32rr).addReg(ScratchRegI32).addReg(
>>> +                           AddressRegI32));
>>> +  EmitInstruction(Out, MCInstBuilder(X86::AND32ri)
>>> +                           .addReg(ScratchRegI32)
>>> +                           .addReg(ScratchRegI32)
>>> +                           .addImm(7));
>>>
>>>  switch (AccessSize) {
>>>  case 1:
>>> @@ -321,19 +421,19 @@ void X86AddressSanitizer32::InstrumentMe
>>>  case 2: {
>>>    MCInst Inst;
>>>    Inst.setOpcode(X86::LEA32r);
>>> -    Inst.addOperand(MCOperand::CreateReg(X86::EDX));
>>> +    Inst.addOperand(MCOperand::CreateReg(ScratchRegI32));
>>>
>>>    const MCExpr *Disp = MCConstantExpr::Create(1, Ctx);
>>>    std::unique_ptr<X86Operand> Op(
>>> -        X86Operand::CreateMem(0, Disp, X86::EDX, 0, 1, SMLoc(), SMLoc()));
>>> +        X86Operand::CreateMem(0, Disp, ScratchRegI32, 0, 1, SMLoc(), SMLoc()));
>>>    Op->addMemOperands(Inst, 5);
>>>    EmitInstruction(Out, Inst);
>>>    break;
>>>  }
>>>  case 4:
>>>    EmitInstruction(Out, MCInstBuilder(X86::ADD32ri8)
>>> -                             .addReg(X86::EDX)
>>> -                             .addReg(X86::EDX)
>>> +                             .addReg(ScratchRegI32)
>>> +                             .addReg(ScratchRegI32)
>>>                             .addImm(3));
>>>    break;
>>>  default:
>>> @@ -342,41 +442,36 @@ void X86AddressSanitizer32::InstrumentMe
>>>  }
>>>
>>>  EmitInstruction(
>>> -      Out, MCInstBuilder(X86::MOVSX32rr8).addReg(X86::ECX).addReg(X86::CL));
>>> -  EmitInstruction(
>>> -      Out, MCInstBuilder(X86::CMP32rr).addReg(X86::EDX).addReg(X86::ECX));
>>> +      Out,
>>> +      MCInstBuilder(X86::MOVSX32rr8).addReg(ShadowRegI32).addReg(ShadowRegI8));
>>> +  EmitInstruction(Out, MCInstBuilder(X86::CMP32rr).addReg(ScratchRegI32).addReg(
>>> +                           ShadowRegI32));
>>>  EmitInstruction(Out, MCInstBuilder(X86::JL_4).addExpr(DoneExpr));
>>>
>>> -  EmitCallAsanReport(Ctx, Out, AccessSize, IsWrite, X86::EAX);
>>> +  EmitCallAsanReport(AccessSize, IsWrite, Ctx, Out, RegCtx);
>>>  EmitLabel(Out, DoneSym);
>>> -
>>> -  EmitInstruction(Out, MCInstBuilder(X86::POPF32));
>>> -  EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::EDX));
>>> -  EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::ECX));
>>> -  EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::EAX));
>>> }
>>>
>>> -void X86AddressSanitizer32::InstrumentMemOperandLargeImpl(X86Operand &Op,
>>> -                                                          unsigned AccessSize,
>>> -                                                          bool IsWrite,
>>> -                                                          MCContext &Ctx,
>>> -                                                          MCStreamer &Out) {
>>> -  EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::EAX));
>>> -  EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::ECX));
>>> -  EmitInstruction(Out, MCInstBuilder(X86::PUSHF32));
>>> +void X86AddressSanitizer32::InstrumentMemOperandLarge(
>>> +    X86Operand &Op, unsigned AccessSize, bool IsWrite,
>>> +    const RegisterContext &RegCtx, MCContext &Ctx, MCStreamer &Out) {
>>> +  unsigned AddressRegI32 = RegCtx.addressReg(MVT::i32);
>>> +  unsigned ShadowRegI32 = RegCtx.shadowReg(MVT::i32);
>>>
>>>  {
>>>    MCInst Inst;
>>>    Inst.setOpcode(X86::LEA32r);
>>> -    Inst.addOperand(MCOperand::CreateReg(X86::EAX));
>>> +    Inst.addOperand(MCOperand::CreateReg(AddressRegI32));
>>>    Op.addMemOperands(Inst, 5);
>>>    EmitInstruction(Out, Inst);
>>>  }
>>> -  EmitInstruction(
>>> -      Out, MCInstBuilder(X86::MOV32rr).addReg(X86::ECX).addReg(X86::EAX));
>>> -  EmitInstruction(
>>> -      Out,
>>> -      MCInstBuilder(X86::SHR32ri).addReg(X86::ECX).addReg(X86::ECX).addImm(3));
>>> +
>>> +  EmitInstruction(Out, MCInstBuilder(X86::MOV32rr).addReg(ShadowRegI32).addReg(
>>> +                           AddressRegI32));
>>> +  EmitInstruction(Out, MCInstBuilder(X86::SHR32ri)
>>> +                           .addReg(ShadowRegI32)
>>> +                           .addReg(ShadowRegI32)
>>> +                           .addImm(3));
>>>  {
>>>    MCInst Inst;
>>>    switch (AccessSize) {
>>> @@ -392,7 +487,7 @@ void X86AddressSanitizer32::InstrumentMe
>>>    }
>>>    const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
>>>    std::unique_ptr<X86Operand> Op(
>>> -        X86Operand::CreateMem(0, Disp, X86::ECX, 0, 1, SMLoc(), SMLoc()));
>>> +        X86Operand::CreateMem(0, Disp, ShadowRegI32, 0, 1, SMLoc(), SMLoc()));
>>>    Op->addMemOperands(Inst, 5);
>>>    Inst.addOperand(MCOperand::CreateImm(0));
>>>    EmitInstruction(Out, Inst);
>>> @@ -401,18 +496,14 @@ void X86AddressSanitizer32::InstrumentMe
>>>  const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx);
>>>  EmitInstruction(Out, MCInstBuilder(X86::JE_4).addExpr(DoneExpr));
>>>
>>> -  EmitCallAsanReport(Ctx, Out, AccessSize, IsWrite, X86::EAX);
>>> +  EmitCallAsanReport(AccessSize, IsWrite, Ctx, Out, RegCtx);
>>>  EmitLabel(Out, DoneSym);
>>> -
>>> -  EmitInstruction(Out, MCInstBuilder(X86::POPF32));
>>> -  EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::ECX));
>>> -  EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::EAX));
>>> }
>>>
>>> void X86AddressSanitizer32::InstrumentMOVSImpl(unsigned AccessSize,
>>>                                               MCContext &Ctx,
>>>                                               MCStreamer &Out) {
>>> -  EmitInstruction(Out, MCInstBuilder(X86::PUSHF32));
>>> +  StoreFlags(Out);
>>>
>>>  // No need to test when ECX is equals to zero.
>>>  MCSymbol *DoneSym = Ctx.CreateTempSymbol();
>>> @@ -426,7 +517,7 @@ void X86AddressSanitizer32::InstrumentMO
>>>                     X86::ECX /* CntReg */, AccessSize, Ctx, Out);
>>>
>>>  EmitLabel(Out, DoneSym);
>>> -  EmitInstruction(Out, MCInstBuilder(X86::POPF32));
>>> +  RestoreFlags(Out);
>>> }
>>>
>>> class X86AddressSanitizer64 : public X86AddressSanitizer {
>>> @@ -437,14 +528,54 @@ public:
>>>      : X86AddressSanitizer(STI) {}
>>>  virtual ~X86AddressSanitizer64() {}
>>>
>>> -  virtual void InstrumentMemOperandSmallImpl(X86Operand &Op,
>>> -                                             unsigned AccessSize, bool IsWrite,
>>> -                                             MCContext &Ctx,
>>> -                                             MCStreamer &Out) override;
>>> -  virtual void InstrumentMemOperandLargeImpl(X86Operand &Op,
>>> -                                             unsigned AccessSize, bool IsWrite,
>>> -                                             MCContext &Ctx,
>>> -                                             MCStreamer &Out) override;
>>> +  virtual void StoreFlags(MCStreamer &Out) override {
>>> +    EmitInstruction(Out, MCInstBuilder(X86::PUSHF64));
>>> +  }
>>> +
>>> +  virtual void RestoreFlags(MCStreamer &Out) override {
>>> +    EmitInstruction(Out, MCInstBuilder(X86::POPF64));
>>> +  }
>>> +
>>> +  virtual void InstrumentMemOperandPrologue(const RegisterContext &RegCtx,
>>> +                                            MCContext &Ctx,
>>> +                                            MCStreamer &Out) override {
>>> +    EmitAdjustRSP(Ctx, Out, -128);
>>> +    EmitInstruction(
>>> +        Out, MCInstBuilder(X86::PUSH64r).addReg(RegCtx.shadowReg(MVT::i64)));
>>> +    EmitInstruction(
>>> +        Out, MCInstBuilder(X86::PUSH64r).addReg(RegCtx.addressReg(MVT::i64)));
>>> +    if (RegCtx.ScratchReg != X86::NoRegister) {
>>> +      EmitInstruction(
>>> +          Out, MCInstBuilder(X86::PUSH64r).addReg(RegCtx.scratchReg(MVT::i64)));
>>> +    }
>>> +    StoreFlags(Out);
>>> +  }
>>> +
>>> +  virtual void InstrumentMemOperandEpilogue(const RegisterContext &RegCtx,
>>> +                                            MCContext &Ctx,
>>> +                                            MCStreamer &Out) override {
>>> +    RestoreFlags(Out);
>>> +    if (RegCtx.ScratchReg != X86::NoRegister) {
>>> +      EmitInstruction(
>>> +          Out, MCInstBuilder(X86::POP64r).addReg(RegCtx.scratchReg(MVT::i64)));
>>> +    }
>>> +    EmitInstruction(
>>> +        Out, MCInstBuilder(X86::POP64r).addReg(RegCtx.addressReg(MVT::i64)));
>>> +    EmitInstruction(
>>> +        Out, MCInstBuilder(X86::POP64r).addReg(RegCtx.shadowReg(MVT::i64)));
>>> +    EmitAdjustRSP(Ctx, Out, 128);
>>> +  }
>>> +
>>> +  virtual void InstrumentMemOperandSmall(X86Operand &Op, unsigned AccessSize,
>>> +                                         bool IsWrite,
>>> +                                         const RegisterContext &RegCtx,
>>> +                                         MCContext &Ctx,
>>> +                                         MCStreamer &Out) override;
>>> +  virtual void InstrumentMemOperandLarge(X86Operand &Op, unsigned AccessSize,
>>> +                                         bool IsWrite,
>>> +                                         const RegisterContext &RegCtx,
>>> +                                         MCContext &Ctx,
>>> +                                         MCStreamer &Out) override;
>>>  virtual void InstrumentMOVSImpl(unsigned AccessSize, MCContext &Ctx,
>>>                                  MCStreamer &Out) override;
>>>
>>> @@ -461,8 +592,8 @@ private:
>>>    EmitInstruction(Out, Inst);
>>>  }
>>>
>>> -  void EmitCallAsanReport(MCContext &Ctx, MCStreamer &Out, unsigned AccessSize,
>>> -                          bool IsWrite) {
>>> +  void EmitCallAsanReport(unsigned AccessSize, bool IsWrite, MCContext &Ctx,
>>> +                          MCStreamer &Out, const RegisterContext &RegCtx) {
>>>    EmitInstruction(Out, MCInstBuilder(X86::CLD));
>>>    EmitInstruction(Out, MCInstBuilder(X86::MMX_EMMS));
>>>
>>> @@ -471,6 +602,10 @@ private:
>>>                             .addReg(X86::RSP)
>>>                             .addImm(-16));
>>>
>>> +    if (RegCtx.AddressReg != X86::RDI) {
>>> +      EmitInstruction(Out, MCInstBuilder(X86::MOV64rr).addReg(X86::RDI).addReg(
>>> +                               RegCtx.addressReg(MVT::i64)));
>>> +    }
>>>    const std::string &Fn = FuncName(AccessSize, IsWrite);
>>>    MCSymbol *FnSym = Ctx.GetOrCreateSymbol(StringRef(Fn));
>>>    const MCSymbolRefExpr *FnExpr =
>>> @@ -479,50 +614,54 @@ private:
>>>  }
>>> };
>>>
>>> -void X86AddressSanitizer64::InstrumentMemOperandSmallImpl(X86Operand &Op,
>>> -                                                          unsigned AccessSize,
>>> -                                                          bool IsWrite,
>>> -                                                          MCContext &Ctx,
>>> -                                                          MCStreamer &Out) {
>>> -  EmitAdjustRSP(Ctx, Out, -128);
>>> -  EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RAX));
>>> -  EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RCX));
>>> -  EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RDI));
>>> -  EmitInstruction(Out, MCInstBuilder(X86::PUSHF64));
>>> +void X86AddressSanitizer64::InstrumentMemOperandSmall(
>>> +    X86Operand &Op, unsigned AccessSize, bool IsWrite,
>>> +    const RegisterContext &RegCtx, MCContext &Ctx, MCStreamer &Out) {
>>> +  unsigned AddressRegI64 = RegCtx.addressReg(MVT::i64);
>>> +  unsigned AddressRegI32 = RegCtx.addressReg(MVT::i32);
>>> +  unsigned ShadowRegI64 = RegCtx.shadowReg(MVT::i64);
>>> +  unsigned ShadowRegI32 = RegCtx.shadowReg(MVT::i32);
>>> +  unsigned ShadowRegI8 = RegCtx.shadowReg(MVT::i8);
>>> +
>>> +  assert(RegCtx.ScratchReg != X86::NoRegister);
>>> +  unsigned ScratchRegI32 = RegCtx.scratchReg(MVT::i32);
>>> +
>>>  {
>>>    MCInst Inst;
>>>    Inst.setOpcode(X86::LEA64r);
>>> -    Inst.addOperand(MCOperand::CreateReg(X86::RDI));
>>> +    Inst.addOperand(MCOperand::CreateReg(AddressRegI64));
>>>    Op.addMemOperands(Inst, 5);
>>>    EmitInstruction(Out, Inst);
>>>  }
>>> -  EmitInstruction(
>>> -      Out, MCInstBuilder(X86::MOV64rr).addReg(X86::RAX).addReg(X86::RDI));
>>> -  EmitInstruction(
>>> -      Out,
>>> -      MCInstBuilder(X86::SHR64ri).addReg(X86::RAX).addReg(X86::RAX).addImm(3));
>>> +  EmitInstruction(Out, MCInstBuilder(X86::MOV64rr).addReg(ShadowRegI64).addReg(
>>> +                           AddressRegI64));
>>> +  EmitInstruction(Out, MCInstBuilder(X86::SHR64ri)
>>> +                           .addReg(ShadowRegI64)
>>> +                           .addReg(ShadowRegI64)
>>> +                           .addImm(3));
>>>  {
>>>    MCInst Inst;
>>>    Inst.setOpcode(X86::MOV8rm);
>>> -    Inst.addOperand(MCOperand::CreateReg(X86::AL));
>>> +    Inst.addOperand(MCOperand::CreateReg(ShadowRegI8));
>>>    const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
>>>    std::unique_ptr<X86Operand> Op(
>>> -        X86Operand::CreateMem(0, Disp, X86::RAX, 0, 1, SMLoc(), SMLoc()));
>>> +        X86Operand::CreateMem(0, Disp, ShadowRegI64, 0, 1, SMLoc(), SMLoc()));
>>>    Op->addMemOperands(Inst, 5);
>>>    EmitInstruction(Out, Inst);
>>>  }
>>>
>>> -  EmitInstruction(Out,
>>> -                  MCInstBuilder(X86::TEST8rr).addReg(X86::AL).addReg(X86::AL));
>>> +  EmitInstruction(
>>> +      Out, MCInstBuilder(X86::TEST8rr).addReg(ShadowRegI8).addReg(ShadowRegI8));
>>>  MCSymbol *DoneSym = Ctx.CreateTempSymbol();
>>>  const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx);
>>>  EmitInstruction(Out, MCInstBuilder(X86::JE_4).addExpr(DoneExpr));
>>>
>>> -  EmitInstruction(
>>> -      Out, MCInstBuilder(X86::MOV32rr).addReg(X86::ECX).addReg(X86::EDI));
>>> -  EmitInstruction(
>>> -      Out,
>>> -      MCInstBuilder(X86::AND32ri).addReg(X86::ECX).addReg(X86::ECX).addImm(7));
>>> +  EmitInstruction(Out, MCInstBuilder(X86::MOV32rr).addReg(ScratchRegI32).addReg(
>>> +                           AddressRegI32));
>>> +  EmitInstruction(Out, MCInstBuilder(X86::AND32ri)
>>> +                           .addReg(ScratchRegI32)
>>> +                           .addReg(ScratchRegI32)
>>> +                           .addImm(7));
>>>
>>>  switch (AccessSize) {
>>>  case 1:
>>> @@ -530,19 +669,19 @@ void X86AddressSanitizer64::InstrumentMe
>>>  case 2: {
>>>    MCInst Inst;
>>>    Inst.setOpcode(X86::LEA32r);
>>> -    Inst.addOperand(MCOperand::CreateReg(X86::ECX));
>>> +    Inst.addOperand(MCOperand::CreateReg(ScratchRegI32));
>>>
>>>    const MCExpr *Disp = MCConstantExpr::Create(1, Ctx);
>>>    std::unique_ptr<X86Operand> Op(
>>> -        X86Operand::CreateMem(0, Disp, X86::ECX, 0, 1, SMLoc(), SMLoc()));
>>> +        X86Operand::CreateMem(0, Disp, ScratchRegI32, 0, 1, SMLoc(), SMLoc()));
>>>    Op->addMemOperands(Inst, 5);
>>>    EmitInstruction(Out, Inst);
>>>    break;
>>>  }
>>>  case 4:
>>>    EmitInstruction(Out, MCInstBuilder(X86::ADD32ri8)
>>> -                             .addReg(X86::ECX)
>>> -                             .addReg(X86::ECX)
>>> +                             .addReg(ScratchRegI32)
>>> +                             .addReg(ScratchRegI32)
>>>                             .addImm(3));
>>>    break;
>>>  default:
>>> @@ -551,40 +690,35 @@ void X86AddressSanitizer64::InstrumentMe
>>>  }
>>>
>>>  EmitInstruction(
>>> -      Out, MCInstBuilder(X86::MOVSX32rr8).addReg(X86::EAX).addReg(X86::AL));
>>> -  EmitInstruction(
>>> -      Out, MCInstBuilder(X86::CMP32rr).addReg(X86::ECX).addReg(X86::EAX));
>>> +      Out,
>>> +      MCInstBuilder(X86::MOVSX32rr8).addReg(ShadowRegI32).addReg(ShadowRegI8));
>>> +  EmitInstruction(Out, MCInstBuilder(X86::CMP32rr).addReg(ScratchRegI32).addReg(
>>> +                           ShadowRegI32));
>>>  EmitInstruction(Out, MCInstBuilder(X86::JL_4).addExpr(DoneExpr));
>>>
>>> -  EmitCallAsanReport(Ctx, Out, AccessSize, IsWrite);
>>> +  EmitCallAsanReport(AccessSize, IsWrite, Ctx, Out, RegCtx);
>>>  EmitLabel(Out, DoneSym);
>>> -
>>> -  EmitInstruction(Out, MCInstBuilder(X86::POPF64));
>>> -  EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(X86::RDI));
>>> -  EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(X86::RCX));
>>> -  EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(X86::RAX));
>>> -  EmitAdjustRSP(Ctx, Out, 128);
>>> }
>>>
>>> -void X86AddressSanitizer64::InstrumentMemOperandLargeImpl(X86Operand &Op,
>>> -                                                          unsigned AccessSize,
>>> -                                                          bool IsWrite,
>>> -                                                          MCContext &Ctx,
>>> -                                                          MCStreamer &Out) {
>>> -  EmitAdjustRSP(Ctx, Out, -128);
>>> -  EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RAX));
>>> -  EmitInstruction(Out, MCInstBuilder(X86::PUSHF64));
>>> +void X86AddressSanitizer64::InstrumentMemOperandLarge(
>>> +    X86Operand &Op, unsigned AccessSize, bool IsWrite,
>>> +    const RegisterContext &RegCtx, MCContext &Ctx, MCStreamer &Out) {
>>> +  unsigned AddressRegI64 = RegCtx.addressReg(MVT::i64);
>>> +  unsigned ShadowRegI64 = RegCtx.shadowReg(MVT::i64);
>>>
>>>  {
>>>    MCInst Inst;
>>>    Inst.setOpcode(X86::LEA64r);
>>> -    Inst.addOperand(MCOperand::CreateReg(X86::RAX));
>>> +    Inst.addOperand(MCOperand::CreateReg(AddressRegI64));
>>>    Op.addMemOperands(Inst, 5);
>>>    EmitInstruction(Out, Inst);
>>>  }
>>> -  EmitInstruction(
>>> -      Out,
>>> -      MCInstBuilder(X86::SHR64ri).addReg(X86::RAX).addReg(X86::RAX).addImm(3));
>>> +  EmitInstruction(Out, MCInstBuilder(X86::MOV64rr).addReg(ShadowRegI64).addReg(
>>> +                           AddressRegI64));
>>> +  EmitInstruction(Out, MCInstBuilder(X86::SHR64ri)
>>> +                           .addReg(ShadowRegI64)
>>> +                           .addReg(ShadowRegI64)
>>> +                           .addImm(3));
>>>  {
>>>    MCInst Inst;
>>>    switch (AccessSize) {
>>> @@ -600,7 +734,7 @@ void X86AddressSanitizer64::InstrumentMe
>>>    }
>>>    const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
>>>    std::unique_ptr<X86Operand> Op(
>>> -        X86Operand::CreateMem(0, Disp, X86::RAX, 0, 1, SMLoc(), SMLoc()));
>>> +        X86Operand::CreateMem(0, Disp, ShadowRegI64, 0, 1, SMLoc(), SMLoc()));
>>>    Op->addMemOperands(Inst, 5);
>>>    Inst.addOperand(MCOperand::CreateImm(0));
>>>    EmitInstruction(Out, Inst);
>>> @@ -610,18 +744,14 @@ void X86AddressSanitizer64::InstrumentMe
>>>  const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx);
>>>  EmitInstruction(Out, MCInstBuilder(X86::JE_4).addExpr(DoneExpr));
>>>
>>> -  EmitCallAsanReport(Ctx, Out, AccessSize, IsWrite);
>>> +  EmitCallAsanReport(AccessSize, IsWrite, Ctx, Out, RegCtx);
>>>  EmitLabel(Out, DoneSym);
>>> -
>>> -  EmitInstruction(Out, MCInstBuilder(X86::POPF64));
>>> -  EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(X86::RAX));
>>> -  EmitAdjustRSP(Ctx, Out, 128);
>>> }
>>>
>>> void X86AddressSanitizer64::InstrumentMOVSImpl(unsigned AccessSize,
>>>                                               MCContext &Ctx,
>>>                                               MCStreamer &Out) {
>>> -  EmitInstruction(Out, MCInstBuilder(X86::PUSHF64));
>>> +  StoreFlags(Out);
>>>
>>>  // No need to test when RCX is equals to zero.
>>>  MCSymbol *DoneSym = Ctx.CreateTempSymbol();
>>> @@ -635,7 +765,7 @@ void X86AddressSanitizer64::InstrumentMO
>>>                     X86::RCX /* CntReg */, AccessSize, Ctx, Out);
>>>
>>>  EmitLabel(Out, DoneSym);
>>> -  EmitInstruction(Out, MCInstBuilder(X86::POPF64));
>>> +  RestoreFlags(Out);
>>> }
>>>
>>> } // End anonymous namespace
>>>
>>> Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmInstrumentation.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmInstrumentation.h?rev=216879&r1=216878&r2=216879&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Target/X86/AsmParser/X86AsmInstrumentation.h (original)
>>> +++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmInstrumentation.h Mon Sep  1 07:51:00 2014
>>> @@ -37,7 +37,7 @@ public:
>>>  // Tries to instrument and emit instruction.
>>>  virtual void InstrumentAndEmitInstruction(
>>>      const MCInst &Inst,
>>> -      SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand>> &Operands,
>>> +      SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand> > &Operands,
>>>      MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out);
>>>
>>> protected:
>>>
>>> Modified: llvm/trunk/test/Instrumentation/AddressSanitizer/X86/asm_mov.ll
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/AddressSanitizer/X86/asm_mov.ll?rev=216879&r1=216878&r2=216879&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Instrumentation/AddressSanitizer/X86/asm_mov.ll (original)
>>> +++ llvm/trunk/test/Instrumentation/AddressSanitizer/X86/asm_mov.ll Mon Sep  1 07:51:00 2014
>>> @@ -6,8 +6,8 @@ target triple = "x86_64-unknown-linux-gn
>>> ; CHECK-LABEL: mov1b
>>> ; CHECK: leaq -128(%rsp), %rsp
>>> ; CHECK-NEXT: pushq %rax
>>> -; CHECK-NEXT: pushq %rcx
>>> ; CHECK-NEXT: pushq %rdi
>>> +; CHECK-NEXT: pushq %rcx
>>> ; CHECK-NEXT: pushfq
>>> ; CHECK-NEXT: leaq {{.*}}, %rdi
>>> ; CHECK-NEXT: movq %rdi, %rax
>>> @@ -26,8 +26,8 @@ target triple = "x86_64-unknown-linux-gn
>>> ; CHECK-NEXT: callq __asan_report_load1 at PLT
>>> ; CHECK-NEXT: [[A]]:
>>> ; CHECK-NEXT: popfq
>>> -; CHECK-NEXT: popq %rdi
>>> ; CHECK-NEXT: popq %rcx
>>> +; CHECK-NEXT: popq %rdi
>>> ; CHECK-NEXT: popq %rax
>>> ; CHECK-NEXT: leaq 128(%rsp), %rsp
>>>
>>> @@ -81,8 +81,10 @@ entry:
>>> ; CHECK-LABEL: mov8b
>>> ; CHECK: leaq -128(%rsp), %rsp
>>> ; CHECK-NEXT: pushq %rax
>>> +; CHECK-NEXT: pushq %rdi
>>> ; CHECK-NEXT: pushfq
>>> -; CHECK-NEXT: leaq {{.*}}, %rax
>>> +; CHECK-NEXT: leaq {{.*}}, %rdi
>>> +; CHECK-NEXT: movq %rdi, %rax
>>> ; CHECK-NEXT: shrq $3, %rax
>>> ; CHECK-NEXT: cmpb $0, 2147450880(%rax)
>>> ; CHECK-NEXT: je [[A:.*]]
>>> @@ -92,13 +94,16 @@ entry:
>>> ; CHECK-NEXT: callq __asan_report_load8 at PLT
>>> ; CHECK-NEXT: [[A]]:
>>> ; CHECK-NEXT: popfq
>>> +; CHECK-NEXT: popq %rdi
>>> ; CHECK-NEXT: popq %rax
>>> ; CHECK-NEXT: leaq 128(%rsp), %rsp
>>>
>>> ; CHECK: leaq -128(%rsp), %rsp
>>> ; CHECK-NEXT: pushq %rax
>>> +; CHECK-NEXT: pushq %rdi
>>> ; CHECK-NEXT: pushfq
>>> -; CHECK-NEXT: leaq {{.*}}, %rax
>>> +; CHECK-NEXT: leaq {{.*}}, %rdi
>>> +; CHECK-NEXT: movq %rdi, %rax
>>> ; CHECK-NEXT: shrq $3, %rax
>>> ; CHECK-NEXT: cmpb $0, 2147450880(%rax)
>>> ; CHECK-NEXT: je [[A:.*]]
>>> @@ -108,6 +113,7 @@ entry:
>>> ; CHECK-NEXT: callq __asan_report_store8 at PLT
>>> ; CHECK-NEXT: [[A]]:
>>> ; CHECK-NEXT: popfq
>>> +; CHECK-NEXT: popq %rdi
>>> ; CHECK-NEXT: popq %rax
>>> ; CHECK-NEXT: leaq 128(%rsp), %rsp
>>>
>>>
>>> Modified: llvm/trunk/test/Instrumentation/AddressSanitizer/X86/asm_rep_movs.ll
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/AddressSanitizer/X86/asm_rep_movs.ll?rev=216879&r1=216878&r2=216879&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Instrumentation/AddressSanitizer/X86/asm_rep_movs.ll (original)
>>> +++ llvm/trunk/test/Instrumentation/AddressSanitizer/X86/asm_rep_movs.ll Mon Sep  1 07:51:00 2014
>>> @@ -8,17 +8,33 @@ target triple = "x86_64-unknown-linux-gn
>>> ; CHECK-NEXT: testq %rcx, %rcx
>>> ; CHECK-NEXT: je [[B:.*]]
>>>
>>> -; CHECK: leaq (%rsi), {{.*}}
>>> -; CHECK: callq __asan_report_load1 at PLT
>>> -
>>> -; CHECK: leaq -1(%rsi,%rcx), {{.*}}
>>> -; CHECK: callq __asan_report_load1 at PLT
>>> -
>>> -; CHECK: leaq (%rdi), {{.*}}
>>> -; CHECK: callq __asan_report_store1 at PLT
>>> -
>>> -; CHECK: leaq -1(%rdi,%rcx), {{.*}}
>>> -; CHECK: callq __asan_report_store1 at PLT
>>> +; CHECK: leaq -128(%rsp), %rsp
>>> +; CHECK-NEXT: pushq %rax
>>> +; CHECK-NEXT: pushq %rdx
>>> +; CHECK-NEXT: pushq %rbx
>>> +; CHECK-NEXT: pushfq
>>> +
>>> +; CHECK: leaq (%rsi), %rdx
>>> +; CHECK: movq %rdx, %rdi
>>> +; CHECK-NEXT: callq __asan_report_load1 at PLT
>>> +
>>> +; CHECK: leaq -1(%rsi,%rcx), %rdx
>>> +; CHECK: movq %rdx, %rdi
>>> +; CHECK-NEXT: callq __asan_report_load1 at PLT
>>> +
>>> +; CHECK: leaq (%rdi), %rdx
>>> +; CHECK: movq %rdx, %rdi
>>> +; CHECK-NEXT: callq __asan_report_store1 at PLT
>>> +
>>> +; CHECK: leaq -1(%rdi,%rcx), %rdx
>>> +; CHECK: movq %rdx, %rdi
>>> +; CHECK-NEXT: callq __asan_report_store1 at PLT
>>> +
>>> +; CHECK: popfq
>>> +; CHECK-NEXT: popq %rbx
>>> +; CHECK-NEXT: popq %rdx
>>> +; CHECK-NEXT: popq %rax
>>> +; CHECK-NEXT: leaq 128(%rsp), %rsp
>>>
>>> ; CHECK: [[B]]:
>>> ; CHECK-NEXT: popfq
>>> @@ -38,17 +54,21 @@ entry:
>>> ; CHECK-NEXT: testq %rcx, %rcx
>>> ; CHECK-NEXT: je [[Q:.*]]
>>>
>>> -; CHECK: leaq (%rsi), {{.*}}
>>> -; CHECK: callq __asan_report_load8 at PLT
>>> -
>>> -; CHECK: leaq -1(%rsi,%rcx,8), {{.*}}
>>> -; CHECK: callq __asan_report_load8 at PLT
>>> -
>>> -; CHECK: leaq (%rdi), {{.*}}
>>> -; CHECK: callq __asan_report_store8 at PLT
>>> -
>>> -; CHECK: leaq -1(%rdi,%rcx,8), {{.*}}
>>> -; CHECK: callq __asan_report_store8 at PLT
>>> +; CHECK: leaq (%rsi), %rdx
>>> +; CHECK: movq %rdx, %rdi
>>> +; CHECK-NEXT: callq __asan_report_load8 at PLT
>>> +
>>> +; CHECK: leaq -1(%rsi,%rcx,8), %rdx
>>> +; CHECK: movq %rdx, %rdi
>>> +; CHECK-NEXT: callq __asan_report_load8 at PLT
>>> +
>>> +; CHECK: leaq (%rdi), %rdx
>>> +; CHECK: movq %rdx, %rdi
>>> +; CHECK-NEXT: callq __asan_report_store8 at PLT
>>> +
>>> +; CHECK: leaq -1(%rdi,%rcx,8), %rdx
>>> +; CHECK: movq %rdx, %rdi
>>> +; CHECK-NEXT: callq __asan_report_store8 at PLT
>>>
>>> ; CHECK: [[Q]]:
>>> ; CHECK-NEXT: popfq
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list