[llvm] r372555 - [MIPS GlobalISel] VarArg argument lowering, select G_VASTART and vacopy

Petar Avramovic via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 23 01:11:41 PDT 2019


Author: petar.avramovic
Date: Mon Sep 23 01:11:41 2019
New Revision: 372555

URL: http://llvm.org/viewvc/llvm-project?rev=372555&view=rev
Log:
[MIPS GlobalISel] VarArg argument lowering, select G_VASTART and vacopy

CC_Mips doesn't accept vararg functions for O32, so we have to explicitly
use CC_Mips_FixedArg.
For lowerCall we now properly figure out whether callee function is vararg
or not, this has no effect for O32 since we always use CC_Mips_FixedArg.
For lower formal arguments we need to copy arguments in register to stack
and save pointer to start for argument list into MipsMachineFunction
object so that G_VASTART could use it during instruction select.
For vacopy we need to copy content from one vreg to another,
load and store are used for that purpose.

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

Added:
    llvm/trunk/test/CodeGen/Mips/GlobalISel/instruction-select/var_arg.mir
    llvm/trunk/test/CodeGen/Mips/GlobalISel/irtranslator/var_arg.ll
    llvm/trunk/test/CodeGen/Mips/GlobalISel/legalizer/var_arg.mir
    llvm/trunk/test/CodeGen/Mips/GlobalISel/llvm-ir/var_arg.ll
    llvm/trunk/test/CodeGen/Mips/GlobalISel/regbankselect/var_arg.mir
Modified:
    llvm/trunk/lib/Target/Mips/MipsCallLowering.cpp
    llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
    llvm/trunk/lib/Target/Mips/MipsInstructionSelector.cpp
    llvm/trunk/lib/Target/Mips/MipsLegalizerInfo.cpp
    llvm/trunk/lib/Target/Mips/MipsRegisterBankInfo.cpp

Modified: llvm/trunk/lib/Target/Mips/MipsCallLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsCallLowering.cpp?rev=372555&r1=372554&r2=372555&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsCallLowering.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsCallLowering.cpp Mon Sep 23 01:11:41 2019
@@ -454,10 +454,6 @@ bool MipsCallLowering::lowerFormalArgume
   if (F.arg_empty())
     return true;
 
-  if (F.isVarArg()) {
-    return false;
-  }
-
   for (auto &Arg : F.args()) {
     if (!isSupportedType(Arg.getType()))
       return false;
@@ -496,6 +492,40 @@ bool MipsCallLowering::lowerFormalArgume
   if (!Handler.handle(ArgLocs, ArgInfos))
     return false;
 
+  if (F.isVarArg()) {
+    ArrayRef<MCPhysReg> ArgRegs = ABI.GetVarArgRegs();
+    unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs);
+
+    int VaArgOffset;
+    unsigned RegSize = 4;
+    if (ArgRegs.size() == Idx)
+      VaArgOffset = alignTo(CCInfo.getNextStackOffset(), RegSize);
+    else {
+      VaArgOffset =
+          (int)ABI.GetCalleeAllocdArgSizeInBytes(CCInfo.getCallingConv()) -
+          (int)(RegSize * (ArgRegs.size() - Idx));
+    }
+
+    MachineFrameInfo &MFI = MF.getFrameInfo();
+    int FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
+    MF.getInfo<MipsFunctionInfo>()->setVarArgsFrameIndex(FI);
+
+    for (unsigned I = Idx; I < ArgRegs.size(); ++I, VaArgOffset += RegSize) {
+      MIRBuilder.getMBB().addLiveIn(ArgRegs[I]);
+
+      MachineInstrBuilder Copy =
+          MIRBuilder.buildCopy(LLT::scalar(RegSize * 8), Register(ArgRegs[I]));
+      FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
+      MachinePointerInfo MPO = MachinePointerInfo::getFixedStack(MF, FI);
+      MachineInstrBuilder FrameIndex =
+          MIRBuilder.buildFrameIndex(LLT::pointer(MPO.getAddrSpace(), 32), FI);
+      MachineMemOperand *MMO =
+          MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, RegSize,
+                                  /* Alignment */ RegSize);
+      MIRBuilder.buildStore(Copy, FrameIndex, *MMO);
+    }
+  }
+
   return true;
 }
 
@@ -566,7 +596,12 @@ bool MipsCallLowering::lowerCall(Machine
   subTargetRegTypeForCallingConv(F, ArgInfos, OrigArgIndices, Outs);
 
   SmallVector<CCValAssign, 8> ArgLocs;
-  MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
+  bool IsCalleeVarArg = false;
+  if (Info.Callee.isGlobal()) {
+    const Function *CF = static_cast<const Function *>(Info.Callee.getGlobal());
+    IsCalleeVarArg = CF->isVarArg();
+  }
+  MipsCCState CCInfo(F.getCallingConv(), IsCalleeVarArg, MF, ArgLocs,
                      F.getContext());
 
   CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(Info.CallConv), 1);

Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=372555&r1=372554&r2=372555&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Mon Sep 23 01:11:41 2019
@@ -2869,7 +2869,7 @@ static bool CC_MipsO32(unsigned ValNo, M
 #include "MipsGenCallingConv.inc"
 
  CCAssignFn *MipsTargetLowering::CCAssignFnForCall() const{
-   return CC_Mips;
+   return CC_Mips_FixedArg;
  }
 
  CCAssignFn *MipsTargetLowering::CCAssignFnForReturn() const{

Modified: llvm/trunk/lib/Target/Mips/MipsInstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstructionSelector.cpp?rev=372555&r1=372554&r2=372555&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsInstructionSelector.cpp Mon Sep 23 01:11:41 2019
@@ -773,6 +773,29 @@ bool MipsInstructionSelector::select(Mac
     MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::SYNC)).addImm(0);
     break;
   }
