[llvm] r320357 - [RISCV] Implement prolog and epilog insertion

Alex Bradbury via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 11 04:34:11 PST 2017


Author: asb
Date: Mon Dec 11 04:34:11 2017
New Revision: 320357

URL: http://llvm.org/viewvc/llvm-project?rev=320357&view=rev
Log:
[RISCV] Implement prolog and epilog insertion

As frame pointer elimination isn't implemented until a later patch and we make 
extensive use of update_llc_test_checks.py, this changes touches a lot of the 
RISC-V tests.

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

Modified:
    llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.cpp
    llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.h
    llvm/trunk/test/CodeGen/RISCV/addc-adde-sube-subc.ll
    llvm/trunk/test/CodeGen/RISCV/alu32.ll
    llvm/trunk/test/CodeGen/RISCV/bare-select.ll
    llvm/trunk/test/CodeGen/RISCV/blockaddress.ll
    llvm/trunk/test/CodeGen/RISCV/branch.ll
    llvm/trunk/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll
    llvm/trunk/test/CodeGen/RISCV/calls.ll
    llvm/trunk/test/CodeGen/RISCV/div.ll
    llvm/trunk/test/CodeGen/RISCV/frame.ll
    llvm/trunk/test/CodeGen/RISCV/i32-icmp.ll
    llvm/trunk/test/CodeGen/RISCV/imm.ll
    llvm/trunk/test/CodeGen/RISCV/indirectbr.ll
    llvm/trunk/test/CodeGen/RISCV/jumptable.ll
    llvm/trunk/test/CodeGen/RISCV/mem.ll
    llvm/trunk/test/CodeGen/RISCV/mul.ll
    llvm/trunk/test/CodeGen/RISCV/rem.ll
    llvm/trunk/test/CodeGen/RISCV/rotl-rotr.ll
    llvm/trunk/test/CodeGen/RISCV/select-cc.ll
    llvm/trunk/test/CodeGen/RISCV/sext-zext-trunc.ll
    llvm/trunk/test/CodeGen/RISCV/shifts.ll
    llvm/trunk/test/CodeGen/RISCV/wide-mem.ll

Modified: llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.cpp?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.cpp Mon Dec 11 04:34:11 2017
@@ -22,11 +22,144 @@ using namespace llvm;
 
 bool RISCVFrameLowering::hasFP(const MachineFunction &MF) const { return true; }
 
+// Determines the size of the frame and maximum call frame size.
+void RISCVFrameLowering::determineFrameLayout(MachineFunction &MF) const {
+  MachineFrameInfo &MFI = MF.getFrameInfo();
+  const RISCVRegisterInfo *RI = STI.getRegisterInfo();
+
+  // Get the number of bytes to allocate from the FrameInfo.
+  uint64_t FrameSize = MFI.getStackSize();
+
+  // Get the alignment.
+  uint64_t StackAlign = RI->needsStackRealignment(MF) ? MFI.getMaxAlignment()
+                                                      : getStackAlignment();
+
+  // Get the maximum call frame size of all the calls.
+  uint64_t MaxCallFrameSize = MFI.getMaxCallFrameSize();
+
+  // If we have dynamic alloca then MaxCallFrameSize needs to be aligned so
+  // that allocations will be aligned.
+  if (MFI.hasVarSizedObjects())
+    MaxCallFrameSize = alignTo(MaxCallFrameSize, StackAlign);
+
+  // Update maximum call frame size.
+  MFI.setMaxCallFrameSize(MaxCallFrameSize);
+
+  // Include call frame size in total.
+  if (!(hasReservedCallFrame(MF) && MFI.adjustsStack()))
+    FrameSize += MaxCallFrameSize;
+
+  // Make sure the frame is aligned.
+  FrameSize = alignTo(FrameSize, StackAlign);
+
+  // Update frame info.
+  MFI.setStackSize(FrameSize);
+}
+
+void RISCVFrameLowering::adjustReg(MachineBasicBlock &MBB,
+                                   MachineBasicBlock::iterator MBBI,
+                                   const DebugLoc &DL, unsigned DestReg,
+                                   unsigned SrcReg, int64_t Val,
+                                   MachineInstr::MIFlag Flag) const {
+  const RISCVInstrInfo *TII = STI.getInstrInfo();
+
+  if (DestReg == SrcReg && Val == 0)
+    return;
+
+  if (!isInt<12>(Val))
+    report_fatal_error("adjustReg cannot yet handle adjustments >12 bits");
+
+  BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), DestReg)
+      .addReg(SrcReg)
+      .addImm(Val)
+      .setMIFlag(Flag);
+}
+
+// Returns the register used to hold the frame pointer.
+static unsigned getFPReg(const RISCVSubtarget &STI) { return RISCV::X8; }
+
+// Returns the register used to hold the stack pointer.
+static unsigned getSPReg(const RISCVSubtarget &STI) { return RISCV::X2; }
+
 void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
-                                      MachineBasicBlock &MBB) const {}
+                                      MachineBasicBlock &MBB) const {
+  assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
+
+  if (!hasFP(MF)) {
+    report_fatal_error(
+        "emitPrologue doesn't support framepointer-less functions");
+  }
+
+  MachineFrameInfo &MFI = MF.getFrameInfo();
+  MachineBasicBlock::iterator MBBI = MBB.begin();
+
+  unsigned FPReg = getFPReg(STI);
+  unsigned SPReg = getSPReg(STI);
+
+  // Debug location must be unknown since the first debug location is used
+  // to determine the end of the prologue.
+  DebugLoc DL;
+
+  // Determine the correct frame layout
+  determineFrameLayout(MF);
+
+  // FIXME (note copied from Lanai): This appears to be overallocating.  Needs
+  // investigation. Get the number of bytes to allocate from the FrameInfo.
+  uint64_t StackSize = MFI.getStackSize();
+
+  // Early exit if there is no need to allocate on the stack
+  if (StackSize == 0 && !MFI.adjustsStack())
+    return;
+
+  // Allocate space on the stack if necessary.
+  adjustReg(MBB, MBBI, DL, SPReg, SPReg, -StackSize, MachineInstr::FrameSetup);
+
+  // The frame pointer is callee-saved, and code has been generated for us to
+  // save it to the stack. We need to skip over the storing of callee-saved
+  // registers as the frame pointer must be modified after it has been saved
+  // to the stack, not before.
+  // FIXME: assumes exactly one instruction is used to save each callee-saved
+  // register.
+  const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
+  std::advance(MBBI, CSI.size());
+
+  // Generate new FP.
+  adjustReg(MBB, MBBI, DL, FPReg, SPReg, StackSize, MachineInstr::FrameSetup);
+}
 
 void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
-                                      MachineBasicBlock &MBB) const {}
+                                      MachineBasicBlock &MBB) const {
+  if (!hasFP(MF)) {
+    report_fatal_error(
+        "emitEpilogue doesn't support framepointer-less functions");
+  }
+
+  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
+  const RISCVRegisterInfo *RI = STI.getRegisterInfo();
+  MachineFrameInfo &MFI = MF.getFrameInfo();
+  DebugLoc DL = MBBI->getDebugLoc();
+  unsigned FPReg = getFPReg(STI);
+  unsigned SPReg = getSPReg(STI);
+
+  // Skip to before the restores of callee-saved registers
+  // FIXME: assumes exactly one instruction is used to restore each
+  // callee-saved register.
+  MachineBasicBlock::iterator LastFrameDestroy = MBBI;
+  std::advance(LastFrameDestroy, -MFI.getCalleeSavedInfo().size());
+
+  uint64_t StackSize = MFI.getStackSize();
+
+  // Restore the stack pointer using the value of the frame pointer. Only
+  // necessary if the stack pointer was modified, meaning the stack size is
+  // unknown.
+  if (RI->needsStackRealignment(MF) || MFI.hasVarSizedObjects()) {
+    adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg, -StackSize,
+              MachineInstr::FrameDestroy);
+  }
+
+  // Deallocate stack
+  adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackSize, MachineInstr::FrameDestroy);
+}
 
 int RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF,
                                                int FI,
@@ -56,3 +189,13 @@ int RISCVFrameLowering::getFrameIndexRef
   }
   return Offset;
 }
+
+void RISCVFrameLowering::determineCalleeSaves(MachineFunction &MF,
+                                              BitVector &SavedRegs,
+                                              RegScavenger *RS) const {
+  TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
+  // TODO: Once frame pointer elimination is implemented, don't
+  // unconditionally spill the frame pointer and return address.
+  SavedRegs.set(RISCV::X1);
+  SavedRegs.set(RISCV::X8);
+}

Modified: llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.h?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.h (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.h Mon Dec 11 04:34:11 2017
@@ -24,7 +24,8 @@ public:
   explicit RISCVFrameLowering(const RISCVSubtarget &STI)
       : TargetFrameLowering(StackGrowsDown,
                             /*StackAlignment=*/16,
-                            /*LocalAreaOffset=*/0) {}
+                            /*LocalAreaOffset=*/0),
+        STI(STI) {}
 
   void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
@@ -32,6 +33,9 @@ public:
   int getFrameIndexReference(const MachineFunction &MF, int FI,
                              unsigned &FrameReg) const override;
 
