[llvm] r336978 - [LiveDebugValues] Tracking copying value between registers

Petar Jovanovic via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 13 01:24:27 PDT 2018


Author: petarj
Date: Fri Jul 13 01:24:26 2018
New Revision: 336978

URL: http://llvm.org/viewvc/llvm-project?rev=336978&view=rev
Log:
[LiveDebugValues] Tracking copying value between registers

During the execution of long functions or functions that have a lot of
inlined code it could come to the situation where tracked value could be
transferred from one register to another. The transfer is recognized only if
destination register is a callee saved register and if source register is
killed. We do not salvage caller-saved registers since there is a great
chance that killed register would outlive it.

Patch by Nikola Prica.

Differential Revision: https://reviews.llvm.org/D44016

Added:
    llvm/trunk/test/DebugInfo/MIR/ARM/live-debug-values-reg-copy.mir
    llvm/trunk/test/DebugInfo/MIR/Mips/live-debug-values-reg-copy.mir
    llvm/trunk/test/DebugInfo/MIR/X86/live-debug-values-reg-copy.mir
Modified:
    llvm/trunk/lib/CodeGen/LiveDebugValues.cpp

Modified: llvm/trunk/lib/CodeGen/LiveDebugValues.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveDebugValues.cpp?rev=336978&r1=336977&r2=336978&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveDebugValues.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveDebugValues.cpp Fri Jul 13 01:24:26 2018
@@ -40,6 +40,7 @@
 #include "llvm/CodeGen/TargetLowering.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/CodeGen/RegisterScavenging.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/DebugLoc.h"
@@ -82,6 +83,7 @@ private:
   const TargetRegisterInfo *TRI;
   const TargetInstrInfo *TII;
   const TargetFrameLowering *TFI;
+  BitVector CalleeSavedRegs;
   LexicalScopes LS;
 
   /// Keeps track of lexical scopes associated with a user value's source
@@ -179,11 +181,11 @@ private:
   using VarLocMap = UniqueVector<VarLoc>;
   using VarLocSet = SparseBitVector<>;
   using VarLocInMBB = SmallDenseMap<const MachineBasicBlock *, VarLocSet>;
-  struct SpillDebugPair {
-    MachineInstr *SpillInst;
+  struct TransferDebugPair {
+    MachineInstr *TransferInst;
     MachineInstr *DebugInst;
   };
-  using SpillMap = SmallVector<SpillDebugPair, 4>;
+  using TransferMap = SmallVector<TransferDebugPair, 4>;
 
   /// This holds the working set of currently open ranges. For fast
   /// access, this is done both as a set of VarLocIDs, and a map of
@@ -236,18 +238,23 @@ private:
   bool isSpillInstruction(const MachineInstr &MI, MachineFunction *MF,
                           unsigned &Reg);
   int extractSpillBaseRegAndOffset(const MachineInstr &MI, unsigned &Reg);
+  void insertTransferDebugPair(MachineInstr &MI, OpenRangesSet &OpenRanges,
+                               TransferMap &Transfers, VarLocMap &VarLocIDs,
+                               unsigned OldVarID, unsigned NewReg = 0);
 
   void transferDebugValue(const MachineInstr &MI, OpenRangesSet &OpenRanges,
                           VarLocMap &VarLocIDs);
   void transferSpillInst(MachineInstr &MI, OpenRangesSet &OpenRanges,
-                         VarLocMap &VarLocIDs, SpillMap &Spills);
+                         VarLocMap &VarLocIDs, TransferMap &Transfers);
+  void transferRegisterCopy(MachineInstr &MI, OpenRangesSet &OpenRanges,
+                            VarLocMap &VarLocIDs, TransferMap &Transfers);
   void transferRegisterDef(MachineInstr &MI, OpenRangesSet &OpenRanges,
                            const VarLocMap &VarLocIDs);
   bool transferTerminatorInst(MachineInstr &MI, OpenRangesSet &OpenRanges,
                               VarLocInMBB &OutLocs, const VarLocMap &VarLocIDs);
-  bool transfer(MachineInstr &MI, OpenRangesSet &OpenRanges,
-                VarLocInMBB &OutLocs, VarLocMap &VarLocIDs, SpillMap &Spills,
-                bool transferSpills);
+  bool process(MachineInstr &MI, OpenRangesSet &OpenRanges,
+               VarLocInMBB &OutLocs, VarLocMap &VarLocIDs,
+               TransferMap &Transfers, bool transferChanges);
 
   bool join(MachineBasicBlock &MBB, VarLocInMBB &OutLocs, VarLocInMBB &InLocs,
             const VarLocMap &VarLocIDs,
@@ -370,6 +377,54 @@ void LiveDebugValues::transferDebugValue
   }
 }
 