+  case G_VASTART: {
+    MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
+    int FI = FuncInfo->getVarArgsFrameIndex();
+
+    Register LeaReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
+    MachineInstr *LEA_ADDiu =
+        BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LEA_ADDiu))
+            .addDef(LeaReg)
+            .addFrameIndex(FI)
+            .addImm(0);
+    if (!constrainSelectedInstRegOperands(*LEA_ADDiu, TII, TRI, RBI))
+      return false;
+
+    MachineInstr *Store = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::SW))
+                              .addUse(LeaReg)
+                              .addUse(I.getOperand(0).getReg())
+                              .addImm(0);
+    if (!constrainSelectedInstRegOperands(*Store, TII, TRI, RBI))
+      return false;
+
+    I.eraseFromParent();
+    return true;
+  }
   default:
     return false;
   }

Modified: llvm/trunk/lib/Target/Mips/MipsLegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsLegalizerInfo.cpp?rev=372555&r1=372554&r2=372555&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsLegalizerInfo.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsLegalizerInfo.cpp Mon Sep 23 01:11:41 2019
@@ -122,6 +122,9 @@ MipsLegalizerInfo::MipsLegalizerInfo(con
   getActionDefinitionsBuilder(G_DYN_STACKALLOC)
       .lowerFor({{p0, s32}});
 
+  getActionDefinitionsBuilder(G_VASTART)
+     .legalFor({p0});
+
   // FP instructions
   getActionDefinitionsBuilder(G_FCONSTANT)
       .legalFor({s32, s64});
@@ -252,6 +255,18 @@ bool MipsLegalizerInfo::legalizeIntrinsi
     MI.eraseFromParent();
     return constrainSelectedInstRegOperands(*Trap, TII, TRI, RBI);
   }
+  case Intrinsic::vacopy: {
+    Register Tmp = MRI.createGenericVirtualRegister(LLT::pointer(0, 32));
+    MachinePointerInfo MPO;
+    MIRBuilder.buildLoad(Tmp, MI.getOperand(2),
+                         *MI.getMF()->getMachineMemOperand(
+                             MPO, MachineMemOperand::MOLoad, 4, 4));
+    MIRBuilder.buildStore(Tmp, MI.getOperand(1),
+                          *MI.getMF()->getMachineMemOperand(
+                              MPO, MachineMemOperand::MOStore, 4, 4));
+    MI.eraseFromParent();
+    return true;
+  }
   default:
     break;
   }

