[llvm] r303183 - [X86] Replace slow LEA instructions in X86

Hubert Tong via llvm-commits llvm-commits at lists.llvm.org
Tue May 16 12:48:05 PDT 2017


This patch also introduced test failures on various buildbots, e.g.,
http://lab.llvm.org:8011/builders/clang-s390x-linux/builds/8305/steps/ninja%20check%201/logs/FAIL%3A%20LLVM%3A%3AleaFixup64.mir

     [exec] 'corei7-avx' is not a recognized processor for this target
(ignoring processor)
     [exec] 'corei7-avx' is not a recognized processor for this target
(ignoring processor)
     [exec] 'corei7-avx' is not a recognized processor for this target
(ignoring processor)
     [exec] 'corei7-avx' is not a recognized processor for this target
(ignoring processor)
     [exec] 'corei7-avx' is not a recognized processor for this target
(ignoring processor)
     [exec] 'corei7-avx' is not a recognized processor for this target
(ignoring processor)
     [exec] error:
/tmp/continuous/jenkins/workspace/continuous.pure_clang.main_trunk.svn/s390x-RedHatEnterpriseServer-7.0/workdir/llvm-dev.src/test/CodeGen/X86/leaFixup64.mir:161:13:
unknown register name 'rax'
     [exec]   - { reg: '%rax' }
     [exec]             ^
     [exec]
     [exec] LLVM ERROR: Unable to initialize machine function



