[llvm] r343315 - [MIPS GlobalISel] Lower i64 arguments

Petar Jovanovic via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 28 06:28:48 PDT 2018


Author: petarj
Date: Fri Sep 28 06:28:47 2018
New Revision: 343315

URL: http://llvm.org/viewvc/llvm-project?rev=343315&view=rev
Log:
[MIPS GlobalISel] Lower i64 arguments

Lower integer arguments larger then 32 bits for MIPS32.
setMostSignificantFirst is used in order for G_UNMERGE_VALUES and
G_MERGE_VALUES to always hold registers in same order, regardless of
endianness.

Patch by Petar Avramovic.

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


Added:
    llvm/trunk/test/CodeGen/Mips/GlobalISel/irtranslator/split_args.ll
Modified:
    llvm/trunk/lib/Target/Mips/MipsCallLowering.cpp
    llvm/trunk/lib/Target/Mips/MipsCallLowering.h

Modified: llvm/trunk/lib/Target/Mips/MipsCallLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsCallLowering.cpp?rev=343315&r1=343314&r2=343315&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsCallLowering.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsCallLowering.cpp Fri Sep 28 06:28:47 2018
@@ -36,15 +36,58 @@ bool MipsCallLowering::MipsHandler::assi
   return true;
 }
 
+bool MipsCallLowering::MipsHandler::assignVRegs(ArrayRef<unsigned> VRegs,
+                                                ArrayRef<CCValAssign> ArgLocs,
+                                                unsigned ArgLocsStartIndex) {
+  for (unsigned i = 0; i < VRegs.size(); ++i)
+    if (!assign(VRegs[i], ArgLocs[ArgLocsStartIndex + i]))
+      return false;
+  return true;
+}
+
+void MipsCallLowering::MipsHandler::setMostSignificantFirst(
+    SmallVectorImpl<unsigned> &VRegs) {
+  if (MIRBuilder.getMF().getDataLayout().isLittleEndian())
+    std::reverse(VRegs.begin(), VRegs.end());
+}
+
+bool MipsCallLowering::MipsHandler::handle(
+    ArrayRef<CCValAssign> ArgLocs, ArrayRef<CallLowering::ArgInfo> Args) {
+  SmallVector<unsigned, 4> VRegs;
+  unsigned SplitLength;
+  const Function &F = MIRBuilder.getMF().getFunction();
+  const DataLayout &DL = F.getParent()->getDataLayout();
+  const MipsTargetLowering &TLI = *static_cast<const MipsTargetLowering *>(
+      MIRBuilder.getMF().getSubtarget().getTargetLowering());
+
+  for (unsigned ArgsIndex = 0, ArgLocsIndex = 0; ArgsIndex < Args.size();
+       ++ArgsIndex, ArgLocsIndex += SplitLength) {
+    EVT VT = TLI.getValueType(DL, Args[ArgsIndex].Ty);
+    SplitLength = TLI.getNumRegistersForCallingConv(F.getContext(),
+                                                    F.getCallingConv(), VT);
+    if (SplitLength > 1) {
+      VRegs.clear();
+      MVT RegisterVT = TLI.getRegisterTypeForCallingConv(
+          F.getContext(), F.getCallingConv(), VT);
+      for (unsigned i = 0; i < SplitLength; ++i)
+        VRegs.push_back(MRI.createGenericVirtualRegister(LLT{RegisterVT}));
+
+      if (!handleSplit(VRegs, ArgLocs, ArgLocsIndex, Args[ArgsIndex].Reg))
+        return false;
+    } else {
+      if (!assign(Args[ArgsIndex].Reg, ArgLocs[ArgLocsIndex]))
+        return false;
+    }
+  }
+  return true;
+}
+
 namespace {
 class IncomingValueHandler : public MipsCallLowering::MipsHandler {
 public:
   IncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
       : MipsHandler(MIRBuilder, MRI) {}
 
-  bool handle(ArrayRef<CCValAssign> ArgLocs,
-              ArrayRef<CallLowering::ArgInfo> Args);
-
 private:
   void assignValueToReg(unsigned ValVReg, const CCValAssign &VA) override;
 
@@ -53,6 +96,10 @@ private:
 
   void assignValueToAddress(unsigned ValVReg, const CCValAssign &VA) override;
 
+  bool handleSplit(SmallVectorImpl<unsigned> &VRegs,
+                   ArrayRef<CCValAssign> ArgLocs, unsigned ArgLocsStartIndex,
+                   unsigned ArgsReg) override;
+
   virtual void markPhysRegUsed(unsigned PhysReg) {
     MIRBuilder.getMBB().addLiveIn(PhysReg);
   }
@@ -128,12 +175,14 @@ void IncomingValueHandler::assignValueTo
     buildLoad(ValVReg, VA);
 }
 
-bool IncomingValueHandler::handle(ArrayRef<CCValAssign> ArgLocs,
-                                  ArrayRef<CallLowering::ArgInfo> Args) {
-  for (unsigned i = 0, ArgsSize = Args.size(); i < ArgsSize; ++i) {
-    if (!assign(Args[i].Reg, ArgLocs[i]))
-      return false;
-  }
+bool IncomingValueHandler::handleSplit(SmallVectorImpl<unsigned> &VRegs,
+                                       ArrayRef<CCValAssign> ArgLocs,
+                                       unsigned ArgLocsStartIndex,
+                                       unsigned ArgsReg) {
+  if (!assignVRegs(VRegs, ArgLocs, ArgLocsStartIndex))
+    return false;
+  setMostSignificantFirst(VRegs);
+  MIRBuilder.buildMerge(ArgsReg, VRegs);
   return true;
 }
 
@@ -144,9 +193,6 @@ public:
                        MachineInstrBuilder &MIB)
       : MipsHandler(MIRBuilder, MRI), MIB(MIB) {}
 
-  bool handle(ArrayRef<CCValAssign> ArgLocs,
-              ArrayRef<CallLowering::ArgInfo> Args);
-
 private:
   void assignValueToReg(unsigned ValVReg, const CCValAssign &VA) override;
 
@@ -155,6 +201,10 @@ private:
 
   void assignValueToAddress(unsigned ValVReg, const CCValAssign &VA) override;
 
+  bool handleSplit(SmallVectorImpl<unsigned> &VRegs,
+                   ArrayRef<CCValAssign> ArgLocs, unsigned ArgLocsStartIndex,
+                   unsigned ArgsReg) override;
+
   unsigned extendRegister(unsigned ValReg, const CCValAssign &VA);
 
   MachineInstrBuilder &MIB;
@@ -228,17 +278,20 @@ unsigned OutgoingValueHandler::extendReg
   llvm_unreachable("unable to extend register");
 }
 