Modified: llvm/trunk/lib/Target/Mips/MipsRegisterBankInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterBankInfo.cpp?rev=372555&r1=372554&r2=372555&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsRegisterBankInfo.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsRegisterBankInfo.cpp Mon Sep 23 01:11:41 2019
@@ -403,6 +403,7 @@ MipsRegisterBankInfo::getInstrMapping(co
   case G_SREM:
   case G_UREM:
   case G_BRINDIRECT:
+  case G_VASTART:
     OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
     break;
   case G_LOAD: {

Added: llvm/trunk/test/CodeGen/Mips/GlobalISel/instruction-select/var_arg.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/GlobalISel/instruction-select/var_arg.mir?rev=372555&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/GlobalISel/instruction-select/var_arg.mir (added)
+++ llvm/trunk/test/CodeGen/Mips/GlobalISel/instruction-select/var_arg.mir Mon Sep 23 01:11:41 2019
@@ -0,0 +1,127 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
+--- |
+
+  @.str = private unnamed_addr constant [11 x i8] c"string %s\0A\00", align 1
+  declare void @llvm.va_start(i8*) #0
+  declare void @llvm.va_copy(i8*, i8*) #0
+  declare i32 @printf(i8*, ...)
+
+  define void @testVaCopyArg(i8* %fmt, ...) {
+  entry:
+    %fmt.addr = alloca i8*, align 4
+    %ap = alloca i8*, align 4
+    %aq = alloca i8*, align 4
+    %s = alloca i8*, align 4
+    store i8* %fmt, i8** %fmt.addr, align 4
+    %ap1 = bitcast i8** %ap to i8*
+    call void @llvm.va_start(i8* %ap1)
+    %0 = bitcast i8** %aq to i8*
+    %1 = bitcast i8** %ap to i8*
+    call void @llvm.va_copy(i8* %0, i8* %1)
+    %argp.cur = load i8*, i8** %aq, align 4
+    %argp.next = getelementptr inbounds i8, i8* %argp.cur, i32 4
+    store i8* %argp.next, i8** %aq, align 4
+    %2 = bitcast i8* %argp.cur to i8**
+    %3 = load i8*, i8** %2, align 4
+    store i8* %3, i8** %s, align 4
+    %4 = load i8*, i8** %s, align 4
+    %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i32 0, i32 0), i8* %4)
+    ret void
+  }
+
+...
+---
+name:            testVaCopyArg
+alignment:       4
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+liveins:
+  - { reg: '$a0' }
+fixedStack:
+  - { id: 0, offset: 12, size: 4, alignment: 4, isImmutable: true }
+  - { id: 1, offset: 8, size: 4, alignment: 8, isImmutable: true }
+  - { id: 2, offset: 4, size: 4, alignment: 4, isImmutable: true }
+  - { id: 3, offset: 4, size: 4, alignment: 4, isImmutable: true }
+stack:
+  - { id: 0, name: fmt.addr, size: 4, alignment: 4 }
+  - { id: 1, name: ap, size: 4, alignment: 4 }
+  - { id: 2, name: aq, size: 4, alignment: 4 }
+  - { id: 3, name: s, size: 4, alignment: 4 }
+machineFunctionInfo: {}
+body:             |
+  bb.1.entry:
+    liveins: $a0, $a1, $a2, $a3
+
+    ; MIPS32-LABEL: name: testVaCopyArg
+    ; MIPS32: liveins: $a0, $a1, $a2, $a3
+    ; MIPS32: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+    ; MIPS32: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
+    ; MIPS32: [[ADDiu:%[0-9]+]]:gpr32 = ADDiu %fixed-stack.1, 0
+    ; MIPS32: SW [[COPY1]], [[ADDiu]], 0 :: (store 4 into %fixed-stack.1)
+    ; MIPS32: [[COPY2:%[0-9]+]]:gpr32 = COPY $a2
+    ; MIPS32: [[ADDiu1:%[0-9]+]]:gpr32 = ADDiu %fixed-stack.2, 0
+    ; MIPS32: SW [[COPY2]], [[ADDiu1]], 0 :: (store 4 into %fixed-stack.2)
+    ; MIPS32: [[COPY3:%[0-9]+]]:gpr32 = COPY $a3
+    ; MIPS32: [[ADDiu2:%[0-9]+]]:gpr32 = ADDiu %fixed-stack.3, 0
+    ; MIPS32: SW [[COPY3]], [[ADDiu2]], 0 :: (store 4 into %fixed-stack.3)
+    ; MIPS32: [[LUi:%[0-9]+]]:gpr32 = LUi target-flags(mips-abs-hi) @.str
+    ; MIPS32: [[ADDiu3:%[0-9]+]]:gpr32 = ADDiu [[LUi]], target-flags(mips-abs-lo) @.str
+    ; MIPS32: [[ADDiu4:%[0-9]+]]:gpr32 = ADDiu %stack.0.fmt.addr, 0
+    ; MIPS32: [[ADDiu5:%[0-9]+]]:gpr32 = ADDiu %stack.1.ap, 0
+    ; MIPS32: [[ADDiu6:%[0-9]+]]:gpr32 = ADDiu %stack.2.aq, 0
+    ; MIPS32: [[ADDiu7:%[0-9]+]]:gpr32 = ADDiu %stack.3.s, 0
+    ; MIPS32: SW [[COPY]], [[ADDiu4]], 0 :: (store 4 into %ir.fmt.addr)
+    ; MIPS32: [[LEA_ADDiu:%[0-9]+]]:gpr32 = LEA_ADDiu %stack.0.fmt.addr, 0
+    ; MIPS32: SW [[LEA_ADDiu]], [[ADDiu5]], 0
+    ; MIPS32: [[LW:%[0-9]+]]:gpr32 = LW [[ADDiu5]], 0 :: (load 4)
+    ; MIPS32: SW [[LW]], [[ADDiu6]], 0 :: (store 4)
+    ; MIPS32: [[LW1:%[0-9]+]]:gpr32 = LW [[ADDiu6]], 0 :: (load 4 from %ir.aq)
+    ; MIPS32: [[ORi:%[0-9]+]]:gpr32 = ORi $zero, 4
+    ; MIPS32: [[ADDu:%[0-9]+]]:gpr32 = ADDu [[LW1]], [[ORi]]
+    ; MIPS32: SW [[ADDu]], [[ADDiu6]], 0 :: (store 4 into %ir.aq)
+    ; MIPS32: [[LW2:%[0-9]+]]:gpr32 = LW [[LW1]], 0 :: (load 4 from %ir.2)
+    ; MIPS32: SW [[LW2]], [[ADDiu7]], 0 :: (store 4 into %ir.s)
+    ; MIPS32: [[LW3:%[0-9]+]]:gpr32 = LW [[ADDiu7]], 0 :: (load 4 from %ir.s)
+    ; MIPS32: ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
+    ; MIPS32: $a0 = COPY [[ADDiu3]]
+    ; MIPS32: $a1 = COPY [[LW3]]
+    ; MIPS32: JAL @printf, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit-def $v0
+    ; MIPS32: ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
+    ; MIPS32: RetRA
+    %0:gprb(p0) = COPY $a0
+    %1:gprb(s32) = COPY $a1
+    %2:gprb(p0) = G_FRAME_INDEX %fixed-stack.2
+    G_STORE %1(s32), %2(p0) :: (store 4 into %fixed-stack.2)
+    %3:gprb(s32) = COPY $a2
+    %4:gprb(p0) = G_FRAME_INDEX %fixed-stack.1
+    G_STORE %3(s32), %4(p0) :: (store 4 into %fixed-stack.1)
+    %5:gprb(s32) = COPY $a3
+    %6:gprb(p0) = G_FRAME_INDEX %fixed-stack.0
+    G_STORE %5(s32), %6(p0) :: (store 4 into %fixed-stack.0)
+    %18:gprb(p0) = G_GLOBAL_VALUE @.str
+    %17:gprb(p0) = COPY %18(p0)
+    %7:gprb(p0) = G_FRAME_INDEX %stack.0.fmt.addr
+    %8:gpr32(p0) = G_FRAME_INDEX %stack.1.ap
+    %9:gpr32(p0) = G_FRAME_INDEX %stack.2.aq
+    %10:gprb(p0) = G_FRAME_INDEX %stack.3.s
+    G_STORE %0(p0), %7(p0) :: (store 4 into %ir.fmt.addr)
+    G_VASTART %8(p0) :: (store 4 into %ir.ap1, align 1)
+    %19:gpr32 = LW %8(p0), 0 :: (load 4)
+    SW %19, %9(p0), 0 :: (store 4)
+    %11:gprb(p0) = G_LOAD %9(p0) :: (load 4 from %ir.aq)
+    %12:gprb(s32) = G_CONSTANT i32 4
+    %13:gprb(p0) = G_GEP %11, %12(s32)
+    G_STORE %13(p0), %9(p0) :: (store 4 into %ir.aq)
+    %14:gprb(p0) = G_LOAD %11(p0) :: (load 4 from %ir.2)
+    G_STORE %14(p0), %10(p0) :: (store 4 into %ir.s)
+    %15:gprb(p0) = G_LOAD %10(p0) :: (load 4 from %ir.s)
+    ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
+    $a0 = COPY %17(p0)
+    $a1 = COPY %15(p0)
+    JAL @printf, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit-def $v0
+    ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
+    RetRA
+
+...