On Tue, May 16, 2017 at 12:01 PM, Lama Saba via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: lsaba
> Date: Tue May 16 11:01:36 2017
> New Revision: 303183
>
> URL: http://llvm.org/viewvc/llvm-project?rev=303183&view=rev
> Log:
> [X86] Replace slow LEA instructions in X86
>
>   According to Intel's Optimization Reference Manual for SNB+:
>   " For LEA instructions with three source operands and some specific
> situations, instruction latency has increased to 3 cycles, and must
>     dispatch via port 1:
>   - LEA that has all three source operands: base, index, and offset
>   - LEA that uses base and index registers where the base is EBP, RBP,or
> R13
>   - LEA that uses RIP relative addressing mode
>   - LEA that uses 16-bit addressing mode "
>   This patch currently handles the first 2 cases only.
>
> Differential Revision: https://reviews.llvm.org/D32277
>
>
> Added:
>     llvm/trunk/test/CodeGen/X86/leaFixup32.mir
>     llvm/trunk/test/CodeGen/X86/leaFixup64.mir
> Modified:
>     llvm/trunk/lib/Target/X86/X86.td
>     llvm/trunk/lib/Target/X86/X86FixupLEAs.cpp
>     llvm/trunk/lib/Target/X86/X86Subtarget.h
>     llvm/trunk/lib/Target/X86/X86TargetMachine.cpp
>
> Modified: llvm/trunk/lib/Target/X86/X86.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/
> X86/X86.td?rev=303183&r1=303182&r2=303183&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/Target/X86/X86.td (original)
> +++ llvm/trunk/lib/Target/X86/X86.td Tue May 16 11:01:36 2017
> @@ -235,6 +235,8 @@ def FeatureLEAUsesAG : SubtargetFeature<
>                                     "LEA instruction needs inputs at AG
> stage">;
>  def FeatureSlowLEA : SubtargetFeature<"slow-lea", "SlowLEA", "true",
>                                     "LEA instruction with certain
> arguments is slow">;
> +def FeatureSlow3OpsLEA : SubtargetFeature<"slow-3ops-lea",
> "Slow3OpsLEA", "true",
> +                                   "LEA instruction with 3 ops or certain
> registers is slow">;
>  def FeatureSlowIncDec : SubtargetFeature<"slow-incdec", "SlowIncDec",
> "true",
>                                     "INC and DEC instructions are slower
> than ADD and SUB">;
>  def FeatureSoftFloat
> @@ -480,6 +482,7 @@ def SNBFeatures : ProcessorFeatures<[],
>    FeatureXSAVE,
>    FeatureXSAVEOPT,
>    FeatureLAHFSAHF,
> +  FeatureSlow3OpsLEA,
>    FeatureFastScalarFSQRT,
>    FeatureFastSHLDRotate
>  ]>;
>
> Modified: llvm/trunk/lib/Target/X86/X86FixupLEAs.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/
> X86/X86FixupLEAs.cpp?rev=303183&r1=303182&r2=303183&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/Target/X86/X86FixupLEAs.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86FixupLEAs.cpp Tue May 16 11:01:36 2017
> @@ -27,20 +27,26 @@
>  #include "llvm/Target/TargetInstrInfo.h"
>  using namespace llvm;
>
> -#define DEBUG_TYPE "x86-fixup-LEAs"
> +namespace llvm {
> +void initializeFixupLEAPassPass(PassRegistry &);
> +}
> +
> +#define FIXUPLEA_DESC "X86 LEA Fixup"
> +#define FIXUPLEA_NAME "x86-fixup-LEAs"
> +
> +#define DEBUG_TYPE FIXUPLEA_NAME
>
>  STATISTIC(NumLEAs, "Number of LEA instructions created");
>
>  namespace {
>  class FixupLEAPass : public MachineFunctionPass {
>    enum RegUsageState { RU_NotUsed, RU_Write, RU_Read };
> -  static char ID;
> +
>    /// \brief Loop over all of the instructions in the basic block
>    /// replacing applicable instructions with LEA instructions,
>    /// where appropriate.
>    bool processBasicBlock(MachineFunction &MF, MachineFunction::iterator
> MFI);
>
> -  StringRef getPassName() const override { return "X86 LEA Fixup"; }
>
>    /// \brief Given a machine register, look for the instruction
>    /// which writes it in the current basic block. If found,
> @@ -62,6 +68,22 @@ class FixupLEAPass : public MachineFunct
>    void processInstructionForSLM(MachineBasicBlock::iterator &I,
>                                  MachineFunction::iterator MFI);
>
> +
> +  /// \brief Given a LEA instruction which is unprofitable
> +  /// on SNB+ try to replace it with other instructions.
> +  /// According to Intel's Optimization Reference Manual:
> +  /// " For LEA instructions with three source operands and some specific
> +  ///   situations, instruction latency has increased to 3 cycles, and
> must
> +  ///   dispatch via port 1:
> +  /// - LEA that has all three source operands: base, index, and offset
> +  /// - LEA that uses base and index registers where the base is EBP, RBP,
> +  ///   or R13
> +  /// - LEA that uses RIP relative addressing mode
> +  /// - LEA that uses 16-bit addressing mode "
> +  /// This function currently handles the first 2 cases only.
> +  MachineInstr *processInstrForSlow3OpLEA(MachineInstr &MI,
> +                                          MachineFunction::iterator MFI);
> +
>    /// \brief Look for LEAs that add 1 to reg or subtract 1 from reg
>    /// and convert them to INC or DEC respectively.
>    bool fixupIncDec(MachineBasicBlock::iterator &I,
> @@ -85,7 +107,13 @@ class FixupLEAPass : public MachineFunct
>                                     MachineBasicBlock::iterator &MBBI)
> const;
>
>  public:
> -  FixupLEAPass() : MachineFunctionPass(ID) {}
> +  static char ID;
> +
> +  StringRef getPassName() const override { return FIXUPLEA_DESC; }
> +
> +  FixupLEAPass() : MachineFunctionPass(ID) {
> +    initializeFixupLEAPassPass(*PassRegistry::getPassRegistry());
> +  }
>
>    /// \brief Loop over all of the basic blocks,
>    /// replacing instructions by equivalent LEA instructions
> @@ -104,9 +132,12 @@ private:
>    bool OptIncDec;
>    bool OptLEA;
>  };
> -char FixupLEAPass::ID = 0;
>  }
>
> +char FixupLEAPass::ID = 0;
> +
> +INITIALIZE_PASS(FixupLEAPass, FIXUPLEA_NAME, FIXUPLEA_DESC, false, false)
> +
>  MachineInstr *
>  FixupLEAPass::postRAConvertToLEA(MachineFunction::iterator &MFI,
>                                   MachineBasicBlock::iterator &MBBI) const
> {
> @@ -168,7 +199,7 @@ bool FixupLEAPass::runOnMachineFunction(
>    MF = &Func;
>    const X86Subtarget &ST = Func.getSubtarget<X86Subtarget>();
>    OptIncDec = !ST.slowIncDec() || Func.getFunction()->optForMinSize();
> -  OptLEA = ST.LEAusesAG() || ST.slowLEA();
> +  OptLEA = ST.LEAusesAG() || ST.slowLEA() || ST.slow3OpsLEA();
>
>    if (!OptLEA && !OptIncDec)
>      return false;
> @@ -242,9 +273,64 @@ FixupLEAPass::searchBackwards(MachineOpe
>    return MachineBasicBlock::iterator();
>  }
>
> -static inline bool isLEA(const int opcode) {
> -  return opcode == X86::LEA16r || opcode == X86::LEA32r ||
> -         opcode == X86::LEA64r || opcode == X86::LEA64_32r;
> +static inline bool isLEA(const int Opcode) {
> +  return Opcode == X86::LEA16r || Opcode == X86::LEA32r ||
> +         Opcode == X86::LEA64r || Opcode == X86::LEA64_32r;
> +}
> +
> +static inline bool isInefficientLEAReg(unsigned int Reg) {
> +  return Reg == X86::EBP || Reg == X86::RBP || Reg == X86::R13;
> +}
> +
> +static inline bool isRegOperand(const MachineOperand &Op) {
> +  return Op.isReg() && Op.getReg() != X86::NoRegister;
> +}
> +/// hasIneffecientLEARegs - LEA that uses base and index registers
> +/// where the base is EBP, RBP, or R13
> +static inline bool hasInefficientLEABaseReg(const MachineOperand &Base,
> +                                            const MachineOperand &Index) {
> +  return Base.isReg() && isInefficientLEAReg(Base.getReg()) &&
> +         isRegOperand(Index);
> +}
> +
> +static inline bool hasLEAOffset(const MachineOperand &Offset) {
> +  return (Offset.isImm() && Offset.getImm() != 0) || Offset.isGlobal();
> +}
> +
> +// LEA instruction that has all three operands: offset, base and index
> +static inline bool isThreeOperandsLEA(const MachineOperand &Base,
> +                                      const MachineOperand &Index,
> +                                      const MachineOperand &Offset) {
> +  return isRegOperand(Base) && isRegOperand(Index) &&
> hasLEAOffset(Offset);
> +}
> +
> +static inline int getADDrrFromLEA(int LEAOpcode) {
> +  switch (LEAOpcode) {
> +  default:
> +    llvm_unreachable("Unexpected LEA instruction");
> +  case X86::LEA16r:
> +    return X86::ADD16rr;
> +  case X86::LEA32r:
> +    return X86::ADD32rr;
> +  case X86::LEA64_32r:
> +  case X86::LEA64r:
> +    return X86::ADD64rr;
> +  }
> +}
> +
> +static inline int getADDriFromLEA(int LEAOpcode, const MachineOperand
> &Offset) {
> +  bool IsInt8 = Offset.isImm() && isInt<8>(Offset.getImm());
> +  switch (LEAOpcode) {
> +  default:
> +    llvm_unreachable("Unexpected LEA instruction");
> +  case X86::LEA16r:
> +    return IsInt8 ? X86::ADD16ri8 : X86::ADD16ri;
> +  case X86::LEA32r:
> +  case X86::LEA64_32r:
> +    return IsInt8 ? X86::ADD32ri8 : X86::ADD32ri;
> +  case X86::LEA64r:
> +    return IsInt8 ? X86::ADD64ri8 : X86::ADD64ri32;
> +  }
>  }
>
>  /// isLEASimpleIncOrDec - Does this LEA have one these forms:
> @@ -337,8 +423,8 @@ void FixupLEAPass::seekLEAFixup(MachineO
>  void FixupLEAPass::processInstructionForSLM(MachineBasicBlock::iterator
> &I,
>                                              MachineFunction::iterator
> MFI) {
>    MachineInstr &MI = *I;
> -  const int opcode = MI.getOpcode();
> -  if (!isLEA(opcode))
> +  const int Opcode = MI.getOpcode();
> +  if (!isLEA(Opcode))
>      return;
>    if (MI.getOperand(5).getReg() != 0 || !MI.getOperand(4).isImm() ||
>        !TII->isSafeToClobberEFLAGS(*MFI, I))
> @@ -350,53 +436,142 @@ void FixupLEAPass::processInstructionFor
>      return;
>    if (MI.getOperand(2).getImm() > 1)
>      return;
> -  int addrr_opcode, addri_opcode;
> -  switch (opcode) {
> -  default:
> -    llvm_unreachable("Unexpected LEA instruction");
> -  case X86::LEA16r:
> -    addrr_opcode = X86::ADD16rr;
> -    addri_opcode = X86::ADD16ri;
> -    break;
> -  case X86::LEA32r:
> -    addrr_opcode = X86::ADD32rr;
> -    addri_opcode = X86::ADD32ri;
> -    break;
> -  case X86::LEA64_32r:
> -  case X86::LEA64r:
> -    addrr_opcode = X86::ADD64rr;
> -    addri_opcode = X86::ADD64ri32;
> -    break;
> -  }
>    DEBUG(dbgs() << "FixLEA: Candidate to replace:"; I->dump(););
>    DEBUG(dbgs() << "FixLEA: Replaced by: ";);
>    MachineInstr *NewMI = nullptr;
> -  const MachineOperand &Dst = MI.getOperand(0);
>    // Make ADD instruction for two registers writing to LEA's destination
>    if (SrcR1 != 0 && SrcR2 != 0) {
> -    const MachineOperand &Src1 = MI.getOperand(SrcR1 == DstR ? 1 : 3);
> -    const MachineOperand &Src2 = MI.getOperand(SrcR1 == DstR ? 3 : 1);
> -    NewMI = BuildMI(*MF, MI.getDebugLoc(), TII->get(addrr_opcode))
> -                .add(Dst)
> -                .add(Src1)
> -                .add(Src2);
> -    MFI->insert(I, NewMI);
> +    const MCInstrDesc &ADDrr = TII->get(getADDrrFromLEA(Opcode));
> +    const MachineOperand &Src = MI.getOperand(SrcR1 == DstR ? 3 : 1);
> +    NewMI =
> +        BuildMI(*MFI, I, MI.getDebugLoc(), ADDrr,
> DstR).addReg(DstR).add(Src);
>      DEBUG(NewMI->dump(););
>    }
>    // Make ADD instruction for immediate
>    if (MI.getOperand(4).getImm() != 0) {
> +    const MCInstrDesc &ADDri =
> +        TII->get(getADDriFromLEA(Opcode, MI.getOperand(4)));
>      const MachineOperand &SrcR = MI.getOperand(SrcR1 == DstR ? 1 : 3);
> -    NewMI = BuildMI(*MF, MI.getDebugLoc(), TII->get(addri_opcode))
> -                .add(Dst)
> +    NewMI = BuildMI(*MFI, I, MI.getDebugLoc(), ADDri, DstR)
>                  .add(SrcR)
>                  .addImm(MI.getOperand(4).getImm());
> -    MFI->insert(I, NewMI);
>      DEBUG(NewMI->dump(););
>    }
>    if (NewMI) {
>      MFI->erase(I);
> -    I = static_cast<MachineBasicBlock::iterator>(NewMI);
> +    I = NewMI;
> +  }
> +}
> +
> +MachineInstr *
> +FixupLEAPass::processInstrForSlow3OpLEA(MachineInstr &MI,
> +                                        MachineFunction::iterator MFI) {
> +
> +  const int LEAOpcode = MI.getOpcode();
> +  if (!isLEA(LEAOpcode))
> +    return nullptr;
> +
> +  const MachineOperand &Dst = MI.getOperand(0);
> +  const MachineOperand &Base = MI.getOperand(1);
> +  const MachineOperand &Scale = MI.getOperand(2);
> +  const MachineOperand &Index = MI.getOperand(3);
> +  const MachineOperand &Offset = MI.getOperand(4);
> +  const MachineOperand &Segment = MI.getOperand(5);
> +
> +  if (!(isThreeOperandsLEA(Base, Index, Offset) ||
> +        hasInefficientLEABaseReg(Base, Index)) ||
> +      !TII->isSafeToClobberEFLAGS(*MFI, MI) ||
> +      Segment.getReg() != X86::NoRegister)
> +    return nullptr;
> +
> +  unsigned int DstR = Dst.getReg();
> +  unsigned int BaseR = Base.getReg();
> +  unsigned int IndexR = Index.getReg();
> +  unsigned SSDstR =
> +      (LEAOpcode == X86::LEA64_32r) ? getX86SubSuperRegister(DstR, 64) :
> DstR;
> +  bool IsScale1 = Scale.getImm() == 1;
> +  bool IsInefficientBase = isInefficientLEAReg(BaseR);
> +  bool IsInefficientIndex = isInefficientLEAReg(IndexR);
> +
> +  // Skip these cases since it takes more than 2 instructions
> +  // to replace the LEA instruction.
> +  if (IsInefficientBase && SSDstR == BaseR && !IsScale1)
> +    return nullptr;
> +  if (LEAOpcode == X86::LEA64_32r && IsInefficientBase &&
> +      (IsInefficientIndex || !IsScale1))
> +    return nullptr;
> +
> +  const DebugLoc DL = MI.getDebugLoc();
> +  const MCInstrDesc &ADDrr = TII->get(getADDrrFromLEA(LEAOpcode));
> +  const MCInstrDesc &ADDri = TII->get(getADDriFromLEA(LEAOpcode,
> Offset));
> +
> +  DEBUG(dbgs() << "FixLEA: Candidate to replace:"; MI.dump(););
> +  DEBUG(dbgs() << "FixLEA: Replaced by: ";);
> +
> +  // First try to replace LEA with one or two (for the 3-op LEA case)
> +  // add instructions:
> +  // 1.lea (%base,%index,1), %base => add %index,%base
> +  // 2.lea (%base,%index,1), %index => add %base,%index
> +  if (IsScale1 && (DstR == BaseR || DstR == IndexR)) {
> +    const MachineOperand &Src = DstR == BaseR ? Index : Base;
> +    MachineInstr *NewMI =
> +        BuildMI(*MFI, MI, DL, ADDrr, DstR).addReg(DstR).add(Src);
> +    DEBUG(NewMI->dump(););
> +    // Create ADD instruction for the Offset in case of 3-Ops LEA.
> +    if (hasLEAOffset(Offset)) {
> +      NewMI = BuildMI(*MFI, MI, DL, ADDri, DstR).addReg(DstR).add(Offset)
> ;
> +      DEBUG(NewMI->dump(););
> +    }
> +    return NewMI;
>    }
> +  // If the base is inefficient try switching the index and base operands,
> +  // otherwise just break the 3-Ops LEA inst into 2-Ops LEA + ADD
> instruction:
> +  // lea offset(%base,%index,scale),%dst =>
> +  // lea (%base,%index,scale); add offset,%dst
> +  if (!IsInefficientBase || (!IsInefficientIndex && IsScale1)) {
> +    MachineInstr *NewMI = BuildMI(*MFI, MI, DL, TII->get(LEAOpcode))
> +                              .add(Dst)
> +                              .add(IsInefficientBase ? Index : Base)
> +                              .add(Scale)
> +                              .add(IsInefficientBase ? Base : Index)
> +                              .addImm(0)
> +                              .add(Segment);
> +    DEBUG(NewMI->dump(););
> +    // Create ADD instruction for the Offset in case of 3-Ops LEA.
> +    if (hasLEAOffset(Offset)) {
> +      NewMI = BuildMI(*MFI, MI, DL, ADDri, DstR).addReg(DstR).add(Offset)
> ;
> +      DEBUG(NewMI->dump(););
> +    }
> +    return NewMI;
> +  }
> +  // Handle the rest of the cases with inefficient base register:
> +  assert(SSDstR != BaseR && "SSDstR == BaseR should be handled already!");
> +  assert(IsInefficientBase && "efficient base should be handled
> already!");
> +
> +  // lea (%base,%index,1), %dst => mov %base,%dst; add %index,%dst
> +  if (IsScale1 && !hasLEAOffset(Offset)) {
> +    TII->copyPhysReg(*MFI, MI, DL, DstR, BaseR, Base.isKill());
> +    DEBUG(MI.getPrevNode()->dump(););
> +
> +    MachineInstr *NewMI =
> +        BuildMI(*MFI, MI, DL, ADDrr, DstR).addReg(DstR).add(Index);
> +    DEBUG(NewMI->dump(););
> +    return NewMI;
> +  }
> +  // lea offset(%base,%index,scale), %dst =>
> +  // lea offset( ,%index,scale), %dst; add %base,%dst
> +  MachineInstr *NewMI = BuildMI(*MFI, MI, DL, TII->get(LEAOpcode))
> +                            .add(Dst)
> +                            .addReg(0)
> +                            .add(Scale)
> +                            .add(Index)
> +                            .add(Offset)
> +                            .add(Segment);
> +  DEBUG(NewMI->dump(););
> +
> +  NewMI = BuildMI(*MFI, MI, DL, ADDrr, DstR).addReg(DstR).add(Base);
> +  DEBUG(NewMI->dump(););
> +  return NewMI;
>  }
>
>  bool FixupLEAPass::processBasicBlock(MachineFunction &MF,
> @@ -410,8 +585,16 @@ bool FixupLEAPass::processBasicBlock(Mac
>      if (OptLEA) {
>        if (MF.getSubtarget<X86Subtarget>().isSLM())
>          processInstructionForSLM(I, MFI);
> -      else
> -        processInstruction(I, MFI);
> +
> +      else {
> +        if (MF.getSubtarget<X86Subtarget>().slow3OpsLEA()) {
> +          if (auto *NewMI = processInstrForSlow3OpLEA(*I, MFI)) {
> +            MFI->erase(I);
> +            I = NewMI;
> +          }
> +        } else
> +          processInstruction(I, MFI);
> +      }
>      }
>    }
>    return false;
>
> Modified: llvm/trunk/lib/Target/X86/X86Subtarget.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/
> X86/X86Subtarget.h?rev=303183&r1=303182&r2=303183&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/Target/X86/X86Subtarget.h (original)
> +++ llvm/trunk/lib/Target/X86/X86Subtarget.h Tue May 16 11:01:36 2017
> @@ -253,6 +253,11 @@ protected:
>    /// True if the LEA instruction with certain arguments is slow
>    bool SlowLEA;
>
> +  /// True if the LEA instruction has all three source operands: base,
> index,
> +  /// and offset or if the LEA instruction uses base and index registers
> where
> +  /// the base is EBP, RBP,or R13
> +  bool Slow3OpsLEA;
> +
>    /// True if INC and DEC instructions are slow when writing to flags
>    bool SlowIncDec;
>
> @@ -490,6 +495,7 @@ public:
>    bool callRegIndirect() const { return CallRegIndirect; }
>    bool LEAusesAG() const { return LEAUsesAG; }
>    bool slowLEA() const { return SlowLEA; }
> +  bool slow3OpsLEA() const { return Slow3OpsLEA; }
>    bool slowIncDec() const { return SlowIncDec; }
>    bool hasCDI() const { return HasCDI; }
>    bool hasPFI() const { return HasPFI; }
>
> Modified: llvm/trunk/lib/Target/X86/X86TargetMachine.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/
> X86/X86TargetMachine.cpp?rev=303183&r1=303182&r2=303183&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/Target/X86/X86TargetMachine.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86TargetMachine.cpp Tue May 16 11:01:36
> 2017
> @@ -61,6 +61,7 @@ static cl::opt<bool> EnableMachineCombin
>  namespace llvm {
>
>  void initializeWinEHStatePassPass(PassRegistry &);
> +void initializeFixupLEAPassPass(PassRegistry &);
>  void initializeX86ExecutionDepsFixPass(PassRegistry &);
>
>  } // end namespace llvm
> @@ -75,6 +76,7 @@ extern "C" void LLVMInitializeX86Target(
>    initializeWinEHStatePassPass(PR);
>    initializeFixupBWInstPassPass(PR);
>    initializeEvexToVexInstPassPass(PR);
> +  initializeFixupLEAPassPass(PR);
>    initializeX86ExecutionDepsFixPass(PR);
>  }
>
>
> Added: llvm/trunk/test/CodeGen/X86/leaFixup32.mir
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
> CodeGen/X86/leaFixup32.mir?rev=303183&view=auto
> ============================================================
> ==================
> --- llvm/trunk/test/CodeGen/X86/leaFixup32.mir (added)
> +++ llvm/trunk/test/CodeGen/X86/leaFixup32.mir Tue May 16 11:01:36 2017
> @@ -0,0 +1,508 @@
> +# RUN: llc -run-pass x86-fixup-LEAs -mcpu=corei7-avx -o - %s | FileCheck
> %s
> +--- |
> +  ; ModuleID = 'test/CodeGen/X86/fixup-lea.ll'
> +  source_filename = "test/CodeGen/X86/fixup-lea.ll"
> +  target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
> +  target triple = "i386"
> +  ;generated using: llc -stop-after x86-pad-short-functions fixup-lea.ll
> > leaFinxup32.mir
> +
> +  ;test2add_32: 3 operands LEA32r that can be replaced with 2 add
> instructions
> +  ; where ADD32ri8 is chosen
> +  define i32 @test2add_32() {
> +    ret i32 0
> +  }
> +
> +  ;test2add_ebp_32: 3 operands LEA32r that can be replaced with 2 add
> instructions
> +  ; where the base is rbp/r13/ebp register
> +  define i32 @test2add_ebp_32() {
> +    ret i32 0
> +  }
> +
> +  ;test1add_ebp_32: 2 operands LEA32r where base register is ebp and can
> be replaced
> +  ; with an add instruction
> +  define i32 @test1add_ebp_32() {
> +    ret i32 0
> +  }
> +
> +  ;testleaadd_32: 3 operands LEA32r that can be replaced with 1 lea 1 add
> instructions
> +  define i32 @testleaadd_32() {
> +    ret i32 0
> +  }
> +
> +  ;testleaadd_ebp_32: 3 operands LEA32r that can be replaced with 1 lea 1
> add instructions
> +  ; where the base is ebp register
> +  define i32 @testleaadd_ebp_32() {
> +    ret i32 0
> +  }
> +
> +  ;test1lea_ebp_32: 2 operands LEA32r wher base register is rbp/r13/ebp
> and can be replaced
> +  ; with a lea instruction
> +  define i32 @test1lea_ebp_32() {
> +    ret i32 0
> +  }
> +
> +  ;test2addi32_32: 3 operands LEA32r that can be replaced with 2 add
> instructions where ADD32ri32
> +  ; is chosen
> +  define i32 @test2addi32_32() {
> +    ret i32 0
> +  }
> +
> +  ;test1mov1add_ebp_32: 2 operands LEA32r that can be replaced with 1 add
> 1 mov instructions
> +  ; where the base is rbp/r13/ebp register
> +  define i32 @test1mov1add_ebp_32() {
> +    ret i32 0
> +  }
> +
> +  ;testleaadd_ebp_index_32: 3 operands LEA32r that can be replaced with 1
> lea 1 add instructions
> +  ; where the base and the index are ebp register and there is offset
> +  define i32 @testleaadd_ebp_index_32() {
> +    ret i32 0
> +  }
> +
> +  ;testleaadd_ebp_index2_32: 3 operands LEA32r that can be replaced with
> 1 lea 1 add instructions
> +  ; where the base and the index are ebp register and there is scale
> +  define i32 @testleaadd_ebp_index2_32() {
> +    ret i32 0
> +  }
> +
> +  ;test_skip_opt_32: 3 operands LEA32r that can not be replaced with 2
> instructions
> +  define i32 @test_skip_opt_32() {
> +    ret i32 0
> +  }
> +
> +  ;test_skip_eflags_32: LEA32r that cannot be replaced since its not safe
> to clobber eflags
> +  define i32 @test_skip_eflags_32() {
> +    ret i32 0
> +  }
> +
> +...
> +---
> +name:            test2add_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%eax' }
> +  - { reg: '%ebp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %eax, %ebp
> +    ; CHECK: %eax = ADD32rr %eax, killed %ebp
> +    ; CHECK: %eax = ADD32ri8 %eax, -5
> +
> +    %eax = LEA32r killed %eax, 1, killed %ebp, -5, _
> +    RETQ %eax
> +
> +...
> +---
> +name:            test2add_ebp_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%eax' }
> +  - { reg: '%ebp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %eax, %ebp
> +    ; CHECK: %ebp = ADD32rr %ebp, killed %eax
> +    ; CHECK: %ebp = ADD32ri8 %ebp, -5
> +
> +    %ebp = LEA32r killed %ebp, 1, killed %eax, -5, _
> +    RETQ %ebp
> +
> +...
> +---
> +name:            test1add_ebp_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%eax' }
> +  - { reg: '%ebp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %eax, %ebp
> +    ; CHECK: %ebp = ADD32rr %ebp, killed %eax
> +
> +    %ebp = LEA32r killed %ebp, 1, killed %eax, 0, _
> +    RETQ %ebp
> +
> +...
> +---
> +name:            testleaadd_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%eax' }
> +  - { reg: '%ebp' }
> +  - { reg: '%ebx' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %eax, %ebp, %esi
> +    ; CHECK: %ebx = LEA32r killed %eax, 1, killed %ebp, 0
> +    ; CHECK: %ebx = ADD32ri8 %ebx, -5
> +
> +    %ebx = LEA32r killed %eax, 1, killed %ebp, -5, _
> +    RETQ %ebx
> +
> +...
> +---
> +name:            testleaadd_ebp_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%eax' }
> +  - { reg: '%ebp' }
> +  - { reg: '%ebx' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %eax, %ebp
> +    ; CHECK: %ebx = LEA32r killed %eax, 1, killed %ebp, 0, _
> +    ; CHECK: %ebx = ADD32ri8  %ebx, -5
> +
> +    %ebx = LEA32r killed %ebp, 1, killed %eax, -5, _
> +    RETQ %ebx
> +
> +...
> +---
> +name:            test1lea_ebp_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%eax' }
> +  - { reg: '%ebp' }
> +  - { reg: '%ebx' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %eax, %ebp
> +    ; CHECK: %ebx = LEA32r killed %eax, 1, killed %ebp, 0, _
> +
> +    %ebx = LEA32r killed %ebp, 1, killed %eax, 0, _
> +    RETQ %ebx
> +
> +...
> +---
> +name:            test2addi32_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%eax' }
> +  - { reg: '%ebp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %eax, %ebp
> +    ; CHECK: %eax = ADD32rr %eax, killed %ebp
> +    ; CHECK: %eax = ADD32ri %eax, 129
> +
> +    %eax = LEA32r killed %eax, 1, killed %ebp, 129, _
> +    RETQ %eax
> +
> +...
> +---
> +name:            test1mov1add_ebp_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%eax' }
> +  - { reg: '%ebp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %eax, %ebp, %ebx
> +    ; CHECK: %ebx = MOV32rr killed %ebp
> +    ; CHECK: %ebx = ADD32rr %ebx, killed %ebp
> +
> +    %ebx = LEA32r killed %ebp, 1, killed %ebp, 0, _
> +    RETQ %ebx
> +
> +...
> +---
> +name:            testleaadd_ebp_index_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%ebx' }
> +  - { reg: '%ebp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %eax, %ebp, %ebx
> +    ; CHECK: %ebx = LEA32r _, 1, killed %ebp, 5, _
> +    ; CHECK: %ebx = ADD32rr %ebx, killed %ebp
> +
> +    %ebx = LEA32r killed %ebp, 1, killed %ebp, 5, _
> +    RETQ %ebx
> +
> +...
> +---
> +name:            testleaadd_ebp_index2_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%ebx' }
> +  - { reg: '%ebp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %eax, %ebp, %ebx
> +    ; CHECK: %ebx = LEA32r _, 4, killed %ebp, 5, _
> +    ; CHECK: %ebx = ADD32rr %ebx, killed %ebp
> +
> +    %ebx = LEA32r killed %ebp, 4, killed %ebp, 5, _
> +    RETQ %ebx
> +
> +...
> +---
> +name:            test_skip_opt_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%ebx' }
> +  - { reg: '%ebp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %eax, %ebp, %ebx
> +    ; CHECK: %ebp = LEA32r killed %ebp, 4, killed %ebp, 0, _
> +
> +    %ebp = LEA32r killed %ebp, 4, killed %ebp, 0, _
> +    RETQ %ebp
> +
> +...
> +---
> +name:            test_skip_eflags_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%ebp' }
> +  - { reg: '%eax' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %eax, %ebp, %ebx
> +    ; CHECK: %ebx = LEA32r killed %eax, 4, killed %eax, 5, _
> +    ; CHECK: %ebp = LEA32r killed %ebx, 4, killed %ebx, 0, _
> +    ; CHECK: %ebp = ADD32ri8 %ebp, 5
> +
> +    CMP32rr   %eax, killed %ebx, implicit-def %eflags
> +    %ebx = LEA32r killed %eax, 4, killed %eax, 5, _
> +    JE_1 %bb.1, implicit %eflags
> +    RETQ %ebx
> +  bb.1:
> +    liveins: %eax, %ebp, %ebx
> +    %ebp = LEA32r killed %ebx, 4, killed %ebx, 5, _
> +    RETQ %ebp
> +
> +...
> +
> +
> +
>
> Added: llvm/trunk/test/CodeGen/X86/leaFixup64.mir
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
> CodeGen/X86/leaFixup64.mir?rev=303183&view=auto
> ============================================================
> ==================
> --- llvm/trunk/test/CodeGen/X86/leaFixup64.mir (added)
> +++ llvm/trunk/test/CodeGen/X86/leaFixup64.mir Tue May 16 11:01:36 2017
> @@ -0,0 +1,1041 @@
> +# RUN: llc -run-pass x86-fixup-LEAs -mcpu=corei7-avx -o - %s | FileCheck
> %s
> +--- |
> +  ; ModuleID = 'lea-2.ll'
> +  source_filename = "lea-2.ll"
> +  target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> +  ;generated using: llc -stop-after x86-pad-short-functions lea-2.ll >
> leaFinxup64.mir
> +
> +  ;testleaadd_64_32_1: 3 operands LEA64_32r cannot be replaced with 2 add
> instructions
> +  ; but can be replaced with 1 lea + 1 add
> +  define i32 @testleaadd_64_32_1() {
> +    ret i32 0
> +  }
> +
> +  ;testleaadd_rbp_64_32_1: 3 operands LEA64_32r cannot be replaced with 2
> add instructions
> +  ; where the base is rbp/r13/ebp register but it can be replaced with 1
> lea + 1 add
> +  define i32 @testleaadd_rbp_64_32_1() {
> +    ret i32 0
> +  }
> +
> +  ;test1lea_rbp_64_32_1: 2 operands LEA64_32r where base register is
> rbp/r13/ebp and can not
> +  ; be replaced with an add instruction but can be replaced with 1 lea
> instruction
> +  define i32 @test1lea_rbp_64_32_1() {
> +    ret i32 0
> +  }
> +
> +  ;test2add_64: 3 operands LEA64r that can be replaced with 2 add
> instructions
> +  define i32 @test2add_64() {
> +    ret i32 0
> +  }
> +
> +  ;test2add_rbp_64: 3 operands LEA64r that can be replaced with 2 add
> instructions
> +  ; where the base is rbp/r13/ebp register
> +  define i32 @test2add_rbp_64() {
> +    ret i32 0
> +  }
> +
> +  ;test1add_rbp_64: 2 operands LEA64r where base register is rbp/r13/ebp
> and can be replaced
> +  ; with an add instruction
> +  define i32 @test1add_rbp_64() {
> +    ret i32 0
> +  }
> +
> +  ;testleaadd_64_32: 3 operands LEA64_32r that can be replaced with 1 lea
> 1 add instructions
> +  define i32 @testleaadd_64_32() {
> +    ret i32 0
> +  }
> +
> +  ;testleaadd_rbp_64_32: 3 operands LEA64_32r that can be replaced with 1
> lea 1 add instructions
> +  ; where the base is rbp/r13/ebp register
> +  define i32 @testleaadd_rbp_64_32() {
> +    ret i32 0
> +  }
> +
> +  ;test1lea_rbp_64_32: 2 operands LEA64_32r where base register is
> rbp/r13/ebp and can be replaced
> +  ; with a lea instruction
> +  define i32 @test1lea_rbp_64_32() {
> +    ret i32 0
> +  }
> +
> +  ;testleaadd_64: 3 operands LEA64r that can be replaced with 1 lea 1 add
> instructions
> +  define i32 @testleaadd_64() {
> +    ret i32 0
> +  }
> +
> +  ;testleaadd_rbp_64: 3 operands LEA64r that can be replaced with 1 lea 1
> add instructions
> +  ; where the base is rbp/r13/ebp register
> +  define i32 @testleaadd_rbp_64() {
> +    ret i32 0
> +  }
> +
> +  ;test1lea_rbp_64: 2 operands LEA64r wher base register is rbp/r13/ebp
> and can be replaced
> +  ; with a lea instruction
> +  define i32 @test1lea_rbp_64() {
> +    ret i32 0
> +  }
> +
> +  ;test8: dst = base & scale!=1, can't optimize
> +  define i32 @test8() {
> +      ret i32 0
> +  }
> +
> +  ;testleaaddi32_64_32: 3 operands LEA64_32r that can be replaced with 1
> lea + 1 add instructions where
> +  ; ADD64ri32 is chosen
> +  define i32 @testleaaddi32_64_32() {
> +    ret i32 0
> +  }
> +
> +  ;test1mov1add_rbp_64_32: 2 operands LEA64_32r cannot be replaced with 1
> add 1 mov instructions
> +  ; where the base is rbp/r13/ebp register
> +  define i32 @test1mov1add_rbp_64_32() {
> +    ret i32 0
> +  }
> +
> +  ;testleaadd_rbp_index_64_32: 3 operands LEA64_32r that cannot replaced
> with 1 lea 1 add instructions
> +  ; where the base and the index are ebp register and there is offset
> +  define i32 @testleaadd_rbp_index_64_32() {
> +    ret i32 0
> +  }
> +
> +  ;testleaadd_rbp_index2_64_32: 3 operands LEA64_32r that cannot replaced
> with 1 lea 1 add instructions
> +  ; where the base and the index are ebp register and there is scale
> +  define i32 @testleaadd_rbp_index2_64_32() {
> +    ret i32 0
> +  }
> +
> +  ;test2addi32_64: 3 operands LEA64r that can be replaced with 2 add
> instructions where ADD64ri32
> +  ; is chosen
> +  define i32 @test2addi32_64() {
> +    ret i32 0
> +  }
> +
> +  ;test1mov1add_rbp_64: 2 operands LEA64r that can be replaced with 1 add
> 1 mov instructions
> +  ; where the base is rbp/r13/ebp register
> +  define i32 @test1mov1add_rbp_64() {
> +    ret i32 0
> +  }
> +
> +  ;testleaadd_rbp_index_64: 3 operands LEA64r that can be replaced with 1
> lea 1 add instructions
> +  ; where the base and the index are ebp register and there is offset
> +  define i32 @testleaadd_rbp_index_64() {
> +    ret i32 0
> +  }
> +
> +  ;testleaadd_rbp_index2_64: 3 operands LEA64r that can be replaced with
> 1 lea 1 add instructions
> +  ; where the base and the index are ebp register and there is scale
> +  define i32 @testleaadd_rbp_index2_64() {
> +    ret i32 0
> +  }
> +
> +  ;test_skip_opt_64: 3 operands LEA64r that can not be replaced with 2
> instructions
> +  define i32 @test_skip_opt_64() {
> +    ret i32 0
> +  }
> +
> +  ;test_skip_eflags_64: LEA64r that cannot be replaced since its not safe
> to clobber eflags
> +  define i32 @test_skip_eflags_64() {
> +    ret i32 0
> +  }
> +
> +  ;test_skip_opt_64_32: 3 operands LEA64_32r that can not be replaced
> with 2 instructions
> +  define i32 @test_skip_opt_64_32() {
> +    ret i32 0
> +  }
> +
> +  ;test_skip_eflags_64_32: LEA64_32r that cannot be replaced since its
> not safe to clobber eflags
> +  define i32 @test_skip_eflags_64_32() {
> +    ret i32 0
> +  }
> +
> +
> +...
> +---
> +name:            testleaadd_64_32_1
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rax' }
> +  - { reg: '%rbp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp
> +    ; CHECK: %eax = LEA64_32r killed %rax, 1, killed %rbp, 0
> +    ; CHECK: %eax = ADD32ri8 %eax, -5
> +
> +    %eax = LEA64_32r killed %rax, 1, killed %rbp, -5, _
> +    RETQ %eax
> +
> +...
> +---
> +name:            testleaadd_rbp_64_32_1
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rax' }
> +  - { reg: '%rbp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp
> +    ; CHECK: %ebp = LEA64_32r killed %rax, 1,  killed %rbp, 0
> +    ; CHECK: %ebp = ADD32ri8 %ebp, -5
> +
> +    %ebp = LEA64_32r killed %rbp, 1, killed %rax, -5, _
> +    RETQ %ebp
> +
> +...
> +---
> +name:            test1lea_rbp_64_32_1
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rax' }
> +  - { reg: '%rbp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp
> +    ; CHECK: %ebp = LEA64_32r killed %rax, 1, killed %rbp, 0
> +
> +    %ebp = LEA64_32r killed %rbp, 1, killed %rax, 0, _
> +    RETQ %ebp
> +
> +...
> +---
> +name:            test2add_64
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rax' }
> +  - { reg: '%rbp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp
> +    ; CHECK: %rax = ADD64rr %rax, killed %rbp
> +    ; CHECK: %rax = ADD64ri8 %rax, -5
> +
> +    %rax = LEA64r killed %rax, 1, killed %rbp, -5, _
> +    RETQ %eax
> +
> +...
> +---
> +name:            test2add_rbp_64
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rax' }
> +  - { reg: '%rbp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp
> +    ; CHECK: %rbp = ADD64rr %rbp, killed %rax
> +    ; CHECK: %rbp = ADD64ri8 %rbp, -5
> +
> +    %rbp = LEA64r killed %rbp, 1, killed %rax, -5, _
> +    RETQ %ebp
> +
> +...
> +---
> +name:            test1add_rbp_64
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rax' }
> +  - { reg: '%rbp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp
> +    ; CHECK: %rbp = ADD64rr %rbp, killed %rax
> +
> +    %rbp = LEA64r killed %rbp, 1, killed %rax, 0, _
> +    RETQ %ebp
> +
> +...
> +---
> +name:            testleaadd_64_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rax' }
> +  - { reg: '%rbp' }
> +  - { reg: '%rbx' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp
> +    ; CHECK: %ebx = LEA64_32r killed %rax, 1, killed %rbp, 0, _
> +    ; CHECK: %ebx = ADD32ri8 %ebx, -5
> +
> +    %ebx = LEA64_32r killed %rax, 1, killed %rbp, -5, _
> +    RETQ %ebx
> +
> +...
> +---
> +name:            testleaadd_rbp_64_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rax' }
> +  - { reg: '%rbp' }
> +  - { reg: '%rbx' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp
> +    ; CHECK: %ebx = LEA64_32r killed %rax, 1, killed %rbp, 0, _
> +    ; CHECK: %ebx = ADD32ri8 %ebx, -5
> +
> +    %ebx = LEA64_32r killed %rbp, 1, killed %rax, -5, _
> +    RETQ %ebx
> +
> +...
> +---
> +name:            test1lea_rbp_64_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rax' }
> +  - { reg: '%rbp' }
> +  - { reg: '%rbx' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp
> +    ; CHECK: %ebx = LEA64_32r killed %rax, 1, killed %rbp, 0, _
> +
> +    %ebx = LEA64_32r killed %rbp, 1, killed %rax, 0, _
> +    RETQ %ebx
> +
> +...
> +---
> +name:            testleaadd_64
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rax' }
> +  - { reg: '%rbp' }
> +  - { reg: '%rbx' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp
> +    ; CHECK: %rbx = LEA64r killed %rax, 1, killed %rbp, 0, _
> +    ; CHECK: %rbx = ADD64ri8 %rbx, -5
> +
> +    %rbx = LEA64r killed %rax, 1, killed %rbp, -5, _
> +    RETQ %ebx
> +
> +...
> +---
> +name:            testleaadd_rbp_64
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rax' }
> +  - { reg: '%rbp' }
> +  - { reg: '%rbx' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp
> +    ; CHECK: %rbx = LEA64r killed %rax, 1, killed %rbp, 0, _
> +    ; CHECK: %rbx = ADD64ri8 %rbx, -5
> +
> +    %rbx = LEA64r killed %rbp, 1, killed %rax, -5, _
> +    RETQ %ebx
> +
> +...
> +---
> +name:            test1lea_rbp_64
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rax' }
> +  - { reg: '%rbp' }
> +  - { reg: '%rbx' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp
> +    ; CHECK: %rbx = LEA64r killed %rax, 1, killed %rbp, 0, _
> +
> +    %rbx = LEA64r killed %rbp, 1, killed %rax, 0, _
> +    RETQ %ebx
> +
> +...
> +---
> +name:            test8
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rdi' }
> +  - { reg: '%rbp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rdi, %rbp
> +    ; CHECK:  %r12 = LEA64r _, 2, killed %r13, 5, _
> +    ; CHECK:  %r12 = ADD64rr %r12, killed %rbp
> +    %rbp = KILL %rbp, implicit-def %rbp
> +    %r13 = KILL %rdi, implicit-def %r13
> +    %r12 = LEA64r killed %rbp, 2, killed %r13, 5, _
> +    RETQ %r12
> +
> +...
> +---
> +name:            testleaaddi32_64_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rax' }
> +  - { reg: '%rbp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp
> +    ; CHECK: %eax = LEA64_32r killed %rax, 1, killed %rbp, 0
> +    ; CHECK: %eax = ADD32ri %eax, 129
> +
> +    %eax = LEA64_32r killed %rax, 1, killed %rbp, 129, _
> +    RETQ %eax
> +
> +...
> +---
> +name:            test1mov1add_rbp_64_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rax' }
> +  - { reg: '%rbp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp, %rbx
> +    ; CHECK: %ebx = LEA64_32r killed %rbp, 1, killed %rbp, 0, _
> +
> +    %ebx = LEA64_32r killed %rbp, 1, killed %rbp, 0, _
> +    RETQ %ebx
> +
> +...
> +---
> +name:            testleaadd_rbp_index_64_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rbx' }
> +  - { reg: '%rbp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp, %rbx
> +    ; CHECK: %ebx = LEA64_32r killed %rbp, 1, killed %rbp, 5, _
> +
> +    %ebx = LEA64_32r killed %rbp, 1, killed %rbp, 5, _
> +    RETQ %ebx
> +
> +...
> +---
> +name:            testleaadd_rbp_index2_64_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rbx' }
> +  - { reg: '%rbp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %eax, %ebp, %ebx
> +    ; CHECK: %ebx = LEA64_32r killed %rbp, 4, killed %rbp, 5, _
> +
> +    %ebx = LEA64_32r killed %rbp, 4, killed %rbp, 5, _
> +    RETQ %ebx
> +
> +...
> +---
> +name:            test2addi32_64
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rax' }
> +  - { reg: '%rbp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp
> +    ; CHECK: %rax = ADD64rr %rax, killed %rbp
> +    ; CHECK: %rax = ADD64ri32 %rax, 129
> +
> +    %rax = LEA64r killed %rax, 1, killed %rbp, 129, _
> +    RETQ %eax
> +
> +...
> +---
> +name:            test1mov1add_rbp_64
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rax' }
> +  - { reg: '%rbp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp, %rbx
> +    ; CHECK: %rbx = MOV64rr killed %rbp
> +    ; CHECK: %rbx = ADD64rr %rbx, killed %rbp
> +
> +    %rbx = LEA64r killed %rbp, 1, killed %rbp, 0, _
> +    RETQ %ebx
> +
> +...
> +---
> +name:            testleaadd_rbp_index_64
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rbx' }
> +  - { reg: '%rbp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp, %rbx
> +    ; CHECK: %rbx = LEA64r _, 1, killed %rbp, 5, _
> +    ; CHECK: %rbx = ADD64rr %rbx, killed %rbp
> +
> +    %rbx = LEA64r killed %rbp, 1, killed %rbp, 5, _
> +    RETQ %ebx
> +
> +...
> +---
> +name:            testleaadd_rbp_index2_64
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rbx' }
> +  - { reg: '%rbp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp, %rbx
> +    ; CHECK: %rbx = LEA64r _, 4, killed %rbp, 5, _
> +    ; CHECK: %rbx = ADD64rr %rbx, killed %rbp
> +
> +    %rbx = LEA64r killed %rbp, 4, killed %rbp, 5, _
> +    RETQ %ebx
> +
> +...
> +---
> +name:            test_skip_opt_64
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rbx' }
> +  - { reg: '%rbp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp, %rbx
> +    ; CHECK: %rbp = LEA64r killed %rbp, 4, killed %rbp, 0, _
> +
> +    %rbp = LEA64r killed %rbp, 4, killed %rbp, 0, _
> +    RETQ %ebp
> +
> +...
> +---
> +name:            test_skip_eflags_64
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rbp' }
> +  - { reg: '%rax' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp, %rbx
> +    ; CHECK: %rbx = LEA64r killed %rax, 4, killed %rax, 5, _
> +    ; CHECK: %rbp = LEA64r killed %rbx, 4, killed %rbx, 0, _
> +    ; CHECK: %rbp = ADD64ri8 %rbp, 5
> +
> +    CMP64rr   %rax, killed %rbx, implicit-def %eflags
> +    %rbx = LEA64r killed %rax, 4, killed %rax, 5, _
> +    JE_1 %bb.1, implicit %eflags
> +    RETQ %ebx
> +  bb.1:
> +    liveins: %rax, %rbp, %rbx
> +    %rbp = LEA64r killed %rbx, 4, killed %rbx, 5, _
> +    RETQ %ebp
> +
> +...
> +---
> +name:            test_skip_opt_64_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rbx' }
> +  - { reg: '%rbp' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp, %rbx
> +    ; CHECK: %ebp = LEA64_32r killed %rbp, 4, killed %rbp, 0, _
> +
> +    %ebp = LEA64_32r killed %rbp, 4, killed %rbp, 0, _
> +    RETQ %ebp
> +
> +...
> +---
> +name:            test_skip_eflags_64_32
> +alignment:       4
> +exposesReturnsTwice: false
> +legalized:       false
> +regBankSelected: false
> +selected:        false
> +tracksRegLiveness: true
> +liveins:
> +  - { reg: '%rbp' }
> +  - { reg: '%rax' }
> +frameInfo:
> +  isFrameAddressTaken: false
> +  isReturnAddressTaken: false
> +  hasStackMap:     false
> +  hasPatchPoint:   false
> +  stackSize:       0
> +  offsetAdjustment: 0
> +  maxAlignment:    0
> +  adjustsStack:    false
> +  hasCalls:        false
> +  maxCallFrameSize: 0
> +  hasOpaqueSPAdjustment: false
> +  hasVAStart:      false
> +  hasMustTailInVarArgFunc: false
> +body:             |
> +  bb.0 (%ir-block.0):
> +    liveins: %rax, %rbp, %rbx
> +    ; CHECK: %ebx = LEA64_32r killed %rax, 4, killed %rax, 5, _
> +    ; CHECK: %ebp = LEA64_32r killed %rbx, 4, killed %rbx, 0, _
> +    ; CHECK: %ebp = ADD32ri8 %ebp, 5
> +
> +    CMP64rr   %rax, killed %rbx, implicit-def %eflags
> +    %ebx = LEA64_32r killed %rax, 4, killed %rax, 5, _
> +    JE_1 %bb.1, implicit %eflags
> +    RETQ %ebx
> +  bb.1:
> +    liveins: %rax, %rbp, %rbx
> +    %ebp = LEA64_32r killed %rbx, 4, killed %rbx, 5, _
> +    RETQ %ebp
> +
> +...
> +
> +
> +
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170516/0dffdf3a/attachment-0001.html>


More information about the llvm-commits mailing list