-bool OutgoingValueHandler::handle(ArrayRef<CCValAssign> ArgLocs,
-                                  ArrayRef<CallLowering::ArgInfo> Args) {
-  for (unsigned i = 0; i < Args.size(); ++i) {
-    if (!assign(Args[i].Reg, ArgLocs[i]))
-      return false;
-  }
+bool OutgoingValueHandler::handleSplit(SmallVectorImpl<unsigned> &VRegs,
+                                       ArrayRef<CCValAssign> ArgLocs,
+                                       unsigned ArgLocsStartIndex,
+                                       unsigned ArgsReg) {
+  MIRBuilder.buildUnmerge(VRegs, ArgsReg);
+  setMostSignificantFirst(VRegs);
+  if (!assignVRegs(VRegs, ArgLocs, ArgLocsStartIndex))
+    return false;
+
   return true;
 }
 
 static bool isSupportedType(Type *T) {
-  if (T->isIntegerTy() && T->getScalarSizeInBits() <= 32)
+  if (T->isIntegerTy())
     return true;
   if (T->isPointerTy())
     return true;
@@ -247,7 +300,9 @@ static bool isSupportedType(Type *T) {
 
 CCValAssign::LocInfo determineLocInfo(const MVT RegisterVT, const EVT VT,
                                       const ISD::ArgFlagsTy &Flags) {
-  if (VT.getSizeInBits() == RegisterVT.getSizeInBits())
+  // > does not mean loss of information as type RegisterVT can't hold type VT,
+  // it means that type VT is split into multiple registers of type RegisterVT
+  if (VT.getSizeInBits() >= RegisterVT.getSizeInBits())
     return CCValAssign::LocInfo::Full;
   if (Flags.isSExt())
     return CCValAssign::LocInfo::SExt;
@@ -304,12 +359,7 @@ bool MipsCallLowering::lowerReturn(Machi
     }
 
     SmallVector<ISD::OutputArg, 8> Outs;
-    subTargetRegTypeForCallingConv(
-        MIRBuilder, RetInfos, OrigArgIndices,
-        [&](ISD::ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
-            unsigned origIdx, unsigned partOffs) {
-          Outs.emplace_back(flags, vt, argvt, used, origIdx, partOffs);
-        });
+    subTargetRegTypeForCallingConv(F, RetInfos, OrigArgIndices, Outs);
 
     SmallVector<CCValAssign, 16> ArgLocs;
     MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
@@ -358,12 +408,7 @@ bool MipsCallLowering::lowerFormalArgume
   }
 
   SmallVector<ISD::InputArg, 8> Ins;
-  subTargetRegTypeForCallingConv(
-      MIRBuilder, ArgInfos, OrigArgIndices,
-      [&](ISD::ArgFlagsTy flags, EVT vt, EVT argvt, bool used, unsigned origIdx,
-          unsigned partOffs) {
-        Ins.emplace_back(flags, vt, argvt, used, origIdx, partOffs);
-      });
+  subTargetRegTypeForCallingConv(F, ArgInfos, OrigArgIndices, Ins);
 
   SmallVector<CCValAssign, 16> ArgLocs;
   MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
@@ -440,12 +485,7 @@ bool MipsCallLowering::lowerCall(Machine
   }
 
   SmallVector<ISD::OutputArg, 8> Outs;
-  subTargetRegTypeForCallingConv(
-      MIRBuilder, ArgInfos, OrigArgIndices,
-      [&](ISD::ArgFlagsTy flags, EVT vt, EVT argvt, bool used, unsigned origIdx,
-          unsigned partOffs) {
-        Outs.emplace_back(flags, vt, argvt, used, origIdx, partOffs);
-      });
+  subTargetRegTypeForCallingConv(F, ArgInfos, OrigArgIndices, Outs);
 
   SmallVector<CCValAssign, 8> ArgLocs;
   MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
@@ -477,12 +517,7 @@ bool MipsCallLowering::lowerCall(Machine
     splitToValueTypes(OrigRet, 0, ArgInfos, OrigRetIndices);
 
     SmallVector<ISD::InputArg, 8> Ins;
-    subTargetRegTypeForCallingConv(
-        MIRBuilder, ArgInfos, OrigRetIndices,
-        [&](ISD::ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
-            unsigned origIdx, unsigned partOffs) {
-          Ins.emplace_back(flags, vt, argvt, used, origIdx, partOffs);
-        });
+    subTargetRegTypeForCallingConv(F, ArgInfos, OrigRetIndices, Ins);
 
     SmallVector<CCValAssign, 8> ArgLocs;
     MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
@@ -501,11 +536,10 @@ bool MipsCallLowering::lowerCall(Machine
   return true;
 }
 
+template <typename T>
 void MipsCallLowering::subTargetRegTypeForCallingConv(
-    MachineIRBuilder &MIRBuilder, ArrayRef<ArgInfo> Args,
-    ArrayRef<unsigned> OrigArgIndices, const FunTy &PushBack) const {
-  MachineFunction &MF = MIRBuilder.getMF();
-  const Function &F = MF.getFunction();
+    const Function &F, ArrayRef<ArgInfo> Args,
+    ArrayRef<unsigned> OrigArgIndices, SmallVectorImpl<T> &ISDArgs) const {
   const DataLayout &DL = F.getParent()->getDataLayout();
   const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
 
@@ -515,12 +549,20 @@ void MipsCallLowering::subTargetRegTypeF
     EVT VT = TLI.getValueType(DL, Arg.Ty);
     MVT RegisterVT = TLI.getRegisterTypeForCallingConv(F.getContext(),
                                                        F.getCallingConv(), VT);
+    unsigned NumRegs = TLI.getNumRegistersForCallingConv(
+        F.getContext(), F.getCallingConv(), VT);
 
-    ISD::ArgFlagsTy Flags = Arg.Flags;
-    Flags.setOrigAlign(TLI.getABIAlignmentForCallingConv(Arg.Ty, DL));
+    for (unsigned i = 0; i < NumRegs; ++i) {
+      ISD::ArgFlagsTy Flags = Arg.Flags;
 
-    PushBack(Flags, RegisterVT, VT, true, OrigArgIndices[ArgNo], 0);
+      if (i == 0)
+        Flags.setOrigAlign(TLI.getABIAlignmentForCallingConv(Arg.Ty, DL));
+      else
+        Flags.setOrigAlign(1);
 
+      ISDArgs.emplace_back(Flags, RegisterVT, VT, true, OrigArgIndices[ArgNo],
+                           0);
+    }
     ++ArgNo;
   }
 }

Modified: llvm/trunk/lib/Target/Mips/MipsCallLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsCallLowering.h?rev=343315&r1=343314&r2=343315&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsCallLowering.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsCallLowering.h Fri Sep 28 06:28:47 2018
@@ -31,13 +31,21 @@ public:
 
     virtual ~MipsHandler() = default;
 
+    bool handle(ArrayRef<CCValAssign> ArgLocs,
+                ArrayRef<CallLowering::ArgInfo> Args);
+
   protected:
-    bool assign(unsigned VReg, const CCValAssign &VA);
+    bool assignVRegs(ArrayRef<unsigned> VRegs, ArrayRef<CCValAssign> ArgLocs,
+                     unsigned Index);
+
+    void setMostSignificantFirst(SmallVectorImpl<unsigned> &VRegs);
 
     MachineIRBuilder &MIRBuilder;
     MachineRegisterInfo &MRI;
 
   private:
+    bool assign(unsigned VReg, const CCValAssign &VA);
+
     virtual unsigned getStackAddress(const CCValAssign &VA,
                                      MachineMemOperand *&MMO) = 0;
 
@@ -45,6 +53,10 @@ public:
 
     virtual void assignValueToAddress(unsigned ValVReg,
                                       const CCValAssign &VA) = 0;
+
+    virtual bool handleSplit(SmallVectorImpl<unsigned> &VRegs,
+                             ArrayRef<CCValAssign> ArgLocs,
+                             unsigned ArgLocsStartIndex, unsigned ArgsReg) = 0;
   };
 
   MipsCallLowering(const MipsTargetLowering &TLI);
@@ -60,18 +72,13 @@ public:
                  ArrayRef<ArgInfo> OrigArgs) const override;
 
 private:
-  using FunTy =
-      std::function<void(ISD::ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
-                         unsigned origIdx, unsigned partOffs)>;
-
   /// Based on registers available on target machine split or extend
   /// type if needed, also change pointer type to appropriate integer
-  /// type. Lambda will fill some info so we can tell MipsCCState to
-  /// assign physical registers.
-  void subTargetRegTypeForCallingConv(MachineIRBuilder &MIRBuilder,
-                                      ArrayRef<ArgInfo> Args,
+  /// type.
+  template <typename T>
+  void subTargetRegTypeForCallingConv(const Function &F, ArrayRef<ArgInfo> Args,
                                       ArrayRef<unsigned> OrigArgIndices,
-                                      const FunTy &PushBack) const;
+                                      SmallVectorImpl<T> &ISDArgs) const;
 
   /// Split structures and arrays, save original argument indices since
   /// Mips calling conv needs info about original argument type.

Added: llvm/trunk/test/CodeGen/Mips/GlobalISel/irtranslator/split_args.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/GlobalISel/irtranslator/split_args.ll?rev=343315&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/GlobalISel/irtranslator/split_args.ll (added)
+++ llvm/trunk/test/CodeGen/Mips/GlobalISel/irtranslator/split_args.ll Fri Sep 28 06:28:47 2018
@@ -0,0 +1,106 @@
+; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
+
+define i64 @i64_reg(i64 %a) {
+  ; MIPS32-LABEL: name: i64_reg
+  ; MIPS32: bb.1.entry:
+  ; MIPS32:   liveins: $a0, $a1
+  ; MIPS32:   [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+  ; MIPS32:   [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
+  ; MIPS32:   [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY]](s32)
+  ; MIPS32:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[MV]](s64)
+  ; MIPS32:   $v0 = COPY [[UV1]](s32)
+  ; MIPS32:   $v1 = COPY [[UV]](s32)
+  ; MIPS32:   RetRA implicit $v0, implicit $v1
+entry:
+  ret i64 %a
+}
+
+define i64 @i64_stack(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i64 %a) {
+  ; MIPS32-LABEL: name: i64_stack
+  ; MIPS32: fixedStack:
+  ; MIPS32-DAG:  - { id: [[STACK0:[0-9]+]], type: default, offset: 20, size: 4, alignment: 4,
+  ; MIPS32-DAG:  - { id: [[STACK1:[0-9]+]], type: default, offset: 16, size: 4, alignment: 8,
+  ; MIPS32: bb.1.entry:
+  ; MIPS32:   liveins: $a0, $a1, $a2, $a3
+  ; MIPS32:   [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+  ; MIPS32:   [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
+  ; MIPS32:   [[COPY2:%[0-9]+]]:_(s32) = COPY $a2
+  ; MIPS32:   [[COPY3:%[0-9]+]]:_(s32) = COPY $a3
+  ; MIPS32:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
+  ; MIPS32:   [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load 4 from %fixed-stack.[[STACK1]], align 0)
+  ; MIPS32:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+  ; MIPS32:   [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX1]](p0) :: (load 4 from %fixed-stack.[[STACK0]], align 0)
+  ; MIPS32:   [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[LOAD1]](s32), [[LOAD]](s32)
+  ; MIPS32:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[MV]](s64)
+  ; MIPS32:   $v0 = COPY [[UV1]](s32)
+  ; MIPS32:   $v1 = COPY [[UV]](s32)
+  ; MIPS32:   RetRA implicit $v0, implicit $v1
+entry:
+  ret i64 %a
+}
+
+define i64 @i64_reg_allign(i32 %a0, i64 %a) {
+  ; MIPS32-LABEL: name: i64_reg_allign
+  ; MIPS32: bb.1.entry:
+  ; MIPS32:   liveins: $a0, $a2, $a3
+  ; MIPS32:   [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+  ; MIPS32:   [[COPY1:%[0-9]+]]:_(s32) = COPY $a2
+  ; MIPS32:   [[COPY2:%[0-9]+]]:_(s32) = COPY $a3
+  ; MIPS32:   [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY2]](s32), [[COPY1]](s32)
+  ; MIPS32:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[MV]](s64)
+  ; MIPS32:   $v0 = COPY [[UV1]](s32)
+  ; MIPS32:   $v1 = COPY [[UV]](s32)
+  ; MIPS32:   RetRA implicit $v0, implicit $v1
+entry:
+  ret i64 %a
+}
+
+define i64 @i64_stack_allign(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %s16, i64 %a) {
+  ; MIPS32-LABEL: name: i64_stack_allign
+  ; MIPS32: fixedStack:
+  ; MIPS32-DAG:  - { id: [[STACK0:[0-9]+]], type: default, offset: 28, size: 4, alignment: 4,
+  ; MIPS32-DAG:  - { id: [[STACK1:[0-9]+]], type: default, offset: 24, size: 4, alignment: 8,
+  ; MIPS32-DAG:  - { id: [[STACK2:[0-9]+]], type: default, offset: 16, size: 4, alignment: 8,
+  ; MIPS32: bb.1.entry:
+  ; MIPS32:   liveins: $a0, $a1, $a2, $a3
+  ; MIPS32:   [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+  ; MIPS32:   [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
+  ; MIPS32:   [[COPY2:%[0-9]+]]:_(s32) = COPY $a2
+  ; MIPS32:   [[COPY3:%[0-9]+]]:_(s32) = COPY $a3
+  ; MIPS32:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.2
+  ; MIPS32:   [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load 4 from %fixed-stack.[[STACK2]], align 0)
+  ; MIPS32:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
+  ; MIPS32:   [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX1]](p0) :: (load 4 from %fixed-stack.[[STACK1]], align 0)
+  ; MIPS32:   [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+  ; MIPS32:   [[LOAD2:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX2]](p0) :: (load 4 from %fixed-stack.[[STACK0]], align 0)
+  ; MIPS32:   [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[LOAD2]](s32), [[LOAD1]](s32)
+  ; MIPS32:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[MV]](s64)
+  ; MIPS32:   $v0 = COPY [[UV1]](s32)
+  ; MIPS32:   $v1 = COPY [[UV]](s32)
+  ; MIPS32:   RetRA implicit $v0, implicit $v1
+entry:
+  ret i64 %a
+}
+
+define i64 @i64_reg_stack(i32 %a0, i32 %a1, i32 %a2, i64 %a) {
+  ; MIPS32-LABEL: name: i64_reg_stack
+  ; MIPS32: fixedStack:
+  ; MIPS32-DAG:  - { id: [[STACK0:[0-9]+]], type: default, offset: 20, size: 4, alignment: 4,
+  ; MIPS32-DAG:  - { id: [[STACK1:[0-9]+]], type: default, offset: 16, size: 4, alignment: 8,
+  ; MIPS32: bb.1.entry:
+  ; MIPS32:   liveins: $a0, $a1, $a2
+  ; MIPS32:   [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+  ; MIPS32:   [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
+  ; MIPS32:   [[COPY2:%[0-9]+]]:_(s32) = COPY $a2
+  ; MIPS32:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
+  ; MIPS32:   [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load 4 from %fixed-stack.[[STACK1]], align 0)
+  ; MIPS32:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+  ; MIPS32:   [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX1]](p0) :: (load 4 from %fixed-stack.[[STACK0]], align 0)
+  ; MIPS32:   [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[LOAD1]](s32), [[LOAD]](s32)
+  ; MIPS32:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[MV]](s64)
+  ; MIPS32:   $v0 = COPY [[UV1]](s32)
+  ; MIPS32:   $v1 = COPY [[UV]](s32)
+  ; MIPS32:   RetRA implicit $v0, implicit $v1
+entry:
+  ret i64 %a
+}




More information about the llvm-commits mailing list