+/// Create new TransferDebugPair and insert it in \p Transfers. The VarLoc
+/// with \p OldVarID should be deleted form \p OpenRanges and replaced with
+/// new VarLoc. If \p NewReg is different than default zero value then the
+/// new location will be register location created by the copy like instruction,
+/// otherwise it is variable's location on the stack.
+void LiveDebugValues::insertTransferDebugPair(
+    MachineInstr &MI, OpenRangesSet &OpenRanges, TransferMap &Transfers,
+    VarLocMap &VarLocIDs, unsigned OldVarID, unsigned NewReg) {
+  const MachineInstr *DMI = &VarLocIDs[OldVarID].MI;
+  MachineFunction *MF = MI.getParent()->getParent();
+  MachineInstr *NewDMI;
+  if (NewReg) {
+    // Create a DBG_VALUE instruction to describe the Var in its new
+    // register location.
+    NewDMI = BuildMI(*MF, DMI->getDebugLoc(), DMI->getDesc(),
+                     DMI->isIndirectDebugValue(), NewReg,
+                     DMI->getDebugVariable(), DMI->getDebugExpression());
+    if (DMI->isIndirectDebugValue())
+      NewDMI->getOperand(1).setImm(DMI->getOperand(1).getImm());
+    LLVM_DEBUG(dbgs() << "Creating DBG_VALUE inst for register copy: ";
+               NewDMI->print(dbgs(), false, false, false, TII));
+  } else {
+    // Create a DBG_VALUE instruction to describe the Var in its spilled
+    // location.
+    unsigned SpillBase;
+    int SpillOffset = extractSpillBaseRegAndOffset(MI, SpillBase);
+    auto *SpillExpr = DIExpression::prepend(DMI->getDebugExpression(),
+                                            DIExpression::NoDeref, SpillOffset);
+    NewDMI = BuildMI(*MF, DMI->getDebugLoc(), DMI->getDesc(), true, SpillBase,
+                     DMI->getDebugVariable(), SpillExpr);
+    LLVM_DEBUG(dbgs() << "Creating DBG_VALUE inst for spill: ";
+               NewDMI->print(dbgs(), false, false, false, TII));
+  }
+
+  // The newly created DBG_VALUE instruction NewDMI must be inserted after
+  // MI. Keep track of the pairing.
+  TransferDebugPair MIP = {&MI, NewDMI};
+  Transfers.push_back(MIP);
+
+  // End all previous ranges of Var.
+  OpenRanges.erase(VarLocIDs[OldVarID].Var);
+
+  // Add the VarLoc to OpenRanges.
+  VarLoc VL(*NewDMI, LS);
+  unsigned LocID = VarLocIDs.insert(VL);
+  OpenRanges.insert(LocID, VL.Var);
+}
+
 /// A definition of a register may mark the end of a range.
 void LiveDebugValues::transferRegisterDef(MachineInstr &MI,
                                           OpenRangesSet &OpenRanges,
@@ -464,14 +519,14 @@ bool LiveDebugValues::isSpillInstruction
 
 /// A spilled register may indicate that we have to end the current range of
 /// a variable and create a new one for the spill location.
-/// We don't want to insert any instructions in transfer(), so we just create
-/// the DBG_VALUE witout inserting it and keep track of it in @Spills.
+/// We don't want to insert any instructions in process(), so we just create
+/// the DBG_VALUE without inserting it and keep track of it in \p Transfers.
 /// It will be inserted into the BB when we're done iterating over the
 /// instructions.
 void LiveDebugValues::transferSpillInst(MachineInstr &MI,
                                         OpenRangesSet &OpenRanges,
                                         VarLocMap &VarLocIDs,
-                                        SpillMap &Spills) {
+                                        TransferMap &Transfers) {
   unsigned Reg;
   MachineFunction *MF = MI.getMF();
   if (!isSpillInstruction(MI, MF, Reg))
@@ -482,33 +537,47 @@ void LiveDebugValues::transferSpillInst(
     if (VarLocIDs[ID].isDescribedByReg() == Reg) {
       LLVM_DEBUG(dbgs() << "Spilling Register " << printReg(Reg, TRI) << '('
                         << VarLocIDs[ID].Var.getVar()->getName() << ")\n");
+      insertTransferDebugPair(MI, OpenRanges, Transfers, VarLocIDs, ID);
+      return;
+    }
+  }
+}
 
-      // Create a DBG_VALUE instruction to describe the Var in its spilled
-      // location, but don't insert it yet to avoid invalidating the
-      // iterator in our caller.
-      unsigned SpillBase;
-      int SpillOffset = extractSpillBaseRegAndOffset(MI, SpillBase);
-      const MachineInstr *DMI = &VarLocIDs[ID].MI;
-      auto *SpillExpr = DIExpression::prepend(
-          DMI->getDebugExpression(), DIExpression::NoDeref, SpillOffset);
-      MachineInstr *SpDMI =
-          BuildMI(*MF, DMI->getDebugLoc(), DMI->getDesc(), true, SpillBase,
-                  DMI->getDebugVariable(), SpillExpr);
-      LLVM_DEBUG(dbgs() << "Creating DBG_VALUE inst for spill: ";
-                 SpDMI->print(dbgs(), false, TII));
-
-      // The newly created DBG_VALUE instruction SpDMI must be inserted after
-      // MI. Keep track of the pairing.
-      SpillDebugPair MIP = {&MI, SpDMI};
-      Spills.push_back(MIP);
-
-      // End all previous ranges of Var.
-      OpenRanges.erase(VarLocIDs[ID].Var);
-
-      // Add the VarLoc to OpenRanges.
-      VarLoc VL(*SpDMI, LS);
-      unsigned SpillLocID = VarLocIDs.insert(VL);
-      OpenRanges.insert(SpillLocID, VL.Var);
+/// If \p MI is a register copy instruction, that copies a previously tracked
+/// value from one register to another register that is callee saved, we
+/// create new DBG_VALUE instruction  described with copy destination register.
+void LiveDebugValues::transferRegisterCopy(MachineInstr &MI,
+                                           OpenRangesSet &OpenRanges,
+                                           VarLocMap &VarLocIDs,
+                                           TransferMap &Transfers) {
+  const MachineOperand *SrcRegOp, *DestRegOp;
+
+  if (!TII->isCopyInstr(MI, SrcRegOp, DestRegOp) || !SrcRegOp->isKill() ||
+      !DestRegOp->isDef())
+    return;
+
+  auto isCalleSavedReg = [&](unsigned Reg) {
+    for (MCRegAliasIterator RAI(Reg, TRI, true); RAI.isValid(); ++RAI)
+      if (CalleeSavedRegs.test(*RAI))
+        return true;
+    return false;
+  };
+
+  unsigned SrcReg = SrcRegOp->getReg();
+  unsigned DestReg = DestRegOp->getReg();
+
+  // We want to recognize instructions where destination register is callee
+  // saved register. If register that could be clobbered by the call is
+  // included, there would be a great chance that it is going to be clobbered
+  // soon. It is more likely that previous register location, which is callee
+  // saved, is going to stay unclobbered longer, even if it is killed.
+  if (!isCalleSavedReg(DestReg))
+    return;
+
+  for (unsigned ID : OpenRanges.getVarLocs()) {
+    if (VarLocIDs[ID].isDescribedByReg() == SrcReg) {
+      insertTransferDebugPair(MI, OpenRanges, Transfers, VarLocIDs, ID,
+                              DestReg);
       return;
     }
   }
@@ -540,14 +609,16 @@ bool LiveDebugValues::transferTerminator
 }
 
 /// This routine creates OpenRanges and OutLocs.
-bool LiveDebugValues::transfer(MachineInstr &MI, OpenRangesSet &OpenRanges,
-                               VarLocInMBB &OutLocs, VarLocMap &VarLocIDs,
-                               SpillMap &Spills, bool transferSpills) {
+bool LiveDebugValues::process(MachineInstr &MI, OpenRangesSet &OpenRanges,
+                              VarLocInMBB &OutLocs, VarLocMap &VarLocIDs,
+                              TransferMap &Transfers, bool transferChanges) {
   bool Changed = false;
   transferDebugValue(MI, OpenRanges, VarLocIDs);
   transferRegisterDef(MI, OpenRanges, VarLocIDs);
-  if (transferSpills)
-    transferSpillInst(MI, OpenRanges, VarLocIDs, Spills);
+  if (transferChanges) {
+    transferRegisterCopy(MI, OpenRanges, VarLocIDs, Transfers);
+    transferSpillInst(MI, OpenRanges, VarLocIDs, Transfers);
+  }
   Changed = transferTerminatorInst(MI, OpenRanges, OutLocs, VarLocIDs);
   return Changed;
 }
@@ -609,7 +680,7 @@ bool LiveDebugValues::join(MachineBasicB
   for (auto ID : Diff) {
     // This VarLoc is not found in InLocs i.e. it is not yet inserted. So, a
     // new range is started for the var from the mbb's beginning by inserting
-    // a new DBG_VALUE. transfer() will end this range however appropriate.
+    // a new DBG_VALUE. process() will end this range however appropriate.
     const VarLoc &DiffIt = VarLocIDs[ID];
     const MachineInstr *DMI = &DiffIt.MI;
     MachineInstr *MI =
@@ -639,7 +710,7 @@ bool LiveDebugValues::ExtendRanges(Machi
   OpenRangesSet OpenRanges; // Ranges that are open until end of bb.
   VarLocInMBB OutLocs;      // Ranges that exist beyond bb.
   VarLocInMBB InLocs;       // Ranges that are incoming after joining.
-  SpillMap Spills;          // DBG_VALUEs associated with spills.
+  TransferMap Transfers;    // DBG_VALUEs associated with spills.
 
   DenseMap<unsigned int, MachineBasicBlock *> OrderToBB;
   DenseMap<MachineBasicBlock *, unsigned int> BBToOrder;
@@ -650,6 +721,8 @@ bool LiveDebugValues::ExtendRanges(Machi
                       std::greater<unsigned int>>
       Pending;
 
+  enum : bool { dontTransferChanges = false, transferChanges = true };
+
   // Initialize every mbb with OutLocs.
   // We are not looking at any spill instructions during the initial pass
   // over the BBs. The LiveDebugVariables pass has already created DBG_VALUE
@@ -657,8 +730,8 @@ bool LiveDebugValues::ExtendRanges(Machi
   // within the BB in which the spill occurs.
   for (auto &MBB : MF)
     for (auto &MI : MBB)
-      transfer(MI, OpenRanges, OutLocs, VarLocIDs, Spills,
-               /*transferSpills=*/false);
+      process(MI, OpenRanges, OutLocs, VarLocIDs, Transfers,
+              dontTransferChanges);
 
   LLVM_DEBUG(printVarLocInMBB(MF, OutLocs, VarLocIDs,
                               "OutLocs after initialization", dbgs()));
@@ -672,7 +745,7 @@ bool LiveDebugValues::ExtendRanges(Machi
     ++RPONumber;
   }
   // This is a standard "union of predecessor outs" dataflow problem.
-  // To solve it, we perform join() and transfer() using the two worklist method
+  // To solve it, we perform join() and process() using the two worklist method
   // until the ranges converge.
   // Ranges have converged when both worklists are empty.
   SmallPtrSet<const MachineBasicBlock *, 16> Visited;
@@ -694,14 +767,14 @@ bool LiveDebugValues::ExtendRanges(Machi
         // examine spill instructions to see whether they spill registers that
         // correspond to user variables.
         for (auto &MI : *MBB)
-          OLChanged |= transfer(MI, OpenRanges, OutLocs, VarLocIDs, Spills,
-                                /*transferSpills=*/true);
+          OLChanged |= process(MI, OpenRanges, OutLocs, VarLocIDs, Transfers,
+                               transferChanges);
 
         // Add any DBG_VALUE instructions necessitated by spills.
-        for (auto &SP : Spills)
-          MBB->insertAfter(MachineBasicBlock::iterator(*SP.SpillInst),
-                           SP.DebugInst);
-        Spills.clear();
+        for (auto &TR : Transfers)
+          MBB->insertAfter(MachineBasicBlock::iterator(*TR.TransferInst),
+                           TR.DebugInst);
+        Transfers.clear();
 
         LLVM_DEBUG(printVarLocInMBB(MF, OutLocs, VarLocIDs,
                                     "OutLocs after propagating", dbgs()));
@@ -741,6 +814,8 @@ bool LiveDebugValues::runOnMachineFuncti
   TRI = MF.getSubtarget().getRegisterInfo();
   TII = MF.getSubtarget().getInstrInfo();
   TFI = MF.getSubtarget().getFrameLowering();
+  TFI->determineCalleeSaves(MF, CalleeSavedRegs,
+                            make_unique<RegScavenger>().get());
   LS.initialize(MF);
 
   bool Changed = ExtendRanges(MF);

Added: llvm/trunk/test/DebugInfo/MIR/ARM/live-debug-values-reg-copy.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/MIR/ARM/live-debug-values-reg-copy.mir?rev=336978&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/MIR/ARM/live-debug-values-reg-copy.mir (added)
+++ llvm/trunk/test/DebugInfo/MIR/ARM/live-debug-values-reg-copy.mir Fri Jul 13 01:24:26 2018
@@ -0,0 +1,147 @@
+# RUN: llc -run-pass=livedebugvalues %s -o - | FileCheck %s
+#
+# This test tests tracking variables value transferring from one register to another.
+# This example is altered additionally in order to test transferring from one float register
+# to another. The altered instructions are labeled below.
+#
+# CHECK: ![[ARG1:.*]] = !DILocalVariable(name: "arg1"
+# CHECK: DBG_VALUE debug-use $r4, debug-use $noreg, ![[ARG1]], !DIExpression(), debug-location
+# CHECK: $r5 = MOVr killed $r4, 14, $noreg, $noreg, debug-location
+# CHECK-NEXT: DBG_VALUE debug-use $r5, debug-use $noreg, ![[ARG1]], !DIExpression(), debug-location
+--- |
+  ; ModuleID = 'live-debug-values-reg-copy.ll'
+  source_filename = "live-debug-values-reg-copy.c"
+  target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+  target triple = "armv4t--"
+  
+  define dso_local arm_aapcscc i32 @foo(i32 %arg1) local_unnamed_addr !dbg !8 {
+  entry:
+    call void @llvm.dbg.value(metadata i32 %arg1, metadata !13, metadata !DIExpression()), !dbg !16
+    %cmp = icmp sgt i32 %arg1, 10, !dbg !16
+    br i1 %cmp, label %if.end, label %if.else, !dbg !16
+  
+  if.else:                                          ; preds = %entry
+    %add5 = add nsw i32 %arg1, 10, !dbg !16
+    call void @llvm.dbg.value(metadata i32 %add5, metadata !13, metadata !DIExpression()), !dbg !16
+    %call6 = tail call arm_aapcscc i32 @externFunc2(i32 %add5), !dbg !16
+    %call8 = tail call arm_aapcscc i32 @externFunc(i32 %add5), !dbg !16
+    ret i32 %call6, !dbg !16
+  
+  if.end:                                           ; preds = %entry
+    %call = tail call arm_aapcscc i32 @externFunc(i32 %arg1), !dbg !16
+    ret i32 1, !dbg !16
+  }
+  
+  declare dso_local arm_aapcscc i32 @externFunc(i32) local_unnamed_addr
+  
+  declare dso_local arm_aapcscc i32 @externFunc2(i32) local_unnamed_addr
+  
+  ; Function Attrs: nounwind readnone speculatable
+  declare void @llvm.dbg.value(metadata, metadata, metadata) #0
+  
+  ; Function Attrs: nounwind
+  declare void @llvm.stackprotector(i8*, i8**) #1
+  
+  attributes #0 = { nounwind readnone speculatable }
+  attributes #1 = { nounwind }
+  
+  !llvm.dbg.cu = !{!0}
+  !llvm.module.flags = !{!3, !4, !5, !6}
+  !llvm.ident = !{!7}
+  
+  !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 7.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+  !1 = !DIFile(filename: "live-debug-values-reg-copy.c", directory: "/")
+  !2 = !{}
+  !3 = !{i32 2, !"Dwarf Version", i32 4}
+  !4 = !{i32 2, !"Debug Info Version", i32 3}
+  !5 = !{i32 1, !"wchar_size", i32 4}
+  !6 = !{i32 1, !"min_enum_size", i32 4}
+  !7 = !{!"clang version 7.0.0"}
+  !8 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 4, type: !9, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !12)
+  !9 = !DISubroutineType(types: !10)
+  !10 = !{!11, !11}
+  !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+  !12 = !{!13}
+  !13 = !DILocalVariable(name: "arg1", arg: 1, scope: !8, file: !1, line: 4, type: !11)
+  !16 = !DILocation(line: 4, column: 13, scope: !8)
+
+...
+---
+name:            foo
+alignment:       2
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: false
+registers:       
+liveins:         
+  - { reg: '$r0', virtual-reg: '' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       16
+  offsetAdjustment: 0
+  maxAlignment:    4
+  adjustsStack:    true
+  hasCalls:        true
+  stackProtector:  ''
+  maxCallFrameSize: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+  - { id: 0, name: '', type: spill-slot, offset: -4, size: 4, alignment: 4, 
+      stack-id: 0, callee-saved-register: '$lr', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 1, name: '', type: spill-slot, offset: -8, size: 4, alignment: 4, 
+      stack-id: 0, callee-saved-register: '$r11', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 2, name: '', type: spill-slot, offset: -12, size: 4, alignment: 4, 
+      stack-id: 0, callee-saved-register: '$r5', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 3, name: '', type: spill-slot, offset: -16, size: 4, alignment: 4, 
+      stack-id: 0, callee-saved-register: '$r4', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+constants:       
+body:             |
+  bb.0.entry:
+    successors: %bb.1(0x40000000), %bb.2(0x40000000)
+  
+    $sp = frame-setup STMDB_UPD $sp, 14, $noreg, killed $r4, killed $r5, killed $r11, killed $lr
+    frame-setup CFI_INSTRUCTION def_cfa_offset 16
+    frame-setup CFI_INSTRUCTION offset $lr, -4
+    frame-setup CFI_INSTRUCTION offset $r11, -8
+    frame-setup CFI_INSTRUCTION offset $r5, -12
+    frame-setup CFI_INSTRUCTION offset $r4, -16
+    DBG_VALUE debug-use $r0, debug-use $noreg, !13, !DIExpression(), debug-location !16
+    DBG_VALUE debug-use $r0, debug-use $noreg, !13, !DIExpression(), debug-location !16
+    CMPri renamable $r0, 10, 14, $noreg, implicit-def $cpsr, debug-location !16
+    Bcc %bb.2, 13, killed $cpsr, debug-location !16
+  
+  bb.1.if.end:
+    BL @externFunc, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $r0, implicit-def $sp, implicit-def dead $r0, debug-location !16
+    $r0 = MOVi 1, 14, $noreg, $noreg, debug-location !16
+    $sp = LDMIA_UPD $sp, 14, $noreg, def $r4, def $r5, def $r11, def $lr, debug-location !16
+    BX_RET 14, $noreg, implicit killed $r0, debug-location !16
+  
+  bb.2.if.else:
+    renamable $r4 = ADDri killed renamable $r0, 10, 14, $noreg, $noreg, debug-location !16
+    DBG_VALUE debug-use $r4, debug-use $noreg, !13, !DIExpression(), debug-location !16
+    $r0 = MOVr $r4, 14, $noreg, $noreg, debug-location !16
+    BL @externFunc2, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $r0, implicit-def $sp, implicit-def $r0, debug-location !16
+    $r5 = MOVr killed $r0, 14, $noreg, $noreg, debug-location !16
+    $r0 = MOVr $r4, 14, $noreg, $noreg, debug-location !16
+    BL @externFunc, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $r0, implicit-def $sp, implicit-def dead $r0, debug-location !16
+    $r0 = MOVr killed $r5, 14, $noreg, $noreg, debug-location !16
+    ; Instruction below is added in order to test moving variable's value from one register to another.
+    $r5 = MOVr killed $r4, 14, $noreg, $noreg, debug-location !16
+    $sp = LDMIA_UPD $sp, 14, $noreg, def $r4, def $r5, def $r11, def $lr, debug-location !16
+    BX_RET 14, $noreg, implicit killed $r0, debug-location !16
+
+...

Added: llvm/trunk/test/DebugInfo/MIR/Mips/live-debug-values-reg-copy.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/MIR/Mips/live-debug-values-reg-copy.mir?rev=336978&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/MIR/Mips/live-debug-values-reg-copy.mir (added)
+++ llvm/trunk/test/DebugInfo/MIR/Mips/live-debug-values-reg-copy.mir Fri Jul 13 01:24:26 2018
@@ -0,0 +1,241 @@
+# RUN: llc -run-pass=livedebugvalues %s -o - | FileCheck %s
+#
+# This test tests tracking variables value transferring from one register to another.
+# This example is altered additionally in order to test transferring from one float register
+# to another. The altered instructions are labeled below.
+#
+# CHECK: ![[ARG1:.*]] = !DILocalVariable(name: "arg1"
+# CHECK: ![[ARG2:.*]] = !DILocalVariable(name: "arg2"
+# CHECK: DBG_VALUE debug-use $s0_64, debug-use $noreg, ![[ARG2]], !DIExpression(), debug-location
+# CHECK: $s1_64 = OR64 killed $s0_64, $zero_64, debug-location
+# CHECK-NEXT: DBG_VALUE debug-use $s1_64, debug-use $noreg, ![[ARG2]], !DIExpression(), debug-location
+# CHECK: DBG_VALUE debug-use $f24, debug-use $noreg, ![[ARG1]], !DIExpression(), debug-location
+# CHECK: $f26 = FMOV_S killed $f24, debug-location
+# CHECK-NEXT: DBG_VALUE debug-use $f26, debug-use $noreg, ![[ARG1]], !DIExpression(), debug-location
+
+--- |
+  ; ModuleID = 'live-debug-values-reg-copy.ll'
+  source_filename = "live-debug-values-reg-copy.c"
+  target datalayout = "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128"
+  target triple = "mips64-octeon-linux"
+
+  define float @foo(float %arg1, i32 signext %arg2) local_unnamed_addr !dbg !8 {
+  entry:
+    call void @llvm.dbg.value(metadata float %arg1, metadata !14, metadata !DIExpression()), !dbg !19
+    call void @llvm.dbg.value(metadata i32 %arg2, metadata !15, metadata !DIExpression()), !dbg !19
+    %conv = fpext float %arg1 to double, !dbg !19
+    %cmp = fcmp ogt double %conv, 1.012310e+01, !dbg !19
+    br i1 %cmp, label %if.then, label %if.else, !dbg !19
+
+  if.then:                                          ; preds = %entry
+    %call = tail call float @externFunc(float %arg1), !dbg !19
+    %call5 = tail call i32 @externFunc3(i32 signext %arg2), !dbg !19
+    %conv6 = sitofp i32 %call5 to float, !dbg !19
+    %add7 = fadd float %conv6, 0x3FF522D0E0000000, !dbg !19
+    br label %if.end, !dbg !19
+
+  if.else:                                          ; preds = %entry
+    %add8 = fadd float %arg1, 1.000000e+01, !dbg !19
+    call void @llvm.dbg.value(metadata float %add8, metadata !14, metadata !DIExpression()), !dbg !19
+    %call9 = tail call float @externFunc2(float %add8), !dbg !19
+    %call10 = tail call i32 @externFunc4(i32 signext %arg2), !dbg !19
+    %conv11 = sitofp i32 %call10 to float, !dbg !19
+    %add12 = fadd float %call9, %conv11, !dbg !19
+    %call14 = tail call float @externFunc(float %add8), !dbg !19
+    br label %if.end
+
+  if.end:                                           ; preds = %if.else, %if.then
+    %local.0 = phi float [ %add7, %if.then ], [ %add12, %if.else ]
+    ret float %local.0, !dbg !19
+  }
+
+  declare float @externFunc(float) local_unnamed_addr
+
+  declare i32 @externFunc3(i32 signext) local_unnamed_addr
+
+  declare float @externFunc2(float) local_unnamed_addr
+
+  declare i32 @externFunc4(i32 signext) local_unnamed_addr
+
+  ; Function Attrs: nounwind readnone speculatable
+  declare void @llvm.dbg.value(metadata, metadata, metadata) #0
+
+  ; Function Attrs: nounwind
+  declare void @llvm.stackprotector(i8*, i8**) #1
+
+  attributes #0 = { nounwind readnone speculatable }
+  attributes #1 = { nounwind }
+
+  !llvm.dbg.cu = !{!0}
+  !llvm.module.flags = !{!3, !4, !5, !6}
+  !llvm.ident = !{!7}
+
+  !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 7.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+  !1 = !DIFile(filename: "live-debug-values-reg-copy.c", directory: "/")
+  !2 = !{}
+  !3 = !{i32 2, !"Dwarf Version", i32 4}
+  !4 = !{i32 2, !"Debug Info Version", i32 3}
+  !5 = !{i32 1, !"wchar_size", i32 4}
+  !6 = !{i32 7, !"PIC Level", i32 2}
+  !7 = !{!"clang version 7.0.0 "}
+  !8 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 6, type: !9, isLocal: false, isDefinition: true, scopeLine: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !13)
+  !9 = !DISubroutineType(types: !10)
+  !10 = !{!11, !11, !12}
+  !11 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
+  !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+  !13 = !{!14, !15}
+  !14 = !DILocalVariable(name: "arg1", arg: 1, scope: !8, file: !1, line: 6, type: !11)
+  !15 = !DILocalVariable(name: "arg2", arg: 2, scope: !8, file: !1, line: 6, type: !12)
+  !19 = !DILocation(line: 6, column: 17, scope: !8)
+
+...
+---
+name:            foo
+alignment:       3
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: false
+registers:
+liveins:
+  - { reg: '$f12', virtual-reg: '' }
+  - { reg: '$a1_64', virtual-reg: '' }
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       32
+  offsetAdjustment: 0
+  maxAlignment:    8
+  adjustsStack:    true
+  hasCalls:        true
+  stackProtector:  ''
+  maxCallFrameSize: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:
+stack:
+  - { id: 0, name: '', type: spill-slot, offset: -8, size: 8, alignment: 8,
+      stack-id: 0, callee-saved-register: '$d25_64', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 1, name: '', type: spill-slot, offset: -16, size: 8, alignment: 8,
+      stack-id: 0, callee-saved-register: '$d24_64', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 2, name: '', type: spill-slot, offset: -24, size: 8, alignment: 8,
+      stack-id: 0, callee-saved-register: '$ra_64', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 3, name: '', type: spill-slot, offset: -32, size: 8, alignment: 8,
+      stack-id: 0, callee-saved-register: '$s0_64', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+constants:
+  - id:              0
+    value:           'double 1.012310e+01'
+    alignment:       8
+    isTargetSpecific: false
+  - id:              1
+    value:           'float 1.000000e+01'
+    alignment:       4
+    isTargetSpecific: false
+  - id:              2
+    value:           float 0x3FF522D0E0000000
+    alignment:       4
+    isTargetSpecific: false
+body:             |
+  bb.0.entry:
+    successors: %bb.1(0x40000000), %bb.2(0x40000000)
+
+    $sp_64 = DADDiu $sp_64, -32
+    CFI_INSTRUCTION def_cfa_offset 32
+    SDC164 killed $d25_64, $sp_64, 24 :: (store 8 into %stack.0)
+    SDC164 killed $d24_64, $sp_64, 16 :: (store 8 into %stack.1)
+    SD killed $ra_64, $sp_64, 8 :: (store 8 into %stack.2)
+    SD killed $s0_64, $sp_64, 0 :: (store 8 into %stack.3)
+    CFI_INSTRUCTION offset $d26_64, -8
+    CFI_INSTRUCTION offset $d25_64, -4
+    CFI_INSTRUCTION offset $d25_64, -16
+    CFI_INSTRUCTION offset $d24_64, -12
+    CFI_INSTRUCTION offset $ra_64, -24
+    CFI_INSTRUCTION offset $s0_64, -32
+    DBG_VALUE debug-use $f12, debug-use $noreg, !14, !DIExpression(), debug-location !19
+    DBG_VALUE debug-use $a1_64, debug-use $noreg, !15, !DIExpression(), debug-location !19
+    DBG_VALUE debug-use $s0, debug-use $noreg, !15, !DIExpression(), debug-location !19
+    DBG_VALUE debug-use $s0_64, debug-use $noreg, !15, !DIExpression(), debug-location !19
+    DBG_VALUE debug-use $f12, debug-use $noreg, !14, !DIExpression(), debug-location !19
+    renamable $d0_64 = CVT_D64_S renamable $f12, debug-location !19
+    renamable $at_64 = LUi64 target-flags(mips-highest) %const.0
+    renamable $at_64 = DADDiu killed renamable $at_64, target-flags(mips-higher) %const.0
+    renamable $at_64 = DSLL killed renamable $at_64, 16
+    renamable $at_64 = DADDiu killed renamable $at_64, target-flags(mips-abs-hi) %const.0
+    renamable $at_64 = DSLL killed renamable $at_64, 16
+    renamable $d1_64 = LDC164 killed renamable $at_64, target-flags(mips-abs-lo) %const.0, debug-location !19 :: (load 8 from constant-pool)
+    FCMP_D64 killed renamable $d0_64, killed renamable $d1_64, 7, implicit-def $fcc0, debug-location !19
+    BC1T killed $fcc0, %bb.2, implicit-def $at, debug-location !19 {
+      $s0_64 = OR64 $a1_64, $zero_64
+    }
+
+  bb.1.if.then:
+    successors: %bb.3(0x80000000)
+
+    JAL @externFunc, csr_n64, implicit-def dead $ra, implicit $f12, implicit-def $sp, implicit-def dead $f0, debug-location !19 {
+      NOP debug-location !19
+    }
+    JAL @externFunc3, csr_n64, implicit-def dead $ra, implicit $a0_64, implicit-def $sp, implicit-def $v0, debug-location !19 {
+      renamable $a0_64 = SLL64_32 renamable $s0, implicit $s0_64, debug-location !19
+    }
+    $f0 = MTC1 killed $v0, debug-location !19
+    $f0 = CVT_S_W killed $f0, debug-location !19
+    ; This instruction is inserted additionally in order to test moving from one register to another
+    $s1_64 = OR64 killed $s0_64, $zero_64, debug-location !19
+    renamable $at_64 = LUi64 target-flags(mips-highest) %const.2
+    renamable $at_64 = DADDiu killed renamable $at_64, target-flags(mips-higher) %const.2
+    renamable $at_64 = DSLL killed renamable $at_64, 16
+    renamable $at_64 = DADDiu killed renamable $at_64, target-flags(mips-abs-hi) %const.2
+    renamable $at_64 = DSLL killed renamable $at_64, 16
+    renamable $f1 = LWC1 killed renamable $at_64, target-flags(mips-abs-lo) %const.2, debug-location !19 :: (load 4 from constant-pool)
+    J %bb.3, implicit-def dead $at, debug-location !19 {
+      renamable $f0 = FADD_S killed renamable $f0, killed renamable $f1, debug-location !19
+    }
+
+  bb.2.if.else:
+    successors: %bb.3(0x80000000)
+
+    renamable $at_64 = LUi64 target-flags(mips-highest) %const.1
+    renamable $at_64 = DADDiu killed renamable $at_64, target-flags(mips-higher) %const.1
+    renamable $at_64 = DSLL killed renamable $at_64, 16
+    renamable $at_64 = DADDiu killed renamable $at_64, target-flags(mips-abs-hi) %const.1
+    renamable $at_64 = DSLL killed renamable $at_64, 16
+    renamable $f0 = LWC1 killed renamable $at_64, target-flags(mips-abs-lo) %const.1, debug-location !19 :: (load 4 from constant-pool)
+    renamable $f24 = FADD_S killed renamable $f12, killed renamable $f0, debug-location !19
+    DBG_VALUE debug-use $f24, debug-use $noreg, !14, !DIExpression(), debug-location !19
+    JAL @externFunc2, csr_n64, implicit-def dead $ra, implicit $f12, implicit-def $sp, implicit-def $f0, debug-location !19 {
+      $f12 = FMOV_S $f24, debug-location !19
+    }
+    $f25 = FMOV_S $f0, debug-location !19
+    JAL @externFunc4, csr_n64, implicit-def dead $ra, implicit $a0_64, implicit-def $sp, implicit-def $v0, debug-location !19 {
+      renamable $a0_64 = SLL64_32 renamable $s0, implicit killed $s0_64, debug-location !19
+    }
+    $s0 = OR $v0, $zero, debug-location !19
+    JAL @externFunc, csr_n64, implicit-def dead $ra, implicit $f12, implicit-def $sp, implicit-def dead $f0, debug-location !19 {
+      $f12 = FMOV_S $f24, debug-location !19
+    }
+    $f0 = MTC1 killed $s0, debug-location !19
+    $f0 = CVT_S_W killed $f0, debug-location !19
+    renamable $f0 = FADD_S renamable $f25, killed renamable $f0, debug-location !19
+    ; This instruction is inserted additionally in order to test moving variable's value from one float register to another.
+    $f26 = FMOV_S killed $f24, debug-location !19
+
+  bb.3.if.end:
+    $s0_64 = LD $sp_64, 0, debug-location !19 :: (load 8 from %stack.3)
+    $ra_64 = LD $sp_64, 8, debug-location !19 :: (load 8 from %stack.2)
+    $d24_64 = LDC164 $sp_64, 16, debug-location !19 :: (load 8 from %stack.1)
+    $d25_64 = LDC164 $sp_64, 24, debug-location !19 :: (load 8 from %stack.0)
+    PseudoReturn64 undef $ra_64, implicit $f0, debug-location !19 {
+      $sp_64 = DADDiu $sp_64, 32
+    }
+
+...

Added: llvm/trunk/test/DebugInfo/MIR/X86/live-debug-values-reg-copy.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/MIR/X86/live-debug-values-reg-copy.mir?rev=336978&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/MIR/X86/live-debug-values-reg-copy.mir (added)
+++ llvm/trunk/test/DebugInfo/MIR/X86/live-debug-values-reg-copy.mir Fri Jul 13 01:24:26 2018
@@ -0,0 +1,190 @@
+# RUN: llc -run-pass=livedebugvalues %s -o - | FileCheck %s
+#
+# This test tests tracking variables value transferring from one register to another.
+# This example is altered additionally in order to test transferring from one float register
+# to another. The altered instructions are labeled below.
+#
+# CHECK: ![[ARG1:.*]] = !DILocalVariable(name: "arg1"
+# CHECK: DBG_VALUE debug-use $ebx, debug-use $noreg, ![[ARG1]], !DIExpression(), debug-location
+# CHECK: $r12d = MOV32rr killed $ebx, implicit-def $r12
+# CHECK-NEXT: DBG_VALUE debug-use $r12d, debug-use $noreg, ![[ARG1]], !DIExpression(), debug-location
+--- |
+  ; ModuleID = 'live-debug-values-reg-copy.ll'
+  source_filename = "live-debug-values-reg-copy.c"
+  target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+  target triple = "x86_64-unknown-linux-gnu"
+
+  define dso_local i32 @foo(i32 %arg1) local_unnamed_addr !dbg !7 {
+  entry:
+    %local1 = alloca i32, align 4
+    call void @llvm.dbg.value(metadata i32 %arg1, metadata !12, metadata !DIExpression()), !dbg !15
+    %0 = bitcast i32* %local1 to i8*, !dbg !15
+    call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0), !dbg !15
+    call void @init(i32* nonnull %local1), !dbg !15
+    %1 = load i32, i32* %local1, align 4, !dbg !15, !tbaa !20
+    %add = add nsw i32 %1, %arg1, !dbg !15
+    %call = call i32 @coeficient(i32 %add), !dbg !15
+    %cmp = icmp sgt i32 %call, 32, !dbg !15
+    br i1 %cmp, label %if.then, label %if.else, !dbg !15
+
+  if.then:                                          ; preds = %entry
+    %call1 = call i32 @externFunc(i32 %arg1), !dbg !15
+    %2 = load i32, i32* %local1, align 4, !dbg !15, !tbaa !20
+    %add2 = add nsw i32 %2, %call1, !dbg !15
+    br label %if.end, !dbg !15
+
+  if.else:                                          ; preds = %entry
+    %call3 = call i32 @externFunc2(i32 %arg1), !dbg !15
+    %3 = load i32, i32* %local1, align 4, !dbg !15, !tbaa !20
+    %add4 = add nsw i32 %3, %call3, !dbg !15
+    br label %if.end
+
+  if.end:                                           ; preds = %if.else, %if.then
+    %storemerge = phi i32 [ %add4, %if.else ], [ %add2, %if.then ]
+    %4 = bitcast i32* %local1 to i8*
+    %mul = shl nsw i32 %arg1, 2, !dbg !15
+    %add5 = add nsw i32 %storemerge, %mul, !dbg !15
+    %mul6 = mul nsw i32 %add5, %call, !dbg !15
+    call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %4), !dbg !15
+    ret i32 %mul6, !dbg !15
+  }
+
+  ; Function Attrs: argmemonly nounwind
+  declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #0
+
+  declare dso_local void @init(i32*) local_unnamed_addr
+
+  declare dso_local i32 @coeficient(i32) local_unnamed_addr
+
+  declare dso_local i32 @externFunc(i32) local_unnamed_addr
+
+  declare dso_local i32 @externFunc2(i32) local_unnamed_addr
+
+  ; Function Attrs: argmemonly nounwind
+  declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #0
+
+  ; Function Attrs: nounwind readnone speculatable
+  declare void @llvm.dbg.value(metadata, metadata, metadata) #1
+
+  ; Function Attrs: nounwind
+  declare void @llvm.stackprotector(i8*, i8**) #2
+
+  attributes #0 = { argmemonly nounwind }
+  attributes #1 = { nounwind readnone speculatable }
+  attributes #2 = { nounwind }
+
+  !llvm.dbg.cu = !{!0}
+  !llvm.module.flags = !{!3, !4, !5}
+  !llvm.ident = !{!6}
+
+  !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 7.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+  !1 = !DIFile(filename: "live-debug-values-reg-copy.c", directory: "/")
+  !2 = !{}
+  !3 = !{i32 2, !"Dwarf Version", i32 4}
+  !4 = !{i32 2, !"Debug Info Version", i32 3}
+  !5 = !{i32 1, !"wchar_size", i32 4}
+  !6 = !{!"clang version 7.0.0 "}
+  !7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 6, type: !8, isLocal: false, isDefinition: true, scopeLine: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !11)
+  !8 = !DISubroutineType(types: !9)
+  !9 = !{!10, !10}
+  !10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+  !11 = !{!12}
+  !12 = !DILocalVariable(name: "arg1", arg: 1, scope: !7, file: !1, line: 6, type: !10)
+  !15 = !DILocation(line: 6, column: 13, scope: !7)
+  !20 = !{!21, !21, i64 0}
+  !21 = !{!"int", !22, i64 0}
+  !22 = !{!"omnipotent char", !23, i64 0}
+  !23 = !{!"Simple C/C++ TBAA"}
+
+...
+---
+name:            foo
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:
+liveins:
+  - { reg: '$edi', virtual-reg: '' }
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       24
+  offsetAdjustment: 0
+  maxAlignment:    4
+  adjustsStack:    true
+  hasCalls:        true
+  stackProtector:  ''
+  maxCallFrameSize: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:
+  - { id: 0, type: spill-slot, offset: -24, size: 8, alignment: 8, stack-id: 0,
+      callee-saved-register: '$rbx', callee-saved-restored: true }
+  - { id: 1, type: spill-slot, offset: -16, size: 8, alignment: 16, stack-id: 0,
+      callee-saved-register: '$rbp', callee-saved-restored: true }
+stack:
+  - { id: 0, name: local1, type: default, offset: -28, size: 4, alignment: 4,
+      stack-id: 0, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+constants:
+body:             |
+  bb.0.entry:
+    successors: %bb.1(0x40000000), %bb.2(0x40000000)
+    liveins: $edi, $rbp, $rbx
+
+    frame-setup PUSH64r killed $rbp, implicit-def $rsp, implicit $rsp
+    CFI_INSTRUCTION def_cfa_offset 16
+    frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp
+    CFI_INSTRUCTION def_cfa_offset 24
+    frame-setup PUSH64r undef $rax, implicit-def $rsp, implicit $rsp
+    CFI_INSTRUCTION def_cfa_offset 32
+    CFI_INSTRUCTION offset $rbx, -24
+    CFI_INSTRUCTION offset $rbp, -16
+    DBG_VALUE debug-use $edi, debug-use $noreg, !12, !DIExpression(), debug-location !15
+    $ebx = MOV32rr $edi, implicit-def $rbx
+    DBG_VALUE debug-use $ebx, debug-use $noreg, !12, !DIExpression(), debug-location !15
+    renamable $rdi = LEA64r $rsp, 1, $noreg, 4, $noreg
+    CALL64pcrel32 @init, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, debug-location !15
+    renamable $edi = MOV32rm $rsp, 1, $noreg, 4, $noreg :: (dereferenceable load 4 from %ir.local1, !tbaa !20)
+    renamable $edi = ADD32rr killed renamable $edi, renamable $ebx, implicit-def dead $eflags, debug-location !15
+    CALL64pcrel32 @coeficient, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax, debug-location !15
+    $ebp = MOV32rr $eax, debug-location !15
+    $edi = MOV32rr $ebx, debug-location !15
+    CMP32ri8 renamable $ebp, 33, implicit-def $eflags, debug-location !15
+    JL_1 %bb.2, implicit killed $eflags, debug-location !15
+
+  bb.1.if.then:
+    successors: %bb.3(0x80000000)
+    liveins: $ebp, $edi
+
+    CALL64pcrel32 @externFunc, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax, debug-location !15
+    JMP_1 %bb.3
+
+  bb.2.if.else:
+    successors: %bb.3(0x80000000)
+    liveins: $ebp, $edi
+
+    CALL64pcrel32 @externFunc2, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax, debug-location !15
+
+  bb.3.if.end:
+    liveins: $ebp, $ebx, $eax
+    ; Instruction below is added in order to test moving variable's value from one register to another.
+    $r12d = MOV32rr killed $ebx, implicit-def $r12
+    renamable $eax = KILL $eax, implicit-def $rax
+    renamable $eax = ADD32rm renamable $eax, $rsp, 1, $noreg, 4, $noreg, implicit-def dead $eflags, implicit killed $rax, implicit-def $rax :: (dereferenceable load 4 from %ir.local1, !tbaa !20)
+    renamable $eax = LEA64_32r killed renamable $rax, 4, killed renamable $r12, 0, $noreg, debug-location !15
+    renamable $eax = IMUL32rr killed renamable $eax, killed renamable $ebp, implicit-def dead $eflags, debug-location !15
+    $rsp = frame-destroy ADD64ri8 $rsp, 8, implicit-def dead $eflags, debug-location !15
+    $rbx = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !15
+    $rbp = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !15
+    RETQ $eax, debug-location !15
+
+...




More information about the llvm-commits mailing list