Added: llvm/trunk/test/CodeGen/Mips/GlobalISel/irtranslator/var_arg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/GlobalISel/irtranslator/var_arg.ll?rev=372555&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/GlobalISel/irtranslator/var_arg.ll (added)
+++ llvm/trunk/test/CodeGen/Mips/GlobalISel/irtranslator/var_arg.ll Mon Sep 23 01:11:41 2019
@@ -0,0 +1,66 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
+
+ at .str = private unnamed_addr constant [11 x i8] c"string %s\0A\00", align 1
+declare void @llvm.va_start(i8*)
+declare void @llvm.va_copy(i8*, i8*)
+declare i32 @printf(i8*, ...)
+
+define void @testVaCopyArg(i8* %fmt, ...) {
+  ; MIPS32-LABEL: name: testVaCopyArg
+  ; MIPS32: bb.1.entry:
+  ; MIPS32:   liveins: $a0, $a1, $a2, $a3
+  ; MIPS32:   [[COPY:%[0-9]+]]:_(p0) = COPY $a0
+  ; MIPS32:   [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
+  ; MIPS32:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.2
+  ; MIPS32:   G_STORE [[COPY1]](s32), [[FRAME_INDEX]](p0) :: (store 4 into %fixed-stack.2)
+  ; MIPS32:   [[COPY2:%[0-9]+]]:_(s32) = COPY $a2
+  ; MIPS32:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
+  ; MIPS32:   G_STORE [[COPY2]](s32), [[FRAME_INDEX1]](p0) :: (store 4 into %fixed-stack.1)
+  ; MIPS32:   [[COPY3:%[0-9]+]]:_(s32) = COPY $a3
+  ; MIPS32:   [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+  ; MIPS32:   G_STORE [[COPY3]](s32), [[FRAME_INDEX2]](p0) :: (store 4 into %fixed-stack.0)
+  ; MIPS32:   [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @.str
+  ; MIPS32:   [[COPY4:%[0-9]+]]:_(p0) = COPY [[GV]](p0)
+  ; MIPS32:   [[FRAME_INDEX3:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.fmt.addr
+  ; MIPS32:   [[FRAME_INDEX4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1.ap
+  ; MIPS32:   [[FRAME_INDEX5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.2.aq
+  ; MIPS32:   [[FRAME_INDEX6:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.3.s
+  ; MIPS32:   G_STORE [[COPY]](p0), [[FRAME_INDEX3]](p0) :: (store 4 into %ir.fmt.addr)
+  ; MIPS32:   G_VASTART [[FRAME_INDEX4]](p0) :: (store 4 into %ir.ap1, align 1)
+  ; MIPS32:   G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.va_copy), [[FRAME_INDEX5]](p0), [[FRAME_INDEX4]](p0)
+  ; MIPS32:   [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX5]](p0) :: (load 4 from %ir.aq)
+  ; MIPS32:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+  ; MIPS32:   [[GEP:%[0-9]+]]:_(p0) = G_GEP [[LOAD]], [[C]](s32)
+  ; MIPS32:   G_STORE [[GEP]](p0), [[FRAME_INDEX5]](p0) :: (store 4 into %ir.aq)
+  ; MIPS32:   [[LOAD1:%[0-9]+]]:_(p0) = G_LOAD [[LOAD]](p0) :: (load 4 from %ir.2)
+  ; MIPS32:   G_STORE [[LOAD1]](p0), [[FRAME_INDEX6]](p0) :: (store 4 into %ir.s)
+  ; MIPS32:   [[LOAD2:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX6]](p0) :: (load 4 from %ir.s)
+  ; MIPS32:   ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
+  ; MIPS32:   $a0 = COPY [[COPY4]](p0)
+  ; MIPS32:   $a1 = COPY [[LOAD2]](p0)
+  ; MIPS32:   JAL @printf, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit-def $v0
+  ; MIPS32:   [[COPY5:%[0-9]+]]:_(s32) = COPY $v0
+  ; MIPS32:   ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
+  ; MIPS32:   RetRA
+entry:
+  %fmt.addr = alloca i8*, align 4
+  %ap = alloca i8*, align 4
+  %aq = alloca i8*, align 4
+  %s = alloca i8*, align 4
+  store i8* %fmt, i8** %fmt.addr, align 4
+  %ap1 = bitcast i8** %ap to i8*
+  call void @llvm.va_start(i8* %ap1)
+  %0 = bitcast i8** %aq to i8*
+  %1 = bitcast i8** %ap to i8*
+  call void @llvm.va_copy(i8* %0, i8* %1)
+  %argp.cur = load i8*, i8** %aq, align 4
+  %argp.next = getelementptr inbounds i8, i8* %argp.cur, i32 4
+  store i8* %argp.next, i8** %aq, align 4
+  %2 = bitcast i8* %argp.cur to i8**
+  %3 = load i8*, i8** %2, align 4
+  store i8* %3, i8** %s, align 4
+  %4 = load i8*, i8** %s, align 4
+  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i32 0, i32 0), i8* %4)
+  ret void
+}

Added: llvm/trunk/test/CodeGen/Mips/GlobalISel/legalizer/var_arg.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/GlobalISel/legalizer/var_arg.mir?rev=372555&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/GlobalISel/legalizer/var_arg.mir (added)
+++ llvm/trunk/test/CodeGen/Mips/GlobalISel/legalizer/var_arg.mir Mon Sep 23 01:11:41 2019
@@ -0,0 +1,123 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
+--- |
+
+  @.str = private unnamed_addr constant [11 x i8] c"string %s\0A\00", align 1
+  declare void @llvm.va_start(i8*) #0
+  declare void @llvm.va_copy(i8*, i8*) #0
+  declare i32 @printf(i8*, ...)
+
+  define void @testVaCopyArg(i8* %fmt, ...) {
+  entry:
+    %fmt.addr = alloca i8*, align 4
+    %ap = alloca i8*, align 4
+    %aq = alloca i8*, align 4
+    %s = alloca i8*, align 4
+    store i8* %fmt, i8** %fmt.addr, align 4
+    %ap1 = bitcast i8** %ap to i8*
+    call void @llvm.va_start(i8* %ap1)
+    %0 = bitcast i8** %aq to i8*
+    %1 = bitcast i8** %ap to i8*
+    call void @llvm.va_copy(i8* %0, i8* %1)
+    %argp.cur = load i8*, i8** %aq, align 4
+    %argp.next = getelementptr inbounds i8, i8* %argp.cur, i32 4
+    store i8* %argp.next, i8** %aq, align 4
+    %2 = bitcast i8* %argp.cur to i8**
+    %3 = load i8*, i8** %2, align 4
+    store i8* %3, i8** %s, align 4
+    %4 = load i8*, i8** %s, align 4
+    %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i32 0, i32 0), i8* %4)
+    ret void
+  }
+
+...
+---
+name:            testVaCopyArg
+alignment:       4
+tracksRegLiveness: true
+liveins:
+  - { reg: '$a0' }
+fixedStack:
+  - { id: 0, offset: 12, size: 4, alignment: 4, isImmutable: true }
+  - { id: 1, offset: 8, size: 4, alignment: 8, isImmutable: true }
+  - { id: 2, offset: 4, size: 4, alignment: 4, isImmutable: true }
+  - { id: 3, offset: 4, size: 4, alignment: 4, isImmutable: true }
+stack:
+  - { id: 0, name: fmt.addr, size: 4, alignment: 4 }
+  - { id: 1, name: ap, size: 4, alignment: 4 }
+  - { id: 2, name: aq, size: 4, alignment: 4 }
+  - { id: 3, name: s, size: 4, alignment: 4 }
+machineFunctionInfo: {}
+body:             |
+  bb.1.entry:
+    liveins: $a0, $a1, $a2, $a3
+
+    ; MIPS32-LABEL: name: testVaCopyArg
+    ; MIPS32: liveins: $a0, $a1, $a2, $a3
+    ; MIPS32: [[COPY:%[0-9]+]]:_(p0) = COPY $a0
+    ; MIPS32: [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
+    ; MIPS32: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
+    ; MIPS32: G_STORE [[COPY1]](s32), [[FRAME_INDEX]](p0) :: (store 4 into %fixed-stack.1)
+    ; MIPS32: [[COPY2:%[0-9]+]]:_(s32) = COPY $a2
+    ; MIPS32: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.2
+    ; MIPS32: G_STORE [[COPY2]](s32), [[FRAME_INDEX1]](p0) :: (store 4 into %fixed-stack.2)
+    ; MIPS32: [[COPY3:%[0-9]+]]:_(s32) = COPY $a3
+    ; MIPS32: [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.3
+    ; MIPS32: G_STORE [[COPY3]](s32), [[FRAME_INDEX2]](p0) :: (store 4 into %fixed-stack.3)
+    ; MIPS32: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @.str
+    ; MIPS32: [[COPY4:%[0-9]+]]:_(p0) = COPY [[GV]](p0)
+    ; MIPS32: [[FRAME_INDEX3:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.fmt.addr
+    ; MIPS32: [[FRAME_INDEX4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1.ap
+    ; MIPS32: [[FRAME_INDEX5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.2.aq
+    ; MIPS32: [[FRAME_INDEX6:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.3.s
+    ; MIPS32: G_STORE [[COPY]](p0), [[FRAME_INDEX3]](p0) :: (store 4 into %ir.fmt.addr)
+    ; MIPS32: G_VASTART [[FRAME_INDEX4]](p0) :: (store 4 into %ir.ap1, align 1)
+    ; MIPS32: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX4]](p0) :: (load 4)
+    ; MIPS32: G_STORE [[LOAD]](p0), [[FRAME_INDEX5]](p0) :: (store 4)
+    ; MIPS32: [[LOAD1:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX5]](p0) :: (load 4 from %ir.aq)
+    ; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+    ; MIPS32: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[LOAD1]], [[C]](s32)
+    ; MIPS32: G_STORE [[GEP]](p0), [[FRAME_INDEX5]](p0) :: (store 4 into %ir.aq)
+    ; MIPS32: [[LOAD2:%[0-9]+]]:_(p0) = G_LOAD [[LOAD1]](p0) :: (load 4 from %ir.2)
+    ; MIPS32: G_STORE [[LOAD2]](p0), [[FRAME_INDEX6]](p0) :: (store 4 into %ir.s)
+    ; MIPS32: [[LOAD3:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX6]](p0) :: (load 4 from %ir.s)
+    ; MIPS32: ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
+    ; MIPS32: $a0 = COPY [[COPY4]](p0)
+    ; MIPS32: $a1 = COPY [[LOAD3]](p0)
+    ; MIPS32: JAL @printf, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit-def $v0
+    ; MIPS32: ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
+    ; MIPS32: RetRA
+    %0:_(p0) = COPY $a0
+    %1:_(s32) = COPY $a1
+    %2:_(p0) = G_FRAME_INDEX %fixed-stack.2
+    G_STORE %1(s32), %2(p0) :: (store 4 into %fixed-stack.2)
+    %3:_(s32) = COPY $a2
+    %4:_(p0) = G_FRAME_INDEX %fixed-stack.1
+    G_STORE %3(s32), %4(p0) :: (store 4 into %fixed-stack.1)
+    %5:_(s32) = COPY $a3
+    %6:_(p0) = G_FRAME_INDEX %fixed-stack.0
+    G_STORE %5(s32), %6(p0) :: (store 4 into %fixed-stack.0)
+    %18:_(p0) = G_GLOBAL_VALUE @.str
+    %17:_(p0) = COPY %18(p0)
+    %7:_(p0) = G_FRAME_INDEX %stack.0.fmt.addr
+    %8:_(p0) = G_FRAME_INDEX %stack.1.ap
+    %9:_(p0) = G_FRAME_INDEX %stack.2.aq
+    %10:_(p0) = G_FRAME_INDEX %stack.3.s
+    G_STORE %0(p0), %7(p0) :: (store 4 into %ir.fmt.addr)
+    G_VASTART %8(p0) :: (store 4 into %ir.ap1, align 1)
+    G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.va_copy), %9(p0), %8(p0)
+    %11:_(p0) = G_LOAD %9(p0) :: (load 4 from %ir.aq)
+    %12:_(s32) = G_CONSTANT i32 4
+    %13:_(p0) = G_GEP %11, %12(s32)
+    G_STORE %13(p0), %9(p0) :: (store 4 into %ir.aq)
+    %14:_(p0) = G_LOAD %11(p0) :: (load 4 from %ir.2)
+    G_STORE %14(p0), %10(p0) :: (store 4 into %ir.s)
+    %15:_(p0) = G_LOAD %10(p0) :: (load 4 from %ir.s)
+    ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
+    $a0 = COPY %17(p0)
+    $a1 = COPY %15(p0)
+    JAL @printf, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit-def $v0
+    ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
+    RetRA
+
+...

Added: llvm/trunk/test/CodeGen/Mips/GlobalISel/llvm-ir/var_arg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/GlobalISel/llvm-ir/var_arg.ll?rev=372555&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/GlobalISel/llvm-ir/var_arg.ll (added)
+++ llvm/trunk/test/CodeGen/Mips/GlobalISel/llvm-ir/var_arg.ll Mon Sep 23 01:11:41 2019
@@ -0,0 +1,67 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc  -O0 -mtriple=mipsel-linux-gnu -global-isel  -verify-machineinstrs %s -o -| FileCheck %s -check-prefixes=MIPS32
+
+ at .str = private unnamed_addr constant [11 x i8] c"string %s\0A\00", align 1
+declare void @llvm.va_start(i8*)
+declare void @llvm.va_copy(i8*, i8*)
+declare i32 @printf(i8*, ...)
+
+define void @testVaCopyArg(i8* %fmt, ...) {
+; MIPS32-LABEL: testVaCopyArg:
+; MIPS32:       # %bb.0: # %entry
+; MIPS32-NEXT:    addiu $sp, $sp, -40
+; MIPS32-NEXT:    .cfi_def_cfa_offset 40
+; MIPS32-NEXT:    sw $ra, 36($sp) # 4-byte Folded Spill
+; MIPS32-NEXT:    .cfi_offset 31, -4
+; MIPS32-NEXT:    addiu $1, $sp, 44
+; MIPS32-NEXT:    sw $5, 0($1)
+; MIPS32-NEXT:    addiu $1, $sp, 48
+; MIPS32-NEXT:    sw $6, 0($1)
+; MIPS32-NEXT:    addiu $1, $sp, 52
+; MIPS32-NEXT:    sw $7, 0($1)
+; MIPS32-NEXT:    lui $1, %hi($.str)
+; MIPS32-NEXT:    addiu $1, $1, %lo($.str)
+; MIPS32-NEXT:    addiu $2, $sp, 32
+; MIPS32-NEXT:    addiu $3, $sp, 28
+; MIPS32-NEXT:    addiu $5, $sp, 24
+; MIPS32-NEXT:    addiu $6, $sp, 20
+; MIPS32-NEXT:    sw $4, 0($2)
+; MIPS32-NEXT:    addiu $2, $sp, 44
+; MIPS32-NEXT:    sw $2, 0($3)
+; MIPS32-NEXT:    lw $2, 0($3)
+; MIPS32-NEXT:    sw $2, 0($5)
+; MIPS32-NEXT:    lw $2, 0($5)
+; MIPS32-NEXT:    ori $3, $zero, 4
+; MIPS32-NEXT:    addu $3, $2, $3
+; MIPS32-NEXT:    sw $3, 0($5)
+; MIPS32-NEXT:    lw $2, 0($2)
+; MIPS32-NEXT:    sw $2, 0($6)
+; MIPS32-NEXT:    lw $5, 0($6)
+; MIPS32-NEXT:    move $4, $1
+; MIPS32-NEXT:    jal printf
+; MIPS32-NEXT:    nop
+; MIPS32-NEXT:    lw $ra, 36($sp) # 4-byte Folded Reload
+; MIPS32-NEXT:    addiu $sp, $sp, 40
+; MIPS32-NEXT:    jr $ra
+; MIPS32-NEXT:    nop
+entry:
+  %fmt.addr = alloca i8*, align 4
+  %ap = alloca i8*, align 4
+  %aq = alloca i8*, align 4
+  %s = alloca i8*, align 4
+  store i8* %fmt, i8** %fmt.addr, align 4
+  %ap1 = bitcast i8** %ap to i8*
+  call void @llvm.va_start(i8* %ap1)
+  %0 = bitcast i8** %aq to i8*
+  %1 = bitcast i8** %ap to i8*
+  call void @llvm.va_copy(i8* %0, i8* %1)
+  %argp.cur = load i8*, i8** %aq, align 4
+  %argp.next = getelementptr inbounds i8, i8* %argp.cur, i32 4
+  store i8* %argp.next, i8** %aq, align 4
+  %2 = bitcast i8* %argp.cur to i8**
+  %3 = load i8*, i8** %2, align 4
+  store i8* %3, i8** %s, align 4
+  %4 = load i8*, i8** %s, align 4
+  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i32 0, i32 0), i8* %4)
+  ret void
+}

Added: llvm/trunk/test/CodeGen/Mips/GlobalISel/regbankselect/var_arg.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/GlobalISel/regbankselect/var_arg.mir?rev=372555&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/GlobalISel/regbankselect/var_arg.mir (added)
+++ llvm/trunk/test/CodeGen/Mips/GlobalISel/regbankselect/var_arg.mir Mon Sep 23 01:11:41 2019
@@ -0,0 +1,125 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=regbankselect -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
+--- |
+
+  @.str = private unnamed_addr constant [11 x i8] c"string %s\0A\00", align 1
+  declare void @llvm.va_start(i8*) #0
+  declare void @llvm.va_copy(i8*, i8*) #0
+  declare i32 @printf(i8*, ...)
+
+  define void @testVaCopyArg(i8* %fmt, ...) {
+  entry:
+    %fmt.addr = alloca i8*, align 4
+    %ap = alloca i8*, align 4
+    %aq = alloca i8*, align 4
+    %s = alloca i8*, align 4
+    store i8* %fmt, i8** %fmt.addr, align 4
+    %ap1 = bitcast i8** %ap to i8*
+    call void @llvm.va_start(i8* %ap1)
+    %0 = bitcast i8** %aq to i8*
+    %1 = bitcast i8** %ap to i8*
+    call void @llvm.va_copy(i8* %0, i8* %1)
+    %argp.cur = load i8*, i8** %aq, align 4
+    %argp.next = getelementptr inbounds i8, i8* %argp.cur, i32 4
+    store i8* %argp.next, i8** %aq, align 4
+    %2 = bitcast i8* %argp.cur to i8**
+    %3 = load i8*, i8** %2, align 4
+    store i8* %3, i8** %s, align 4
+    %4 = load i8*, i8** %s, align 4
+    %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i32 0, i32 0), i8* %4)
+    ret void
+  }
+
+...
+---
+name:            testVaCopyArg
+alignment:       4
+legalized:       true
+tracksRegLiveness: true
+liveins:
+  - { reg: '$a0' }
+fixedStack:
+  - { id: 0, offset: 12, size: 4, alignment: 4, isImmutable: true }
+  - { id: 1, offset: 8, size: 4, alignment: 8, isImmutable: true }
+  - { id: 2, offset: 4, size: 4, alignment: 4, isImmutable: true }
+  - { id: 3, offset: 4, size: 4, alignment: 4, isImmutable: true }
+stack:
+  - { id: 0, name: fmt.addr, size: 4, alignment: 4 }
+  - { id: 1, name: ap, size: 4, alignment: 4 }
+  - { id: 2, name: aq, size: 4, alignment: 4 }
+  - { id: 3, name: s, size: 4, alignment: 4 }
+machineFunctionInfo: {}
+body:             |
+  bb.1.entry:
+    liveins: $a0, $a1, $a2, $a3
+
+    ; MIPS32-LABEL: name: testVaCopyArg
+    ; MIPS32: liveins: $a0, $a1, $a2, $a3
+    ; MIPS32: [[COPY:%[0-9]+]]:gprb(p0) = COPY $a0
+    ; MIPS32: [[COPY1:%[0-9]+]]:gprb(s32) = COPY $a1
+    ; MIPS32: [[FRAME_INDEX:%[0-9]+]]:gprb(p0) = G_FRAME_INDEX %fixed-stack.1
+    ; MIPS32: G_STORE [[COPY1]](s32), [[FRAME_INDEX]](p0) :: (store 4 into %fixed-stack.1)
+    ; MIPS32: [[COPY2:%[0-9]+]]:gprb(s32) = COPY $a2
+    ; MIPS32: [[FRAME_INDEX1:%[0-9]+]]:gprb(p0) = G_FRAME_INDEX %fixed-stack.2
+    ; MIPS32: G_STORE [[COPY2]](s32), [[FRAME_INDEX1]](p0) :: (store 4 into %fixed-stack.2)
+    ; MIPS32: [[COPY3:%[0-9]+]]:gprb(s32) = COPY $a3
+    ; MIPS32: [[FRAME_INDEX2:%[0-9]+]]:gprb(p0) = G_FRAME_INDEX %fixed-stack.3
+    ; MIPS32: G_STORE [[COPY3]](s32), [[FRAME_INDEX2]](p0) :: (store 4 into %fixed-stack.3)
+    ; MIPS32: [[GV:%[0-9]+]]:gprb(p0) = G_GLOBAL_VALUE @.str
+    ; MIPS32: [[COPY4:%[0-9]+]]:gprb(p0) = COPY [[GV]](p0)
+    ; MIPS32: [[FRAME_INDEX3:%[0-9]+]]:gprb(p0) = G_FRAME_INDEX %stack.0.fmt.addr
+    ; MIPS32: [[FRAME_INDEX4:%[0-9]+]]:gpr32(p0) = G_FRAME_INDEX %stack.1.ap
+    ; MIPS32: [[FRAME_INDEX5:%[0-9]+]]:gpr32(p0) = G_FRAME_INDEX %stack.2.aq
+    ; MIPS32: [[FRAME_INDEX6:%[0-9]+]]:gprb(p0) = G_FRAME_INDEX %stack.3.s
+    ; MIPS32: G_STORE [[COPY]](p0), [[FRAME_INDEX3]](p0) :: (store 4 into %ir.fmt.addr)
+    ; MIPS32: G_VASTART [[FRAME_INDEX4]](p0) :: (store 4 into %ir.ap1, align 1)
+    ; MIPS32: [[LW:%[0-9]+]]:gpr32 = LW [[FRAME_INDEX4]](p0), 0 :: (load 4)
+    ; MIPS32: SW [[LW]], [[FRAME_INDEX5]](p0), 0 :: (store 4)
+    ; MIPS32: [[LOAD:%[0-9]+]]:gprb(p0) = G_LOAD [[FRAME_INDEX5]](p0) :: (load 4 from %ir.aq)
+    ; MIPS32: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 4
+    ; MIPS32: [[GEP:%[0-9]+]]:gprb(p0) = G_GEP [[LOAD]], [[C]](s32)
+    ; MIPS32: G_STORE [[GEP]](p0), [[FRAME_INDEX5]](p0) :: (store 4 into %ir.aq)
+    ; MIPS32: [[LOAD1:%[0-9]+]]:gprb(p0) = G_LOAD [[LOAD]](p0) :: (load 4 from %ir.2)
+    ; MIPS32: G_STORE [[LOAD1]](p0), [[FRAME_INDEX6]](p0) :: (store 4 into %ir.s)
+    ; MIPS32: [[LOAD2:%[0-9]+]]:gprb(p0) = G_LOAD [[FRAME_INDEX6]](p0) :: (load 4 from %ir.s)
+    ; MIPS32: ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
+    ; MIPS32: $a0 = COPY [[COPY4]](p0)
+    ; MIPS32: $a1 = COPY [[LOAD2]](p0)
+    ; MIPS32: JAL @printf, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit-def $v0
+    ; MIPS32: ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
+    ; MIPS32: RetRA
+    %0:_(p0) = COPY $a0
+    %1:_(s32) = COPY $a1
+    %2:_(p0) = G_FRAME_INDEX %fixed-stack.2
+    G_STORE %1(s32), %2(p0) :: (store 4 into %fixed-stack.2)
+    %3:_(s32) = COPY $a2
+    %4:_(p0) = G_FRAME_INDEX %fixed-stack.1
+    G_STORE %3(s32), %4(p0) :: (store 4 into %fixed-stack.1)
+    %5:_(s32) = COPY $a3
+    %6:_(p0) = G_FRAME_INDEX %fixed-stack.0
+    G_STORE %5(s32), %6(p0) :: (store 4 into %fixed-stack.0)
+    %18:_(p0) = G_GLOBAL_VALUE @.str
+    %17:_(p0) = COPY %18(p0)
+    %7:_(p0) = G_FRAME_INDEX %stack.0.fmt.addr
+    %8:gpr32(p0) = G_FRAME_INDEX %stack.1.ap
+    %9:gpr32(p0) = G_FRAME_INDEX %stack.2.aq
+    %10:_(p0) = G_FRAME_INDEX %stack.3.s
+    G_STORE %0(p0), %7(p0) :: (store 4 into %ir.fmt.addr)
+    G_VASTART %8(p0) :: (store 4 into %ir.ap1, align 1)
+    %19:gpr32 = LW %8(p0), 0 :: (load 4)
+    SW %19, %9(p0), 0 :: (store 4)
+    %11:_(p0) = G_LOAD %9(p0) :: (load 4 from %ir.aq)
+    %12:_(s32) = G_CONSTANT i32 4
+    %13:_(p0) = G_GEP %11, %12(s32)
+    G_STORE %13(p0), %9(p0) :: (store 4 into %ir.aq)
+    %14:_(p0) = G_LOAD %11(p0) :: (load 4 from %ir.2)
+    G_STORE %14(p0), %10(p0) :: (store 4 into %ir.s)
+    %15:_(p0) = G_LOAD %10(p0) :: (load 4 from %ir.s)
+    ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
+    $a0 = COPY %17(p0)
+    $a1 = COPY %15(p0)
+    JAL @printf, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit-def $v0
+    ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
+    RetRA
+
+...




More information about the llvm-commits mailing list