+  void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
+                            RegScavenger *RS) const override;
+
   bool hasFP(const MachineFunction &MF) const override;
 
   MachineBasicBlock::iterator
@@ -39,6 +43,15 @@ public:
                                 MachineBasicBlock::iterator MI) const override {
     return MBB.erase(MI);
   }
+
+protected:
+  const RISCVSubtarget &STI;
+
+private:
+  void determineFrameLayout(MachineFunction &MF) const;
+  void adjustReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
+                 const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
+                 int64_t Val, MachineInstr::MIFlag Flag) const;
 };
 }
 #endif

Modified: llvm/trunk/test/CodeGen/RISCV/addc-adde-sube-subc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/addc-adde-sube-subc.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/addc-adde-sube-subc.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/addc-adde-sube-subc.ll Mon Dec 11 04:34:11 2017
@@ -7,11 +7,18 @@
 define i64 @addc_adde(i64 %a, i64 %b) {
 ; RV32I-LABEL: addc_adde:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    add a1, a1, a3
 ; RV32I-NEXT:    add a2, a0, a2
 ; RV32I-NEXT:    sltu a0, a2, a0
 ; RV32I-NEXT:    add a1, a1, a0
 ; RV32I-NEXT:    addi a0, a2, 0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = add i64 %a, %b
   ret i64 %1
@@ -20,10 +27,17 @@ define i64 @addc_adde(i64 %a, i64 %b) {
 define i64 @subc_sube(i64 %a, i64 %b) {
 ; RV32I-LABEL: subc_sube:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    sub a1, a1, a3
 ; RV32I-NEXT:    sltu a3, a0, a2
 ; RV32I-NEXT:    sub a1, a1, a3
 ; RV32I-NEXT:    sub a0, a0, a2
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sub i64 %a, %b
   ret i64 %1

Modified: llvm/trunk/test/CodeGen/RISCV/alu32.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/alu32.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/alu32.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/alu32.ll Mon Dec 11 04:34:11 2017
@@ -11,7 +11,14 @@
 define i32 @addi(i32 %a) nounwind {
 ; RV32I-LABEL: addi:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    addi a0, a0, 1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = add i32 %a, 1
   ret i32 %1
@@ -20,7 +27,14 @@ define i32 @addi(i32 %a) nounwind {
 define i32 @slti(i32 %a) nounwind {
 ; RV32I-LABEL: slti:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    slti a0, a0, 2
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = icmp slt i32 %a, 2
   %2 = zext i1 %1 to i32
@@ -30,7 +44,14 @@ define i32 @slti(i32 %a) nounwind {
 define i32 @sltiu(i32 %a) nounwind {
 ; RV32I-LABEL: sltiu:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    sltiu a0, a0, 3
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = icmp ult i32 %a, 3
   %2 = zext i1 %1 to i32
@@ -40,7 +61,14 @@ define i32 @sltiu(i32 %a) nounwind {
 define i32 @xori(i32 %a) nounwind {
 ; RV32I-LABEL: xori:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    xori a0, a0, 4
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = xor i32 %a, 4
   ret i32 %1
@@ -49,7 +77,14 @@ define i32 @xori(i32 %a) nounwind {
 define i32 @ori(i32 %a) nounwind {
 ; RV32I-LABEL: ori:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    ori a0, a0, 5
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = or i32 %a, 5
   ret i32 %1
@@ -58,7 +93,14 @@ define i32 @ori(i32 %a) nounwind {
 define i32 @andi(i32 %a) nounwind {
 ; RV32I-LABEL: andi:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    andi a0, a0, 6
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = and i32 %a, 6
   ret i32 %1
@@ -67,7 +109,14 @@ define i32 @andi(i32 %a) nounwind {
 define i32 @slli(i32 %a) nounwind {
 ; RV32I-LABEL: slli:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    slli a0, a0, 7
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = shl i32 %a, 7
   ret i32 %1
@@ -76,7 +125,14 @@ define i32 @slli(i32 %a) nounwind {
 define i32 @srli(i32 %a) nounwind {
 ; RV32I-LABEL: srli:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    srli a0, a0, 8
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = lshr i32 %a, 8
   ret i32 %1
@@ -85,7 +141,14 @@ define i32 @srli(i32 %a) nounwind {
 define i32 @srai(i32 %a) nounwind {
 ; RV32I-LABEL: srai:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    srai a0, a0, 9
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = ashr i32 %a, 9
   ret i32 %1
@@ -96,7 +159,14 @@ define i32 @srai(i32 %a) nounwind {
 define i32 @add(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: add:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    add a0, a0, a1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = add i32 %a, %b
   ret i32 %1
@@ -105,7 +175,14 @@ define i32 @add(i32 %a, i32 %b) nounwind
 define i32 @sub(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: sub:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    sub a0, a0, a1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sub i32 %a, %b
   ret i32 %1
@@ -114,7 +191,14 @@ define i32 @sub(i32 %a, i32 %b) nounwind
 define i32 @sll(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: sll:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    sll a0, a0, a1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = shl i32 %a, %b
   ret i32 %1
@@ -123,7 +207,14 @@ define i32 @sll(i32 %a, i32 %b) nounwind
 define i32 @slt(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: slt:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    slt a0, a0, a1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = icmp slt i32 %a, %b
   %2 = zext i1 %1 to i32
@@ -133,7 +224,14 @@ define i32 @slt(i32 %a, i32 %b) nounwind
 define i32 @sltu(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: sltu:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    sltu a0, a0, a1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = icmp ult i32 %a, %b
   %2 = zext i1 %1 to i32
@@ -143,7 +241,14 @@ define i32 @sltu(i32 %a, i32 %b) nounwin
 define i32 @xor(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: xor:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    xor a0, a0, a1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = xor i32 %a, %b
   ret i32 %1
@@ -152,7 +257,14 @@ define i32 @xor(i32 %a, i32 %b) nounwind
 define i32 @srl(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: srl:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    srl a0, a0, a1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = lshr i32 %a, %b
   ret i32 %1
@@ -161,7 +273,14 @@ define i32 @srl(i32 %a, i32 %b) nounwind
 define i32 @sra(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: sra:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    sra a0, a0, a1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = ashr i32 %a, %b
   ret i32 %1
@@ -170,7 +289,14 @@ define i32 @sra(i32 %a, i32 %b) nounwind
 define i32 @or(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: or:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    or a0, a0, a1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = or i32 %a, %b
   ret i32 %1
@@ -179,7 +305,14 @@ define i32 @or(i32 %a, i32 %b) nounwind
 define i32 @and(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: and:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    and a0, a0, a1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = and i32 %a, %b
   ret i32 %1

Modified: llvm/trunk/test/CodeGen/RISCV/bare-select.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/bare-select.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/bare-select.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/bare-select.ll Mon Dec 11 04:34:11 2017
@@ -5,12 +5,19 @@
 define i32 @bare_select(i1 %a, i32 %b, i32 %c) {
 ; RV32I-LABEL: bare_select:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    andi a0, a0, 1
 ; RV32I-NEXT:    bne a0, zero, .LBB0_2
 ; RV32I-NEXT:  # %bb.1:
 ; RV32I-NEXT:    addi a1, a2, 0
 ; RV32I-NEXT:  .LBB0_2:
 ; RV32I-NEXT:    addi a0, a1, 0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = select i1 %a, i32 %b, i32 %c
   ret i32 %1

Modified: llvm/trunk/test/CodeGen/RISCV/blockaddress.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/blockaddress.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/blockaddress.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/blockaddress.ll Mon Dec 11 04:34:11 2017
@@ -7,7 +7,10 @@
 define void @test_blockaddress() nounwind {
 ; RV32I-LABEL: test_blockaddress:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 0(sp)
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a0, %hi(addr)
 ; RV32I-NEXT:    addi a0, a0, %lo(addr)
 ; RV32I-NEXT:    lui a1, %hi(.Ltmp0)
@@ -17,7 +20,9 @@ define void @test_blockaddress() nounwin
 ; RV32I-NEXT:    jalr zero, a0, 0
 ; RV32I-NEXT:  .Ltmp0: # Block address taken
 ; RV32I-NEXT:  .LBB0_1: # %block
-; RV32I-NEXT:    lw ra, 0(sp)
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   store volatile i8* blockaddress(@test_blockaddress, %block), i8** @addr
   %val = load volatile i8*, i8** @addr

Modified: llvm/trunk/test/CodeGen/RISCV/branch.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/branch.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/branch.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/branch.ll Mon Dec 11 04:34:11 2017
@@ -5,6 +5,10 @@
 define void @foo(i32 %a, i32 *%b, i1 %c) {
 ; RV32I-LABEL: foo:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lw a3, 0(a1)
 ; RV32I-NEXT:    beq a3, a0, .LBB0_12
 ; RV32I-NEXT:    jal zero, .LBB0_1
@@ -52,6 +56,9 @@ define void @foo(i32 %a, i32 *%b, i1 %c)
 ; RV32I-NEXT:  .LBB0_11: # %test12
 ; RV32I-NEXT:    lw a0, 0(a1)
 ; RV32I-NEXT:  .LBB0_12: # %end
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
 
   %val1 = load volatile i32, i32* %b

Modified: llvm/trunk/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll Mon Dec 11 04:34:11 2017
@@ -15,6 +15,10 @@ declare i32 @llvm.ctpop.i32(i32)
 define i16 @test_bswap_i16(i16 %a) nounwind {
 ; RV32I-LABEL: test_bswap_i16:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a1, 4080
 ; RV32I-NEXT:    addi a1, a1, 0
 ; RV32I-NEXT:    slli a2, a0, 8
@@ -22,6 +26,9 @@ define i16 @test_bswap_i16(i16 %a) nounw
 ; RV32I-NEXT:    slli a0, a0, 24
 ; RV32I-NEXT:    or a0, a0, a1
 ; RV32I-NEXT:    srli a0, a0, 16
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %tmp = call i16 @llvm.bswap.i16(i16 %a)
   ret i16 %tmp
@@ -30,6 +37,10 @@ define i16 @test_bswap_i16(i16 %a) nounw
 define i32 @test_bswap_i32(i32 %a) nounwind {
 ; RV32I-LABEL: test_bswap_i32:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a1, 16
 ; RV32I-NEXT:    addi a1, a1, -256
 ; RV32I-NEXT:    srli a2, a0, 8
@@ -43,6 +54,9 @@ define i32 @test_bswap_i32(i32 %a) nounw
 ; RV32I-NEXT:    slli a0, a0, 24
 ; RV32I-NEXT:    or a0, a0, a2
 ; RV32I-NEXT:    or a0, a0, a1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %tmp = call i32 @llvm.bswap.i32(i32 %a)
   ret i32 %tmp
@@ -51,6 +65,10 @@ define i32 @test_bswap_i32(i32 %a) nounw
 define i64 @test_bswap_i64(i64 %a) nounwind {
 ; RV32I-LABEL: test_bswap_i64:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a2, 16
 ; RV32I-NEXT:    addi a3, a2, -256
 ; RV32I-NEXT:    srli a2, a1, 8
@@ -74,6 +92,9 @@ define i64 @test_bswap_i64(i64 %a) nounw
 ; RV32I-NEXT:    or a0, a0, a3
 ; RV32I-NEXT:    or a1, a0, a1
 ; RV32I-NEXT:    addi a0, a2, 0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %tmp = call i64 @llvm.bswap.i64(i64 %a)
   ret i64 %tmp
@@ -82,7 +103,10 @@ define i64 @test_bswap_i64(i64 %a) nounw
 define i8 @test_cttz_i8(i8 %a) nounwind {
 ; RV32I-LABEL: test_cttz_i8:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    addi a1, a0, 0
 ; RV32I-NEXT:    addi a0, zero, 8
 ; RV32I-NEXT:    andi a2, a1, 255
@@ -115,7 +139,9 @@ define i8 @test_cttz_i8(i8 %a) nounwind
 ; RV32I-NEXT:    jalr ra, a2, 0
 ; RV32I-NEXT:    srli a0, a0, 24
 ; RV32I-NEXT:  .LBB3_2: # %cond.end
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %tmp = call i8 @llvm.cttz.i8(i8 %a, i1 false)
   ret i8 %tmp
@@ -124,7 +150,10 @@ define i8 @test_cttz_i8(i8 %a) nounwind
 define i16 @test_cttz_i16(i16 %a) nounwind {
 ; RV32I-LABEL: test_cttz_i16:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    addi a1, a0, 0
 ; RV32I-NEXT:    addi a0, zero, 16
 ; RV32I-NEXT:    lui a2, 16
@@ -159,7 +188,9 @@ define i16 @test_cttz_i16(i16 %a) nounwi
 ; RV32I-NEXT:    jalr ra, a2, 0
 ; RV32I-NEXT:    srli a0, a0, 24
 ; RV32I-NEXT:  .LBB4_2: # %cond.end
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %tmp = call i16 @llvm.cttz.i16(i16 %a, i1 false)
   ret i16 %tmp
@@ -168,7 +199,10 @@ define i16 @test_cttz_i16(i16 %a) nounwi
 define i32 @test_cttz_i32(i32 %a) nounwind {
 ; RV32I-LABEL: test_cttz_i32:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    addi a1, a0, 0
 ; RV32I-NEXT:    addi a0, zero, 32
 ; RV32I-NEXT:    beq a1, zero, .LBB5_2
@@ -200,7 +234,9 @@ define i32 @test_cttz_i32(i32 %a) nounwi
 ; RV32I-NEXT:    jalr ra, a2, 0
 ; RV32I-NEXT:    srli a0, a0, 24
 ; RV32I-NEXT:  .LBB5_2: # %cond.end
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %tmp = call i32 @llvm.cttz.i32(i32 %a, i1 false)
   ret i32 %tmp
@@ -209,7 +245,10 @@ define i32 @test_cttz_i32(i32 %a) nounwi
 define i32 @test_ctlz_i32(i32 %a) nounwind {
 ; RV32I-LABEL: test_ctlz_i32:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    addi a1, a0, 0
 ; RV32I-NEXT:    addi a0, zero, 32
 ; RV32I-NEXT:    beq a1, zero, .LBB6_2
@@ -249,7 +288,9 @@ define i32 @test_ctlz_i32(i32 %a) nounwi
 ; RV32I-NEXT:    jalr ra, a2, 0
 ; RV32I-NEXT:    srli a0, a0, 24
 ; RV32I-NEXT:  .LBB6_2: # %cond.end
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %tmp = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
   ret i32 %tmp
@@ -258,14 +299,17 @@ define i32 @test_ctlz_i32(i32 %a) nounwi
 define i64 @test_cttz_i64(i64 %a) nounwind {
 ; RV32I-LABEL: test_cttz_i64:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 28(sp)
-; RV32I-NEXT:    sw s1, 24(sp)
-; RV32I-NEXT:    sw s2, 20(sp)
-; RV32I-NEXT:    sw s3, 16(sp)
-; RV32I-NEXT:    sw s4, 12(sp)
-; RV32I-NEXT:    sw s5, 8(sp)
-; RV32I-NEXT:    sw s6, 4(sp)
-; RV32I-NEXT:    sw s7, 0(sp)
+; RV32I-NEXT:    addi sp, sp, -48
+; RV32I-NEXT:    sw ra, 44(sp)
+; RV32I-NEXT:    sw s0, 40(sp)
+; RV32I-NEXT:    sw s1, 36(sp)
+; RV32I-NEXT:    sw s2, 32(sp)
+; RV32I-NEXT:    sw s3, 28(sp)
+; RV32I-NEXT:    sw s4, 24(sp)
+; RV32I-NEXT:    sw s5, 20(sp)
+; RV32I-NEXT:    sw s6, 16(sp)
+; RV32I-NEXT:    sw s7, 12(sp)
+; RV32I-NEXT:    addi s0, sp, 48
 ; RV32I-NEXT:    addi s1, a1, 0
 ; RV32I-NEXT:    addi s2, a0, 0
 ; RV32I-NEXT:    addi a0, s2, -1
@@ -317,14 +361,16 @@ define i64 @test_cttz_i64(i64 %a) nounwi
 ; RV32I-NEXT:  .LBB7_2:
 ; RV32I-NEXT:    addi a0, s1, 0
 ; RV32I-NEXT:    addi a1, zero, 0
-; RV32I-NEXT:    lw s7, 0(sp)
-; RV32I-NEXT:    lw s6, 4(sp)
-; RV32I-NEXT:    lw s5, 8(sp)
-; RV32I-NEXT:    lw s4, 12(sp)
-; RV32I-NEXT:    lw s3, 16(sp)
-; RV32I-NEXT:    lw s2, 20(sp)
-; RV32I-NEXT:    lw s1, 24(sp)
-; RV32I-NEXT:    lw ra, 28(sp)
+; RV32I-NEXT:    lw s7, 12(sp)
+; RV32I-NEXT:    lw s6, 16(sp)
+; RV32I-NEXT:    lw s5, 20(sp)
+; RV32I-NEXT:    lw s4, 24(sp)
+; RV32I-NEXT:    lw s3, 28(sp)
+; RV32I-NEXT:    lw s2, 32(sp)
+; RV32I-NEXT:    lw s1, 36(sp)
+; RV32I-NEXT:    lw s0, 40(sp)
+; RV32I-NEXT:    lw ra, 44(sp)
+; RV32I-NEXT:    addi sp, sp, 48
 ; RV32I-NEXT:    jalr zero, ra, 0
   %tmp = call i64 @llvm.cttz.i64(i64 %a, i1 false)
   ret i64 %tmp
@@ -333,7 +379,10 @@ define i64 @test_cttz_i64(i64 %a) nounwi
 define i8 @test_cttz_i8_zero_undef(i8 %a) nounwind {
 ; RV32I-LABEL: test_cttz_i8_zero_undef:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    addi a1, a0, -1
 ; RV32I-NEXT:    xori a0, a0, -1
 ; RV32I-NEXT:    and a0, a0, a1
@@ -359,7 +408,9 @@ define i8 @test_cttz_i8_zero_undef(i8 %a
 ; RV32I-NEXT:    addi a2, a2, %lo(__mulsi3)
 ; RV32I-NEXT:    jalr ra, a2, 0
 ; RV32I-NEXT:    srli a0, a0, 24
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %tmp = call i8 @llvm.cttz.i8(i8 %a, i1 true)
   ret i8 %tmp
@@ -368,7 +419,10 @@ define i8 @test_cttz_i8_zero_undef(i8 %a
 define i16 @test_cttz_i16_zero_undef(i16 %a) nounwind {
 ; RV32I-LABEL: test_cttz_i16_zero_undef:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    addi a1, a0, -1
 ; RV32I-NEXT:    xori a0, a0, -1
 ; RV32I-NEXT:    and a0, a0, a1
@@ -394,7 +448,9 @@ define i16 @test_cttz_i16_zero_undef(i16
 ; RV32I-NEXT:    addi a2, a2, %lo(__mulsi3)
 ; RV32I-NEXT:    jalr ra, a2, 0
 ; RV32I-NEXT:    srli a0, a0, 24
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %tmp = call i16 @llvm.cttz.i16(i16 %a, i1 true)
   ret i16 %tmp
@@ -403,7 +459,10 @@ define i16 @test_cttz_i16_zero_undef(i16
 define i32 @test_cttz_i32_zero_undef(i32 %a) nounwind {
 ; RV32I-LABEL: test_cttz_i32_zero_undef:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    addi a1, a0, -1
 ; RV32I-NEXT:    xori a0, a0, -1
 ; RV32I-NEXT:    and a0, a0, a1
@@ -429,7 +488,9 @@ define i32 @test_cttz_i32_zero_undef(i32
 ; RV32I-NEXT:    addi a2, a2, %lo(__mulsi3)
 ; RV32I-NEXT:    jalr ra, a2, 0
 ; RV32I-NEXT:    srli a0, a0, 24
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %tmp = call i32 @llvm.cttz.i32(i32 %a, i1 true)
   ret i32 %tmp
@@ -438,14 +499,17 @@ define i32 @test_cttz_i32_zero_undef(i32
 define i64 @test_cttz_i64_zero_undef(i64 %a) nounwind {
 ; RV32I-LABEL: test_cttz_i64_zero_undef:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 28(sp)
-; RV32I-NEXT:    sw s1, 24(sp)
-; RV32I-NEXT:    sw s2, 20(sp)
-; RV32I-NEXT:    sw s3, 16(sp)
-; RV32I-NEXT:    sw s4, 12(sp)
-; RV32I-NEXT:    sw s5, 8(sp)
-; RV32I-NEXT:    sw s6, 4(sp)
-; RV32I-NEXT:    sw s7, 0(sp)
+; RV32I-NEXT:    addi sp, sp, -48
+; RV32I-NEXT:    sw ra, 44(sp)
+; RV32I-NEXT:    sw s0, 40(sp)
+; RV32I-NEXT:    sw s1, 36(sp)
+; RV32I-NEXT:    sw s2, 32(sp)
+; RV32I-NEXT:    sw s3, 28(sp)
+; RV32I-NEXT:    sw s4, 24(sp)
+; RV32I-NEXT:    sw s5, 20(sp)
+; RV32I-NEXT:    sw s6, 16(sp)
+; RV32I-NEXT:    sw s7, 12(sp)
+; RV32I-NEXT:    addi s0, sp, 48
 ; RV32I-NEXT:    addi s1, a1, 0
 ; RV32I-NEXT:    addi s2, a0, 0
 ; RV32I-NEXT:    addi a0, s2, -1
@@ -497,14 +561,16 @@ define i64 @test_cttz_i64_zero_undef(i64
 ; RV32I-NEXT:  .LBB11_2:
 ; RV32I-NEXT:    addi a0, s1, 0
 ; RV32I-NEXT:    addi a1, zero, 0
-; RV32I-NEXT:    lw s7, 0(sp)
-; RV32I-NEXT:    lw s6, 4(sp)
-; RV32I-NEXT:    lw s5, 8(sp)
-; RV32I-NEXT:    lw s4, 12(sp)
-; RV32I-NEXT:    lw s3, 16(sp)
-; RV32I-NEXT:    lw s2, 20(sp)
-; RV32I-NEXT:    lw s1, 24(sp)
-; RV32I-NEXT:    lw ra, 28(sp)
+; RV32I-NEXT:    lw s7, 12(sp)
+; RV32I-NEXT:    lw s6, 16(sp)
+; RV32I-NEXT:    lw s5, 20(sp)
+; RV32I-NEXT:    lw s4, 24(sp)
+; RV32I-NEXT:    lw s3, 28(sp)
+; RV32I-NEXT:    lw s2, 32(sp)
+; RV32I-NEXT:    lw s1, 36(sp)
+; RV32I-NEXT:    lw s0, 40(sp)
+; RV32I-NEXT:    lw ra, 44(sp)
+; RV32I-NEXT:    addi sp, sp, 48
 ; RV32I-NEXT:    jalr zero, ra, 0
   %tmp = call i64 @llvm.cttz.i64(i64 %a, i1 true)
   ret i64 %tmp
@@ -513,7 +579,10 @@ define i64 @test_cttz_i64_zero_undef(i64
 define i32 @test_ctpop_i32(i32 %a) nounwind {
 ; RV32I-LABEL: test_ctpop_i32:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a1, 349525
 ; RV32I-NEXT:    addi a1, a1, 1365
 ; RV32I-NEXT:    srli a2, a0, 1
@@ -536,7 +605,9 @@ define i32 @test_ctpop_i32(i32 %a) nounw
 ; RV32I-NEXT:    addi a2, a2, %lo(__mulsi3)
 ; RV32I-NEXT:    jalr ra, a2, 0
 ; RV32I-NEXT:    srli a0, a0, 24
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = call i32 @llvm.ctpop.i32(i32 %a)
   ret i32 %1

Modified: llvm/trunk/test/CodeGen/RISCV/calls.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/calls.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/calls.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/calls.ll Mon Dec 11 04:34:11 2017
@@ -7,11 +7,16 @@ declare i32 @external_function(i32)
 define i32 @test_call_external(i32 %a) nounwind {
 ; RV32I-LABEL: test_call_external:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a1, %hi(external_function)
 ; RV32I-NEXT:    addi a1, a1, %lo(external_function)
 ; RV32I-NEXT:    jalr ra, a1, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = call i32 @external_function(i32 %a)
   ret i32 %1
@@ -20,7 +25,14 @@ define i32 @test_call_external(i32 %a) n
 define i32 @defined_function(i32 %a) nounwind {
 ; RV32I-LABEL: defined_function:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    addi a0, a0, 1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = add i32 %a, 1
   ret i32 %1
@@ -29,11 +41,16 @@ define i32 @defined_function(i32 %a) nou
 define i32 @test_call_defined(i32 %a) nounwind {
 ; RV32I-LABEL: test_call_defined:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a1, %hi(defined_function)
 ; RV32I-NEXT:    addi a1, a1, %lo(defined_function)
 ; RV32I-NEXT:    jalr ra, a1, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = call i32 @defined_function(i32 %a) nounwind
   ret i32 %1
@@ -42,11 +59,16 @@ define i32 @test_call_defined(i32 %a) no
 define i32 @test_call_indirect(i32 (i32)* %a, i32 %b) nounwind {
 ; RV32I-LABEL: test_call_indirect:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    addi a2, a0, 0
 ; RV32I-NEXT:    addi a0, a1, 0
 ; RV32I-NEXT:    jalr ra, a2, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = call i32 %a(i32 %b)
   ret i32 %1
@@ -58,7 +80,14 @@ define i32 @test_call_indirect(i32 (i32)
 define fastcc i32 @fastcc_function(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: fastcc_function:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    add a0, a0, a1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
  %1 = add i32 %a, %b
  ret i32 %1
@@ -67,16 +96,21 @@ define fastcc i32 @fastcc_function(i32 %
 define i32 @test_call_fastcc(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: test_call_fastcc:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
-; RV32I-NEXT:    sw s1, 8(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    sw s1, 4(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    addi s1, a0, 0
 ; RV32I-NEXT:    lui a0, %hi(fastcc_function)
 ; RV32I-NEXT:    addi a2, a0, %lo(fastcc_function)
 ; RV32I-NEXT:    addi a0, s1, 0
 ; RV32I-NEXT:    jalr ra, a2, 0
 ; RV32I-NEXT:    addi a0, s1, 0
-; RV32I-NEXT:    lw s1, 8(sp)
+; RV32I-NEXT:    lw s1, 4(sp)
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = call fastcc i32 @fastcc_function(i32 %a, i32 %b)
   ret i32 %a

Modified: llvm/trunk/test/CodeGen/RISCV/div.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/div.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/div.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/div.ll Mon Dec 11 04:34:11 2017
@@ -5,11 +5,16 @@
 define i32 @udiv(i32 %a, i32 %b) {
 ; RV32I-LABEL: udiv:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a2, %hi(__udivsi3)
 ; RV32I-NEXT:    addi a2, a2, %lo(__udivsi3)
 ; RV32I-NEXT:    jalr ra, a2, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = udiv i32 %a, %b
   ret i32 %1
@@ -18,12 +23,17 @@ define i32 @udiv(i32 %a, i32 %b) {
 define i32 @udiv_constant(i32 %a) {
 ; RV32I-LABEL: udiv_constant:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a1, %hi(__udivsi3)
 ; RV32I-NEXT:    addi a2, a1, %lo(__udivsi3)
 ; RV32I-NEXT:    addi a1, zero, 5
 ; RV32I-NEXT:    jalr ra, a2, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = udiv i32 %a, 5
   ret i32 %1
@@ -32,7 +42,14 @@ define i32 @udiv_constant(i32 %a) {
 define i32 @udiv_pow2(i32 %a) {
 ; RV32I-LABEL: udiv_pow2:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    srli a0, a0, 3
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = udiv i32 %a, 8
   ret i32 %1
@@ -41,11 +58,16 @@ define i32 @udiv_pow2(i32 %a) {
 define i64 @udiv64(i64 %a, i64 %b) {
 ; RV32I-LABEL: udiv64:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a4, %hi(__udivdi3)
 ; RV32I-NEXT:    addi a4, a4, %lo(__udivdi3)
 ; RV32I-NEXT:    jalr ra, a4, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = udiv i64 %a, %b
   ret i64 %1
@@ -54,13 +76,18 @@ define i64 @udiv64(i64 %a, i64 %b) {
 define i64 @udiv64_constant(i64 %a) {
 ; RV32I-LABEL: udiv64_constant:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a2, %hi(__udivdi3)
 ; RV32I-NEXT:    addi a4, a2, %lo(__udivdi3)
 ; RV32I-NEXT:    addi a2, zero, 5
 ; RV32I-NEXT:    addi a3, zero, 0
 ; RV32I-NEXT:    jalr ra, a4, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = udiv i64 %a, 5
   ret i64 %1
@@ -69,11 +96,16 @@ define i64 @udiv64_constant(i64 %a) {
 define i32 @sdiv(i32 %a, i32 %b) {
 ; RV32I-LABEL: sdiv:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a2, %hi(__divsi3)
 ; RV32I-NEXT:    addi a2, a2, %lo(__divsi3)
 ; RV32I-NEXT:    jalr ra, a2, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sdiv i32 %a, %b
   ret i32 %1
@@ -82,12 +114,17 @@ define i32 @sdiv(i32 %a, i32 %b) {
 define i32 @sdiv_constant(i32 %a) {
 ; RV32I-LABEL: sdiv_constant:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a1, %hi(__divsi3)
 ; RV32I-NEXT:    addi a2, a1, %lo(__divsi3)
 ; RV32I-NEXT:    addi a1, zero, 5
 ; RV32I-NEXT:    jalr ra, a2, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sdiv i32 %a, 5
   ret i32 %1
@@ -96,10 +133,17 @@ define i32 @sdiv_constant(i32 %a) {
 define i32 @sdiv_pow2(i32 %a) {
 ; RV32I-LABEL: sdiv_pow2:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    srai a1, a0, 31
 ; RV32I-NEXT:    srli a1, a1, 29
 ; RV32I-NEXT:    add a0, a0, a1
 ; RV32I-NEXT:    srai a0, a0, 3
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sdiv i32 %a, 8
   ret i32 %1
@@ -108,11 +152,16 @@ define i32 @sdiv_pow2(i32 %a) {
 define i64 @sdiv64(i64 %a, i64 %b) {
 ; RV32I-LABEL: sdiv64:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a4, %hi(__divdi3)
 ; RV32I-NEXT:    addi a4, a4, %lo(__divdi3)
 ; RV32I-NEXT:    jalr ra, a4, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sdiv i64 %a, %b
   ret i64 %1
@@ -121,13 +170,18 @@ define i64 @sdiv64(i64 %a, i64 %b) {
 define i64 @sdiv64_constant(i64 %a) {
 ; RV32I-LABEL: sdiv64_constant:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a2, %hi(__divdi3)
 ; RV32I-NEXT:    addi a4, a2, %lo(__divdi3)
 ; RV32I-NEXT:    addi a2, zero, 5
 ; RV32I-NEXT:    addi a3, zero, 0
 ; RV32I-NEXT:    jalr ra, a4, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sdiv i64 %a, 5
   ret i64 %1

Modified: llvm/trunk/test/CodeGen/RISCV/frame.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/frame.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/frame.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/frame.ll Mon Dec 11 04:34:11 2017
@@ -4,24 +4,26 @@
 
 %struct.key_t = type { i32, [16 x i8] }
 
-; FIXME: prologue and epilogue insertion must be implemented to complete this
-; test
-
 define i32 @test() nounwind {
 ; RV32I-LABEL: test:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -32
 ; RV32I-NEXT:    sw ra, 28(sp)
-; RV32I-NEXT:    sw zero, -8(s0)
-; RV32I-NEXT:    sw zero, -12(s0)
+; RV32I-NEXT:    sw s0, 24(sp)
+; RV32I-NEXT:    addi s0, sp, 32
 ; RV32I-NEXT:    sw zero, -16(s0)
 ; RV32I-NEXT:    sw zero, -20(s0)
 ; RV32I-NEXT:    sw zero, -24(s0)
+; RV32I-NEXT:    sw zero, -28(s0)
+; RV32I-NEXT:    sw zero, -32(s0)
 ; RV32I-NEXT:    lui a0, %hi(test1)
 ; RV32I-NEXT:    addi a1, a0, %lo(test1)
-; RV32I-NEXT:    addi a0, s0, -20
+; RV32I-NEXT:    addi a0, s0, -28
 ; RV32I-NEXT:    jalr ra, a1, 0
 ; RV32I-NEXT:    addi a0, zero, 0
+; RV32I-NEXT:    lw s0, 24(sp)
 ; RV32I-NEXT:    lw ra, 28(sp)
+; RV32I-NEXT:    addi sp, sp, 32
 ; RV32I-NEXT:    jalr zero, ra, 0
   %key = alloca %struct.key_t, align 4
   %1 = bitcast %struct.key_t* %key to i8*

Modified: llvm/trunk/test/CodeGen/RISCV/i32-icmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/i32-icmp.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/i32-icmp.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/i32-icmp.ll Mon Dec 11 04:34:11 2017
@@ -8,8 +8,15 @@
 define i32 @icmp_eq(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: icmp_eq:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    xor a0, a0, a1
 ; RV32I-NEXT:    sltiu a0, a0, 1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = icmp eq i32 %a, %b
   %2 = zext i1 %1 to i32
@@ -19,8 +26,15 @@ define i32 @icmp_eq(i32 %a, i32 %b) noun
 define i32 @icmp_ne(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: icmp_ne:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    xor a0, a0, a1
 ; RV32I-NEXT:    sltu a0, zero, a0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = icmp ne i32 %a, %b
   %2 = zext i1 %1 to i32
@@ -30,7 +44,14 @@ define i32 @icmp_ne(i32 %a, i32 %b) noun
 define i32 @icmp_ugt(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: icmp_ugt:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    sltu a0, a1, a0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = icmp ugt i32 %a, %b
   %2 = zext i1 %1 to i32
@@ -40,8 +61,15 @@ define i32 @icmp_ugt(i32 %a, i32 %b) nou
 define i32 @icmp_uge(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: icmp_uge:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    sltu a0, a0, a1
 ; RV32I-NEXT:    xori a0, a0, 1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = icmp uge i32 %a, %b
   %2 = zext i1 %1 to i32
@@ -51,7 +79,14 @@ define i32 @icmp_uge(i32 %a, i32 %b) nou
 define i32 @icmp_ult(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: icmp_ult:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    sltu a0, a0, a1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = icmp ult i32 %a, %b
   %2 = zext i1 %1 to i32
@@ -61,8 +96,15 @@ define i32 @icmp_ult(i32 %a, i32 %b) nou
 define i32 @icmp_ule(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: icmp_ule:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    sltu a0, a1, a0
 ; RV32I-NEXT:    xori a0, a0, 1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = icmp ule i32 %a, %b
   %2 = zext i1 %1 to i32
@@ -72,7 +114,14 @@ define i32 @icmp_ule(i32 %a, i32 %b) nou
 define i32 @icmp_sgt(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: icmp_sgt:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    slt a0, a1, a0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = icmp sgt i32 %a, %b
   %2 = zext i1 %1 to i32
@@ -82,8 +131,15 @@ define i32 @icmp_sgt(i32 %a, i32 %b) nou
 define i32 @icmp_sge(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: icmp_sge:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    slt a0, a0, a1
 ; RV32I-NEXT:    xori a0, a0, 1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = icmp sge i32 %a, %b
   %2 = zext i1 %1 to i32
@@ -93,7 +149,14 @@ define i32 @icmp_sge(i32 %a, i32 %b) nou
 define i32 @icmp_slt(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: icmp_slt:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    slt a0, a0, a1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = icmp slt i32 %a, %b
   %2 = zext i1 %1 to i32
@@ -103,8 +166,15 @@ define i32 @icmp_slt(i32 %a, i32 %b) nou
 define i32 @icmp_sle(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: icmp_sle:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    slt a0, a1, a0
 ; RV32I-NEXT:    xori a0, a0, 1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = icmp sle i32 %a, %b
   %2 = zext i1 %1 to i32

Modified: llvm/trunk/test/CodeGen/RISCV/imm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/imm.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/imm.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/imm.ll Mon Dec 11 04:34:11 2017
@@ -7,7 +7,14 @@
 define i32 @zero() nounwind {
 ; RV32I-LABEL: zero:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    addi a0, zero, 0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   ret i32 0
 }
@@ -15,7 +22,14 @@ define i32 @zero() nounwind {
 define i32 @pos_small() nounwind {
 ; RV32I-LABEL: pos_small:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    addi a0, zero, 2047
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   ret i32 2047
 }
@@ -23,7 +37,14 @@ define i32 @pos_small() nounwind {
 define i32 @neg_small() nounwind {
 ; RV32I-LABEL: neg_small:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    addi a0, zero, -2048
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   ret i32 -2048
 }
@@ -31,8 +52,15 @@ define i32 @neg_small() nounwind {
 define i32 @pos_i32() nounwind {
 ; RV32I-LABEL: pos_i32:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a0, 423811
 ; RV32I-NEXT:    addi a0, a0, -1297
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   ret i32 1735928559
 }
@@ -40,8 +68,15 @@ define i32 @pos_i32() nounwind {
 define i32 @neg_i32() nounwind {
 ; RV32I-LABEL: neg_i32:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a0, 912092
 ; RV32I-NEXT:    addi a0, a0, -273
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   ret i32 -559038737
 }

Modified: llvm/trunk/test/CodeGen/RISCV/indirectbr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/indirectbr.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/indirectbr.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/indirectbr.ll Mon Dec 11 04:34:11 2017
@@ -5,11 +5,16 @@
 define i32 @indirectbr(i8* %target) nounwind {
 ; RV32I-LABEL: indirectbr:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 0(sp)
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    jalr zero, a0, 0
 ; RV32I-NEXT:  .LBB0_1: # %ret
 ; RV32I-NEXT:    addi a0, zero, 0
-; RV32I-NEXT:    lw ra, 0(sp)
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   indirectbr i8* %target, [label %test_label]
 test_label:
@@ -21,11 +26,16 @@ ret:
 define i32 @indirectbr_with_offset(i8* %a) nounwind {
 ; RV32I-LABEL: indirectbr_with_offset:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 0(sp)
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    jalr zero, a0, 1380
 ; RV32I-NEXT:  .LBB1_1: # %ret
 ; RV32I-NEXT:    addi a0, zero, 0
-; RV32I-NEXT:    lw ra, 0(sp)
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %target = getelementptr inbounds i8, i8* %a, i32 1380
   indirectbr i8* %target, [label %test_label]

Modified: llvm/trunk/test/CodeGen/RISCV/jumptable.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/jumptable.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/jumptable.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/jumptable.ll Mon Dec 11 04:34:11 2017
@@ -5,6 +5,10 @@
 define void @jt(i32 %in, i32* %out) {
 ; RV32I-LABEL: jt:
 ; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    addi a2, zero, 2
 ; RV32I-NEXT:    blt a2, a0, .LBB0_3
 ; RV32I-NEXT:    jal zero, .LBB0_1
@@ -31,6 +35,9 @@ define void @jt(i32 %in, i32* %out) {
 ; RV32I-NEXT:    addi a0, zero, 1
 ; RV32I-NEXT:    sw a0, 0(a1)
 ; RV32I-NEXT:  .LBB0_9: # %exit
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
 ; RV32I-NEXT:  .LBB0_5: # %bb1
 ; RV32I-NEXT:    addi a0, zero, 4

Modified: llvm/trunk/test/CodeGen/RISCV/mem.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/mem.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/mem.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/mem.ll Mon Dec 11 04:34:11 2017
@@ -7,8 +7,15 @@
 define i32 @lb(i8 *%a) nounwind {
 ; RV32I-LABEL: lb:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lb a1, 0(a0)
 ; RV32I-NEXT:    lb a0, 1(a0)
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = getelementptr i8, i8* %a, i32 1
   %2 = load i8, i8* %1
@@ -21,8 +28,15 @@ define i32 @lb(i8 *%a) nounwind {
 define i32 @lh(i16 *%a) nounwind {
 ; RV32I-LABEL: lh:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lh a1, 0(a0)
 ; RV32I-NEXT:    lh a0, 4(a0)
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = getelementptr i16, i16* %a, i32 2
   %2 = load i16, i16* %1
@@ -35,8 +49,15 @@ define i32 @lh(i16 *%a) nounwind {
 define i32 @lw(i32 *%a) nounwind {
 ; RV32I-LABEL: lw:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lw a1, 0(a0)
 ; RV32I-NEXT:    lw a0, 12(a0)
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = getelementptr i32, i32* %a, i32 3
   %2 = load i32, i32* %1
@@ -47,9 +68,16 @@ define i32 @lw(i32 *%a) nounwind {
 define i32 @lbu(i8 *%a) nounwind {
 ; RV32I-LABEL: lbu:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lbu a1, 0(a0)
 ; RV32I-NEXT:    lbu a0, 4(a0)
 ; RV32I-NEXT:    add a0, a0, a1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = getelementptr i8, i8* %a, i32 4
   %2 = load i8, i8* %1
@@ -63,9 +91,16 @@ define i32 @lbu(i8 *%a) nounwind {
 define i32 @lhu(i16 *%a) nounwind {
 ; RV32I-LABEL: lhu:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lhu a1, 0(a0)
 ; RV32I-NEXT:    lhu a0, 10(a0)
 ; RV32I-NEXT:    add a0, a0, a1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = getelementptr i16, i16* %a, i32 5
   %2 = load i16, i16* %1
@@ -81,8 +116,15 @@ define i32 @lhu(i16 *%a) nounwind {
 define void @sb(i8 *%a, i8 %b) nounwind {
 ; RV32I-LABEL: sb:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    sb a1, 6(a0)
 ; RV32I-NEXT:    sb a1, 0(a0)
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   store i8 %b, i8* %a
   %1 = getelementptr i8, i8* %a, i32 6
@@ -93,8 +135,15 @@ define void @sb(i8 *%a, i8 %b) nounwind
 define void @sh(i16 *%a, i16 %b) nounwind {
 ; RV32I-LABEL: sh:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    sh a1, 14(a0)
 ; RV32I-NEXT:    sh a1, 0(a0)
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   store i16 %b, i16* %a
   %1 = getelementptr i16, i16* %a, i32 7
@@ -105,8 +154,15 @@ define void @sh(i16 *%a, i16 %b) nounwin
 define void @sw(i32 *%a, i32 %b) nounwind {
 ; RV32I-LABEL: sw:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    sw a1, 32(a0)
 ; RV32I-NEXT:    sw a1, 0(a0)
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   store i32 %b, i32* %a
   %1 = getelementptr i32, i32* %a, i32 8
@@ -118,10 +174,17 @@ define void @sw(i32 *%a, i32 %b) nounwin
 define i32 @load_sext_zext_anyext_i1(i1 *%a) nounwind {
 ; RV32I-LABEL: load_sext_zext_anyext_i1:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lb a1, 0(a0)
 ; RV32I-NEXT:    lbu a1, 1(a0)
 ; RV32I-NEXT:    lbu a0, 2(a0)
 ; RV32I-NEXT:    sub a0, a0, a1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   ; sextload i1
   %1 = getelementptr i1, i1* %a, i32 1
@@ -140,10 +203,17 @@ define i32 @load_sext_zext_anyext_i1(i1
 define i16 @load_sext_zext_anyext_i1_i16(i1 *%a) nounwind {
 ; RV32I-LABEL: load_sext_zext_anyext_i1_i16:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lb a1, 0(a0)
 ; RV32I-NEXT:    lbu a1, 1(a0)
 ; RV32I-NEXT:    lbu a0, 2(a0)
 ; RV32I-NEXT:    sub a0, a0, a1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   ; sextload i1
   %1 = getelementptr i1, i1* %a, i32 1
@@ -166,6 +236,10 @@ define i32 @lw_sw_global(i32 %a) nounwin
 ; TODO: the addi should be folded in to the lw/sw operations
 ; RV32I-LABEL: lw_sw_global:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a1, %hi(G)
 ; RV32I-NEXT:    addi a2, a1, %lo(G)
 ; RV32I-NEXT:    lw a1, 0(a2)
@@ -175,6 +249,9 @@ define i32 @lw_sw_global(i32 %a) nounwin
 ; RV32I-NEXT:    lw a3, 0(a2)
 ; RV32I-NEXT:    sw a0, 0(a2)
 ; RV32I-NEXT:    addi a0, a1, 0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = load volatile i32, i32* @G
   store i32 %a, i32* @G
@@ -189,11 +266,18 @@ define i32 @lw_sw_constant(i32 %a) nounw
 ; TODO: the addi should be folded in to the lw/sw
 ; RV32I-LABEL: lw_sw_constant:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a1, 912092
 ; RV32I-NEXT:    addi a2, a1, -273
 ; RV32I-NEXT:    lw a1, 0(a2)
 ; RV32I-NEXT:    sw a0, 0(a2)
 ; RV32I-NEXT:    addi a0, a1, 0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = inttoptr i32 3735928559 to i32*
   %2 = load volatile i32, i32* %1

Modified: llvm/trunk/test/CodeGen/RISCV/mul.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/mul.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/mul.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/mul.ll Mon Dec 11 04:34:11 2017
@@ -5,12 +5,17 @@
 define i32 @square(i32 %a) {
 ; RV32I-LABEL: square:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a1, %hi(__mulsi3)
 ; RV32I-NEXT:    addi a2, a1, %lo(__mulsi3)
 ; RV32I-NEXT:    addi a1, a0, 0
 ; RV32I-NEXT:    jalr ra, a2, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = mul i32 %a, %a
   ret i32 %1
@@ -19,11 +24,16 @@ define i32 @square(i32 %a) {
 define i32 @mul(i32 %a, i32 %b) {
 ; RV32I-LABEL: mul:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a2, %hi(__mulsi3)
 ; RV32I-NEXT:    addi a2, a2, %lo(__mulsi3)
 ; RV32I-NEXT:    jalr ra, a2, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = mul i32 %a, %b
   ret i32 %1
@@ -32,12 +42,17 @@ define i32 @mul(i32 %a, i32 %b) {
 define i32 @mul_constant(i32 %a) {
 ; RV32I-LABEL: mul_constant:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a1, %hi(__mulsi3)
 ; RV32I-NEXT:    addi a2, a1, %lo(__mulsi3)
 ; RV32I-NEXT:    addi a1, zero, 5
 ; RV32I-NEXT:    jalr ra, a2, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = mul i32 %a, 5
   ret i32 %1
@@ -46,7 +61,14 @@ define i32 @mul_constant(i32 %a) {
 define i32 @mul_pow2(i32 %a) {
 ; RV32I-LABEL: mul_pow2:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    slli a0, a0, 3
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = mul i32 %a, 8
   ret i32 %1
@@ -55,11 +77,16 @@ define i32 @mul_pow2(i32 %a) {
 define i64 @mul64(i64 %a, i64 %b) {
 ; RV32I-LABEL: mul64:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a4, %hi(__muldi3)
 ; RV32I-NEXT:    addi a4, a4, %lo(__muldi3)
 ; RV32I-NEXT:    jalr ra, a4, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = mul i64 %a, %b
   ret i64 %1
@@ -68,13 +95,18 @@ define i64 @mul64(i64 %a, i64 %b) {
 define i64 @mul64_constant(i64 %a) {
 ; RV32I-LABEL: mul64_constant:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a2, %hi(__muldi3)
 ; RV32I-NEXT:    addi a4, a2, %lo(__muldi3)
 ; RV32I-NEXT:    addi a2, zero, 5
 ; RV32I-NEXT:    addi a3, zero, 0
 ; RV32I-NEXT:    jalr ra, a4, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = mul i64 %a, 5
   ret i64 %1

Modified: llvm/trunk/test/CodeGen/RISCV/rem.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/rem.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/rem.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/rem.ll Mon Dec 11 04:34:11 2017
@@ -5,11 +5,16 @@
 define i32 @urem(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: urem:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a2, %hi(__umodsi3)
 ; RV32I-NEXT:    addi a2, a2, %lo(__umodsi3)
 ; RV32I-NEXT:    jalr ra, a2, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = urem i32 %a, %b
   ret i32 %1
@@ -18,11 +23,16 @@ define i32 @urem(i32 %a, i32 %b) nounwin
 define i32 @srem(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: srem:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a2, %hi(__modsi3)
 ; RV32I-NEXT:    addi a2, a2, %lo(__modsi3)
 ; RV32I-NEXT:    jalr ra, a2, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = srem i32 %a, %b
   ret i32 %1

Modified: llvm/trunk/test/CodeGen/RISCV/rotl-rotr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/rotl-rotr.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/rotl-rotr.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/rotl-rotr.ll Mon Dec 11 04:34:11 2017
@@ -8,11 +8,18 @@
 define i32 @rotl(i32 %x, i32 %y) {
 ; RV32I-LABEL: rotl:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    addi a2, zero, 32
 ; RV32I-NEXT:    sub a2, a2, a1
 ; RV32I-NEXT:    sll a1, a0, a1
 ; RV32I-NEXT:    srl a0, a0, a2
 ; RV32I-NEXT:    or a0, a1, a0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %z = sub i32 32, %y
   %b = shl i32 %x, %y
@@ -24,11 +31,18 @@ define i32 @rotl(i32 %x, i32 %y) {
 define i32 @rotr(i32 %x, i32 %y) {
 ; RV32I-LABEL: rotr:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    addi a2, zero, 32
 ; RV32I-NEXT:    sub a2, a2, a1
 ; RV32I-NEXT:    srl a1, a0, a1
 ; RV32I-NEXT:    sll a0, a0, a2
 ; RV32I-NEXT:    or a0, a1, a0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %z = sub i32 32, %y
   %b = lshr i32 %x, %y

Modified: llvm/trunk/test/CodeGen/RISCV/select-cc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/select-cc.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/select-cc.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/select-cc.ll Mon Dec 11 04:34:11 2017
@@ -5,6 +5,10 @@
 define i32 @foo(i32 %a, i32 *%b) {
 ; RV32I-LABEL: foo:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lw a2, 0(a1)
 ; RV32I-NEXT:    beq a0, a2, .LBB0_2
 ; RV32I-NEXT:  # %bb.1:
@@ -55,6 +59,9 @@ define i32 @foo(i32 %a, i32 *%b) {
 ; RV32I-NEXT:  # %bb.19:
 ; RV32I-NEXT:    addi a0, a1, 0
 ; RV32I-NEXT:  .LBB0_20:
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %val1 = load volatile i32, i32* %b
   %tst1 = icmp eq i32 %a, %val1

Modified: llvm/trunk/test/CodeGen/RISCV/sext-zext-trunc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/sext-zext-trunc.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/sext-zext-trunc.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/sext-zext-trunc.ll Mon Dec 11 04:34:11 2017
@@ -5,8 +5,15 @@
 define i8 @sext_i1_to_i8(i1 %a) {
 ; RV32I-LABEL: sext_i1_to_i8:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    andi a0, a0, 1
 ; RV32I-NEXT:    sub a0, zero, a0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sext i1 %a to i8
   ret i8 %1
@@ -15,8 +22,15 @@ define i8 @sext_i1_to_i8(i1 %a) {
 define i16 @sext_i1_to_i16(i1 %a) {
 ; RV32I-LABEL: sext_i1_to_i16:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    andi a0, a0, 1
 ; RV32I-NEXT:    sub a0, zero, a0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sext i1 %a to i16
   ret i16 %1
@@ -25,8 +39,15 @@ define i16 @sext_i1_to_i16(i1 %a) {
 define i32 @sext_i1_to_i32(i1 %a) {
 ; RV32I-LABEL: sext_i1_to_i32:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    andi a0, a0, 1
 ; RV32I-NEXT:    sub a0, zero, a0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sext i1 %a to i32
   ret i32 %1
@@ -35,9 +56,16 @@ define i32 @sext_i1_to_i32(i1 %a) {
 define i64 @sext_i1_to_i64(i1 %a) {
 ; RV32I-LABEL: sext_i1_to_i64:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    andi a0, a0, 1
 ; RV32I-NEXT:    sub a0, zero, a0
 ; RV32I-NEXT:    addi a1, a0, 0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sext i1 %a to i64
   ret i64 %1
@@ -46,8 +74,15 @@ define i64 @sext_i1_to_i64(i1 %a) {
 define i16 @sext_i8_to_i16(i8 %a) {
 ; RV32I-LABEL: sext_i8_to_i16:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    slli a0, a0, 24
 ; RV32I-NEXT:    srai a0, a0, 24
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sext i8 %a to i16
   ret i16 %1
@@ -56,8 +91,15 @@ define i16 @sext_i8_to_i16(i8 %a) {
 define i32 @sext_i8_to_i32(i8 %a) {
 ; RV32I-LABEL: sext_i8_to_i32:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    slli a0, a0, 24
 ; RV32I-NEXT:    srai a0, a0, 24
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sext i8 %a to i32
   ret i32 %1
@@ -66,9 +108,16 @@ define i32 @sext_i8_to_i32(i8 %a) {
 define i64 @sext_i8_to_i64(i8 %a) {
 ; RV32I-LABEL: sext_i8_to_i64:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    slli a1, a0, 24
 ; RV32I-NEXT:    srai a0, a1, 24
 ; RV32I-NEXT:    srai a1, a1, 31
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sext i8 %a to i64
   ret i64 %1
@@ -77,8 +126,15 @@ define i64 @sext_i8_to_i64(i8 %a) {
 define i32 @sext_i16_to_i32(i16 %a) {
 ; RV32I-LABEL: sext_i16_to_i32:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    slli a0, a0, 16
 ; RV32I-NEXT:    srai a0, a0, 16
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sext i16 %a to i32
   ret i32 %1
@@ -87,9 +143,16 @@ define i32 @sext_i16_to_i32(i16 %a) {
 define i64 @sext_i16_to_i64(i16 %a) {
 ; RV32I-LABEL: sext_i16_to_i64:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    slli a1, a0, 16
 ; RV32I-NEXT:    srai a0, a1, 16
 ; RV32I-NEXT:    srai a1, a1, 31
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sext i16 %a to i64
   ret i64 %1
@@ -98,7 +161,14 @@ define i64 @sext_i16_to_i64(i16 %a) {
 define i64 @sext_i32_to_i64(i32 %a) {
 ; RV32I-LABEL: sext_i32_to_i64:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    srai a1, a0, 31
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sext i32 %a to i64
   ret i64 %1
@@ -107,7 +177,14 @@ define i64 @sext_i32_to_i64(i32 %a) {
 define i8 @zext_i1_to_i8(i1 %a) {
 ; RV32I-LABEL: zext_i1_to_i8:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    andi a0, a0, 1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = zext i1 %a to i8
   ret i8 %1
@@ -116,7 +193,14 @@ define i8 @zext_i1_to_i8(i1 %a) {
 define i16 @zext_i1_to_i16(i1 %a) {
 ; RV32I-LABEL: zext_i1_to_i16:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    andi a0, a0, 1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = zext i1 %a to i16
   ret i16 %1
@@ -125,7 +209,14 @@ define i16 @zext_i1_to_i16(i1 %a) {
 define i32 @zext_i1_to_i32(i1 %a) {
 ; RV32I-LABEL: zext_i1_to_i32:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    andi a0, a0, 1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = zext i1 %a to i32
   ret i32 %1
@@ -134,8 +225,15 @@ define i32 @zext_i1_to_i32(i1 %a) {
 define i64 @zext_i1_to_i64(i1 %a) {
 ; RV32I-LABEL: zext_i1_to_i64:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    andi a0, a0, 1
 ; RV32I-NEXT:    addi a1, zero, 0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = zext i1 %a to i64
   ret i64 %1
@@ -144,7 +242,14 @@ define i64 @zext_i1_to_i64(i1 %a) {
 define i16 @zext_i8_to_i16(i8 %a) {
 ; RV32I-LABEL: zext_i8_to_i16:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    andi a0, a0, 255
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = zext i8 %a to i16
   ret i16 %1
@@ -153,7 +258,14 @@ define i16 @zext_i8_to_i16(i8 %a) {
 define i32 @zext_i8_to_i32(i8 %a) {
 ; RV32I-LABEL: zext_i8_to_i32:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    andi a0, a0, 255
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = zext i8 %a to i32
   ret i32 %1
@@ -162,8 +274,15 @@ define i32 @zext_i8_to_i32(i8 %a) {
 define i64 @zext_i8_to_i64(i8 %a) {
 ; RV32I-LABEL: zext_i8_to_i64:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    andi a0, a0, 255
 ; RV32I-NEXT:    addi a1, zero, 0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = zext i8 %a to i64
   ret i64 %1
@@ -172,9 +291,16 @@ define i64 @zext_i8_to_i64(i8 %a) {
 define i32 @zext_i16_to_i32(i16 %a) {
 ; RV32I-LABEL: zext_i16_to_i32:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a1, 16
 ; RV32I-NEXT:    addi a1, a1, -1
 ; RV32I-NEXT:    and a0, a0, a1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = zext i16 %a to i32
   ret i32 %1
@@ -183,10 +309,17 @@ define i32 @zext_i16_to_i32(i16 %a) {
 define i64 @zext_i16_to_i64(i16 %a) {
 ; RV32I-LABEL: zext_i16_to_i64:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a1, 16
 ; RV32I-NEXT:    addi a1, a1, -1
 ; RV32I-NEXT:    and a0, a0, a1
 ; RV32I-NEXT:    addi a1, zero, 0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = zext i16 %a to i64
   ret i64 %1
@@ -195,7 +328,14 @@ define i64 @zext_i16_to_i64(i16 %a) {
 define i64 @zext_i32_to_i64(i32 %a) {
 ; RV32I-LABEL: zext_i32_to_i64:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    addi a1, zero, 0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = zext i32 %a to i64
   ret i64 %1
@@ -207,6 +347,13 @@ define i64 @zext_i32_to_i64(i32 %a) {
 define i1 @trunc_i8_to_i1(i8 %a) {
 ; RV32I-LABEL: trunc_i8_to_i1:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = trunc i8 %a to i1
   ret i1 %1
@@ -215,6 +362,13 @@ define i1 @trunc_i8_to_i1(i8 %a) {
 define i1 @trunc_i16_to_i1(i16 %a) {
 ; RV32I-LABEL: trunc_i16_to_i1:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = trunc i16 %a to i1
   ret i1 %1
@@ -223,6 +377,13 @@ define i1 @trunc_i16_to_i1(i16 %a) {
 define i1 @trunc_i32_to_i1(i32 %a) {
 ; RV32I-LABEL: trunc_i32_to_i1:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = trunc i32 %a to i1
   ret i1 %1
@@ -231,6 +392,13 @@ define i1 @trunc_i32_to_i1(i32 %a) {
 define i1 @trunc_i64_to_i1(i64 %a) {
 ; RV32I-LABEL: trunc_i64_to_i1:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = trunc i64 %a to i1
   ret i1 %1
@@ -239,6 +407,13 @@ define i1 @trunc_i64_to_i1(i64 %a) {
 define i8 @trunc_i16_to_i8(i16 %a) {
 ; RV32I-LABEL: trunc_i16_to_i8:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = trunc i16 %a to i8
   ret i8 %1
@@ -247,6 +422,13 @@ define i8 @trunc_i16_to_i8(i16 %a) {
 define i8 @trunc_i32_to_i8(i32 %a) {
 ; RV32I-LABEL: trunc_i32_to_i8:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = trunc i32 %a to i8
   ret i8 %1
@@ -255,6 +437,13 @@ define i8 @trunc_i32_to_i8(i32 %a) {
 define i8 @trunc_i64_to_i8(i64 %a) {
 ; RV32I-LABEL: trunc_i64_to_i8:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = trunc i64 %a to i8
   ret i8 %1
@@ -263,6 +452,13 @@ define i8 @trunc_i64_to_i8(i64 %a) {
 define i16 @trunc_i32_to_i16(i32 %a) {
 ; RV32I-LABEL: trunc_i32_to_i16:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = trunc i32 %a to i16
   ret i16 %1
@@ -271,6 +467,13 @@ define i16 @trunc_i32_to_i16(i32 %a) {
 define i16 @trunc_i64_to_i16(i64 %a) {
 ; RV32I-LABEL: trunc_i64_to_i16:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = trunc i64 %a to i16
   ret i16 %1
@@ -279,6 +482,13 @@ define i16 @trunc_i64_to_i16(i64 %a) {
 define i32 @trunc_i64_to_i32(i64 %a) {
 ; RV32I-LABEL: trunc_i64_to_i32:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = trunc i64 %a to i32
   ret i32 %1

Modified: llvm/trunk/test/CodeGen/RISCV/shifts.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/shifts.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/shifts.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/shifts.ll Mon Dec 11 04:34:11 2017
@@ -8,11 +8,16 @@
 define i64 @lshr64(i64 %a, i64 %b) nounwind {
 ; RV32I-LABEL: lshr64:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a3, %hi(__lshrdi3)
 ; RV32I-NEXT:    addi a3, a3, %lo(__lshrdi3)
 ; RV32I-NEXT:    jalr ra, a3, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = lshr i64 %a, %b
   ret i64 %1
@@ -21,11 +26,16 @@ define i64 @lshr64(i64 %a, i64 %b) nounw
 define i64 @ashr64(i64 %a, i64 %b) nounwind {
 ; RV32I-LABEL: ashr64:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a3, %hi(__ashrdi3)
 ; RV32I-NEXT:    addi a3, a3, %lo(__ashrdi3)
 ; RV32I-NEXT:    jalr ra, a3, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = ashr i64 %a, %b
   ret i64 %1
@@ -34,11 +44,16 @@ define i64 @ashr64(i64 %a, i64 %b) nounw
 define i64 @shl64(i64 %a, i64 %b) nounwind {
 ; RV32I-LABEL: shl64:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a3, %hi(__ashldi3)
 ; RV32I-NEXT:    addi a3, a3, %lo(__ashldi3)
 ; RV32I-NEXT:    jalr ra, a3, 0
+; RV32I-NEXT:    lw s0, 8(sp)
 ; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = shl i64 %a, %b
   ret i64 %1

Modified: llvm/trunk/test/CodeGen/RISCV/wide-mem.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/wide-mem.ll?rev=320357&r1=320356&r2=320357&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/wide-mem.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/wide-mem.ll Mon Dec 11 04:34:11 2017
@@ -7,9 +7,16 @@
 define i64 @load_i64(i64 *%a) nounwind {
 ; RV32I-LABEL: load_i64:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lw a2, 0(a0)
 ; RV32I-NEXT:    lw a1, 4(a0)
 ; RV32I-NEXT:    addi a0, a2, 0
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = load i64, i64* %a
   ret i64 %1
@@ -22,12 +29,19 @@ define i64 @load_i64(i64 *%a) nounwind {
 define i64 @load_i64_global() nounwind {
 ; RV32I-LABEL: load_i64_global:
 ; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
 ; RV32I-NEXT:    lui a0, %hi(val64)
 ; RV32I-NEXT:    addi a0, a0, %lo(val64)
 ; RV32I-NEXT:    lw a0, 0(a0)
 ; RV32I-NEXT:    lui a1, %hi(val64+4)
 ; RV32I-NEXT:    addi a1, a1, %lo(val64+4)
 ; RV32I-NEXT:    lw a1, 0(a1)
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = load i64, i64* @val64
   ret i64 %1




More information about the llvm-commits mailing list