[RISCV] Support lowering FrameIndex

Introduces the AddrFI "addressing mode", which is necessary simply because 
it's not possible to write a pattern that directly matches a frameindex.

Ensure callee-saved registers are accessed relative to the stackpointer. This
is necessary as callee-saved register spills are performed before the frame
pointer is set.

Move HexagonDAGToDAGISel::isOrEquivalentToAdd to SelectionDAGISel, so we can 
make use of it in the RISC-V backend.

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

llvm-svn: 320353
diff --git a/llvm/test/CodeGen/RISCV/blockaddress.ll b/llvm/test/CodeGen/RISCV/blockaddress.ll
index 9eb4e3d..41fe9b5 100644
--- a/llvm/test/CodeGen/RISCV/blockaddress.ll
+++ b/llvm/test/CodeGen/RISCV/blockaddress.ll
@@ -7,7 +7,7 @@
 define void @test_blockaddress() nounwind {
 ; RV32I-LABEL: test_blockaddress:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 0(s0)
+; RV32I-NEXT:    sw ra, 0(sp)
 ; RV32I-NEXT:    lui a0, %hi(addr)
 ; RV32I-NEXT:    addi a0, a0, %lo(addr)
 ; RV32I-NEXT:    lui a1, %hi(.Ltmp0)
@@ -17,7 +17,7 @@
 ; RV32I-NEXT:    jalr zero, a0, 0
 ; RV32I-NEXT:  .Ltmp0: # Block address taken
 ; RV32I-NEXT:  .LBB0_1: # %block
-; RV32I-NEXT:    lw ra, 0(s0)
+; RV32I-NEXT:    lw ra, 0(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   store volatile i8* blockaddress(@test_blockaddress, %block), i8** @addr
   %val = load volatile i8*, i8** @addr
diff --git a/llvm/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll b/llvm/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll
index 150dfed..143800d 100644
--- a/llvm/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll
+++ b/llvm/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll
@@ -82,7 +82,7 @@
 define i8 @test_cttz_i8(i8 %a) nounwind {
 ; RV32I-LABEL: test_cttz_i8:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    addi a1, a0, 0
 ; RV32I-NEXT:    addi a0, zero, 8
 ; RV32I-NEXT:    andi a2, a1, 255
@@ -115,7 +115,7 @@
 ; RV32I-NEXT:    jalr ra, a2, 0
 ; RV32I-NEXT:    srli a0, a0, 24
 ; RV32I-NEXT:  .LBB3_2: # %cond.end
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %tmp = call i8 @llvm.cttz.i8(i8 %a, i1 false)
   ret i8 %tmp
@@ -124,7 +124,7 @@
 define i16 @test_cttz_i16(i16 %a) nounwind {
 ; RV32I-LABEL: test_cttz_i16:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    addi a1, a0, 0
 ; RV32I-NEXT:    addi a0, zero, 16
 ; RV32I-NEXT:    lui a2, 16
@@ -159,7 +159,7 @@
 ; RV32I-NEXT:    jalr ra, a2, 0
 ; RV32I-NEXT:    srli a0, a0, 24
 ; RV32I-NEXT:  .LBB4_2: # %cond.end
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %tmp = call i16 @llvm.cttz.i16(i16 %a, i1 false)
   ret i16 %tmp
@@ -168,7 +168,7 @@
 define i32 @test_cttz_i32(i32 %a) nounwind {
 ; RV32I-LABEL: test_cttz_i32:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    addi a1, a0, 0
 ; RV32I-NEXT:    addi a0, zero, 32
 ; RV32I-NEXT:    beq a1, zero, .LBB5_2
@@ -200,7 +200,7 @@
 ; RV32I-NEXT:    jalr ra, a2, 0
 ; RV32I-NEXT:    srli a0, a0, 24
 ; RV32I-NEXT:  .LBB5_2: # %cond.end
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %tmp = call i32 @llvm.cttz.i32(i32 %a, i1 false)
   ret i32 %tmp
@@ -209,7 +209,7 @@
 define i32 @test_ctlz_i32(i32 %a) nounwind {
 ; RV32I-LABEL: test_ctlz_i32:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    addi a1, a0, 0
 ; RV32I-NEXT:    addi a0, zero, 32
 ; RV32I-NEXT:    beq a1, zero, .LBB6_2
@@ -249,7 +249,7 @@
 ; RV32I-NEXT:    jalr ra, a2, 0
 ; RV32I-NEXT:    srli a0, a0, 24
 ; RV32I-NEXT:  .LBB6_2: # %cond.end
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %tmp = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
   ret i32 %tmp
@@ -258,14 +258,14 @@
 define i64 @test_cttz_i64(i64 %a) nounwind {
 ; RV32I-LABEL: test_cttz_i64:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 28(s0)
-; RV32I-NEXT:    sw s1, 24(s0)
-; RV32I-NEXT:    sw s2, 20(s0)
-; RV32I-NEXT:    sw s3, 16(s0)
-; RV32I-NEXT:    sw s4, 12(s0)
-; RV32I-NEXT:    sw s5, 8(s0)
-; RV32I-NEXT:    sw s6, 4(s0)
-; RV32I-NEXT:    sw s7, 0(s0)
+; 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 s1, a1, 0
 ; RV32I-NEXT:    addi s2, a0, 0
 ; RV32I-NEXT:    addi a0, s2, -1
@@ -317,14 +317,14 @@
 ; RV32I-NEXT:  .LBB7_2:
 ; RV32I-NEXT:    addi a0, s1, 0
 ; RV32I-NEXT:    addi a1, zero, 0
-; RV32I-NEXT:    lw s7, 0(s0)
-; RV32I-NEXT:    lw s6, 4(s0)
-; RV32I-NEXT:    lw s5, 8(s0)
-; RV32I-NEXT:    lw s4, 12(s0)
-; RV32I-NEXT:    lw s3, 16(s0)
-; RV32I-NEXT:    lw s2, 20(s0)
-; RV32I-NEXT:    lw s1, 24(s0)
-; RV32I-NEXT:    lw ra, 28(s0)
+; 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:    jalr zero, ra, 0
   %tmp = call i64 @llvm.cttz.i64(i64 %a, i1 false)
   ret i64 %tmp
@@ -333,7 +333,7 @@
 define i8 @test_cttz_i8_zero_undef(i8 %a) nounwind {
 ; RV32I-LABEL: test_cttz_i8_zero_undef:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    addi a1, a0, -1
 ; RV32I-NEXT:    xori a0, a0, -1
 ; RV32I-NEXT:    and a0, a0, a1
@@ -359,7 +359,7 @@
 ; RV32I-NEXT:    addi a2, a2, %lo(__mulsi3)
 ; RV32I-NEXT:    jalr ra, a2, 0
 ; RV32I-NEXT:    srli a0, a0, 24
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %tmp = call i8 @llvm.cttz.i8(i8 %a, i1 true)
   ret i8 %tmp
@@ -368,7 +368,7 @@
 define i16 @test_cttz_i16_zero_undef(i16 %a) nounwind {
 ; RV32I-LABEL: test_cttz_i16_zero_undef:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    addi a1, a0, -1
 ; RV32I-NEXT:    xori a0, a0, -1
 ; RV32I-NEXT:    and a0, a0, a1
@@ -394,7 +394,7 @@
 ; RV32I-NEXT:    addi a2, a2, %lo(__mulsi3)
 ; RV32I-NEXT:    jalr ra, a2, 0
 ; RV32I-NEXT:    srli a0, a0, 24
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %tmp = call i16 @llvm.cttz.i16(i16 %a, i1 true)
   ret i16 %tmp
@@ -403,7 +403,7 @@
 define i32 @test_cttz_i32_zero_undef(i32 %a) nounwind {
 ; RV32I-LABEL: test_cttz_i32_zero_undef:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    addi a1, a0, -1
 ; RV32I-NEXT:    xori a0, a0, -1
 ; RV32I-NEXT:    and a0, a0, a1
@@ -429,7 +429,7 @@
 ; RV32I-NEXT:    addi a2, a2, %lo(__mulsi3)
 ; RV32I-NEXT:    jalr ra, a2, 0
 ; RV32I-NEXT:    srli a0, a0, 24
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %tmp = call i32 @llvm.cttz.i32(i32 %a, i1 true)
   ret i32 %tmp
@@ -438,14 +438,14 @@
 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(s0)
-; RV32I-NEXT:    sw s1, 24(s0)
-; RV32I-NEXT:    sw s2, 20(s0)
-; RV32I-NEXT:    sw s3, 16(s0)
-; RV32I-NEXT:    sw s4, 12(s0)
-; RV32I-NEXT:    sw s5, 8(s0)
-; RV32I-NEXT:    sw s6, 4(s0)
-; RV32I-NEXT:    sw s7, 0(s0)
+; 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 s1, a1, 0
 ; RV32I-NEXT:    addi s2, a0, 0
 ; RV32I-NEXT:    addi a0, s2, -1
@@ -497,14 +497,14 @@
 ; RV32I-NEXT:  .LBB11_2:
 ; RV32I-NEXT:    addi a0, s1, 0
 ; RV32I-NEXT:    addi a1, zero, 0
-; RV32I-NEXT:    lw s7, 0(s0)
-; RV32I-NEXT:    lw s6, 4(s0)
-; RV32I-NEXT:    lw s5, 8(s0)
-; RV32I-NEXT:    lw s4, 12(s0)
-; RV32I-NEXT:    lw s3, 16(s0)
-; RV32I-NEXT:    lw s2, 20(s0)
-; RV32I-NEXT:    lw s1, 24(s0)
-; RV32I-NEXT:    lw ra, 28(s0)
+; 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:    jalr zero, ra, 0
   %tmp = call i64 @llvm.cttz.i64(i64 %a, i1 true)
   ret i64 %tmp
@@ -513,7 +513,7 @@
 define i32 @test_ctpop_i32(i32 %a) nounwind {
 ; RV32I-LABEL: test_ctpop_i32:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    lui a1, 349525
 ; RV32I-NEXT:    addi a1, a1, 1365
 ; RV32I-NEXT:    srli a2, a0, 1
@@ -536,7 +536,7 @@
 ; RV32I-NEXT:    addi a2, a2, %lo(__mulsi3)
 ; RV32I-NEXT:    jalr ra, a2, 0
 ; RV32I-NEXT:    srli a0, a0, 24
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = call i32 @llvm.ctpop.i32(i32 %a)
   ret i32 %1
diff --git a/llvm/test/CodeGen/RISCV/calls.ll b/llvm/test/CodeGen/RISCV/calls.ll
index 77f6129..cc43e25 100644
--- a/llvm/test/CodeGen/RISCV/calls.ll
+++ b/llvm/test/CodeGen/RISCV/calls.ll
@@ -7,11 +7,11 @@
 define i32 @test_call_external(i32 %a) nounwind {
 ; RV32I-LABEL: test_call_external:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    lui a1, %hi(external_function)
 ; RV32I-NEXT:    addi a1, a1, %lo(external_function)
 ; RV32I-NEXT:    jalr ra, a1, 0
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = call i32 @external_function(i32 %a)
   ret i32 %1
@@ -29,11 +29,11 @@
 define i32 @test_call_defined(i32 %a) nounwind {
 ; RV32I-LABEL: test_call_defined:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    lui a1, %hi(defined_function)
 ; RV32I-NEXT:    addi a1, a1, %lo(defined_function)
 ; RV32I-NEXT:    jalr ra, a1, 0
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = call i32 @defined_function(i32 %a) nounwind
   ret i32 %1
@@ -42,11 +42,11 @@
 define i32 @test_call_indirect(i32 (i32)* %a, i32 %b) nounwind {
 ; RV32I-LABEL: test_call_indirect:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    addi a2, a0, 0
 ; RV32I-NEXT:    addi a0, a1, 0
 ; RV32I-NEXT:    jalr ra, a2, 0
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = call i32 %a(i32 %b)
   ret i32 %1
@@ -67,16 +67,16 @@
 define i32 @test_call_fastcc(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: test_call_fastcc:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
-; RV32I-NEXT:    sw s1, 8(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s1, 8(sp)
 ; 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(s0)
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw s1, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = call fastcc i32 @fastcc_function(i32 %a, i32 %b)
   ret i32 %a
diff --git a/llvm/test/CodeGen/RISCV/div.ll b/llvm/test/CodeGen/RISCV/div.ll
index a53c51c..651d49e 100644
--- a/llvm/test/CodeGen/RISCV/div.ll
+++ b/llvm/test/CodeGen/RISCV/div.ll
@@ -5,11 +5,11 @@
 define i32 @udiv(i32 %a, i32 %b) {
 ; RV32I-LABEL: udiv:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    lui a2, %hi(__udivsi3)
 ; RV32I-NEXT:    addi a2, a2, %lo(__udivsi3)
 ; RV32I-NEXT:    jalr ra, a2, 0
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = udiv i32 %a, %b
   ret i32 %1
@@ -18,12 +18,12 @@
 define i32 @udiv_constant(i32 %a) {
 ; RV32I-LABEL: udiv_constant:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; 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 ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = udiv i32 %a, 5
   ret i32 %1
@@ -41,11 +41,11 @@
 define i64 @udiv64(i64 %a, i64 %b) {
 ; RV32I-LABEL: udiv64:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    lui a4, %hi(__udivdi3)
 ; RV32I-NEXT:    addi a4, a4, %lo(__udivdi3)
 ; RV32I-NEXT:    jalr ra, a4, 0
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = udiv i64 %a, %b
   ret i64 %1
@@ -54,13 +54,13 @@
 define i64 @udiv64_constant(i64 %a) {
 ; RV32I-LABEL: udiv64_constant:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; 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 ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = udiv i64 %a, 5
   ret i64 %1
@@ -69,11 +69,11 @@
 define i32 @sdiv(i32 %a, i32 %b) {
 ; RV32I-LABEL: sdiv:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    lui a2, %hi(__divsi3)
 ; RV32I-NEXT:    addi a2, a2, %lo(__divsi3)
 ; RV32I-NEXT:    jalr ra, a2, 0
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sdiv i32 %a, %b
   ret i32 %1
@@ -82,12 +82,12 @@
 define i32 @sdiv_constant(i32 %a) {
 ; RV32I-LABEL: sdiv_constant:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; 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 ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sdiv i32 %a, 5
   ret i32 %1
@@ -108,11 +108,11 @@
 define i64 @sdiv64(i64 %a, i64 %b) {
 ; RV32I-LABEL: sdiv64:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    lui a4, %hi(__divdi3)
 ; RV32I-NEXT:    addi a4, a4, %lo(__divdi3)
 ; RV32I-NEXT:    jalr ra, a4, 0
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sdiv i64 %a, %b
   ret i64 %1
@@ -121,13 +121,13 @@
 define i64 @sdiv64_constant(i64 %a) {
 ; RV32I-LABEL: sdiv64_constant:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; 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 ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = sdiv i64 %a, 5
   ret i64 %1
diff --git a/llvm/test/CodeGen/RISCV/frame.ll b/llvm/test/CodeGen/RISCV/frame.ll
new file mode 100644
index 0000000..4a2486e
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/frame.ll
@@ -0,0 +1,36 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
+; RUN:   | FileCheck -check-prefix=RV32I %s
+
+%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:    sw ra, 28(sp)
+; RV32I-NEXT:    sw zero, -8(s0)
+; RV32I-NEXT:    sw zero, -12(s0)
+; RV32I-NEXT:    sw zero, -16(s0)
+; RV32I-NEXT:    sw zero, -20(s0)
+; RV32I-NEXT:    sw zero, -24(s0)
+; RV32I-NEXT:    lui a0, %hi(test1)
+; RV32I-NEXT:    addi a1, a0, %lo(test1)
+; RV32I-NEXT:    addi a0, s0, -20
+; RV32I-NEXT:    jalr ra, a1, 0
+; RV32I-NEXT:    addi a0, zero, 0
+; RV32I-NEXT:    lw ra, 28(sp)
+; RV32I-NEXT:    jalr zero, ra, 0
+  %key = alloca %struct.key_t, align 4
+  %1 = bitcast %struct.key_t* %key to i8*
+  call void @llvm.memset.p0i8.i64(i8* %1, i8 0, i64 20, i32 4, i1 false)
+  %2 = getelementptr inbounds %struct.key_t, %struct.key_t* %key, i64 0, i32 1, i64 0
+  call void @test1(i8* %2) #3
+  ret i32 0
+}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1)
+
+declare void @test1(i8*)
diff --git a/llvm/test/CodeGen/RISCV/indirectbr.ll b/llvm/test/CodeGen/RISCV/indirectbr.ll
index 40641da..45232c8 100644
--- a/llvm/test/CodeGen/RISCV/indirectbr.ll
+++ b/llvm/test/CodeGen/RISCV/indirectbr.ll
@@ -5,11 +5,11 @@
 define i32 @indirectbr(i8* %target) nounwind {
 ; RV32I-LABEL: indirectbr:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 0(s0)
+; RV32I-NEXT:    sw ra, 0(sp)
 ; RV32I-NEXT:    jalr zero, a0, 0
 ; RV32I-NEXT:  .LBB0_1: # %ret
 ; RV32I-NEXT:    addi a0, zero, 0
-; RV32I-NEXT:    lw ra, 0(s0)
+; RV32I-NEXT:    lw ra, 0(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   indirectbr i8* %target, [label %test_label]
 test_label:
@@ -21,11 +21,11 @@
 define i32 @indirectbr_with_offset(i8* %a) nounwind {
 ; RV32I-LABEL: indirectbr_with_offset:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 0(s0)
+; RV32I-NEXT:    sw ra, 0(sp)
 ; RV32I-NEXT:    jalr zero, a0, 1380
 ; RV32I-NEXT:  .LBB1_1: # %ret
 ; RV32I-NEXT:    addi a0, zero, 0
-; RV32I-NEXT:    lw ra, 0(s0)
+; RV32I-NEXT:    lw ra, 0(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %target = getelementptr inbounds i8, i8* %a, i32 1380
   indirectbr i8* %target, [label %test_label]
diff --git a/llvm/test/CodeGen/RISCV/mul.ll b/llvm/test/CodeGen/RISCV/mul.ll
index 2eb5db7..b8c46d2 100644
--- a/llvm/test/CodeGen/RISCV/mul.ll
+++ b/llvm/test/CodeGen/RISCV/mul.ll
@@ -5,12 +5,12 @@
 define i32 @square(i32 %a) {
 ; RV32I-LABEL: square:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; 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 ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = mul i32 %a, %a
   ret i32 %1
@@ -19,11 +19,11 @@
 define i32 @mul(i32 %a, i32 %b) {
 ; RV32I-LABEL: mul:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    lui a2, %hi(__mulsi3)
 ; RV32I-NEXT:    addi a2, a2, %lo(__mulsi3)
 ; RV32I-NEXT:    jalr ra, a2, 0
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = mul i32 %a, %b
   ret i32 %1
@@ -32,12 +32,12 @@
 define i32 @mul_constant(i32 %a) {
 ; RV32I-LABEL: mul_constant:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; 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 ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = mul i32 %a, 5
   ret i32 %1
@@ -55,11 +55,11 @@
 define i64 @mul64(i64 %a, i64 %b) {
 ; RV32I-LABEL: mul64:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    lui a4, %hi(__muldi3)
 ; RV32I-NEXT:    addi a4, a4, %lo(__muldi3)
 ; RV32I-NEXT:    jalr ra, a4, 0
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = mul i64 %a, %b
   ret i64 %1
@@ -68,13 +68,13 @@
 define i64 @mul64_constant(i64 %a) {
 ; RV32I-LABEL: mul64_constant:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; 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 ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = mul i64 %a, 5
   ret i64 %1
diff --git a/llvm/test/CodeGen/RISCV/rem.ll b/llvm/test/CodeGen/RISCV/rem.ll
index c9e2a90..b30968a 100644
--- a/llvm/test/CodeGen/RISCV/rem.ll
+++ b/llvm/test/CodeGen/RISCV/rem.ll
@@ -5,11 +5,11 @@
 define i32 @urem(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: urem:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    lui a2, %hi(__umodsi3)
 ; RV32I-NEXT:    addi a2, a2, %lo(__umodsi3)
 ; RV32I-NEXT:    jalr ra, a2, 0
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = urem i32 %a, %b
   ret i32 %1
@@ -18,11 +18,11 @@
 define i32 @srem(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: srem:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    lui a2, %hi(__modsi3)
 ; RV32I-NEXT:    addi a2, a2, %lo(__modsi3)
 ; RV32I-NEXT:    jalr ra, a2, 0
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = srem i32 %a, %b
   ret i32 %1
diff --git a/llvm/test/CodeGen/RISCV/shifts.ll b/llvm/test/CodeGen/RISCV/shifts.ll
index c4033c5..b76b724 100644
--- a/llvm/test/CodeGen/RISCV/shifts.ll
+++ b/llvm/test/CodeGen/RISCV/shifts.ll
@@ -8,11 +8,11 @@
 define i64 @lshr64(i64 %a, i64 %b) nounwind {
 ; RV32I-LABEL: lshr64:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    lui a3, %hi(__lshrdi3)
 ; RV32I-NEXT:    addi a3, a3, %lo(__lshrdi3)
 ; RV32I-NEXT:    jalr ra, a3, 0
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = lshr i64 %a, %b
   ret i64 %1
@@ -21,11 +21,11 @@
 define i64 @ashr64(i64 %a, i64 %b) nounwind {
 ; RV32I-LABEL: ashr64:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    lui a3, %hi(__ashrdi3)
 ; RV32I-NEXT:    addi a3, a3, %lo(__ashrdi3)
 ; RV32I-NEXT:    jalr ra, a3, 0
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = ashr i64 %a, %b
   ret i64 %1
@@ -34,11 +34,11 @@
 define i64 @shl64(i64 %a, i64 %b) nounwind {
 ; RV32I-LABEL: shl64:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    sw ra, 12(s0)
+; RV32I-NEXT:    sw ra, 12(sp)
 ; RV32I-NEXT:    lui a3, %hi(__ashldi3)
 ; RV32I-NEXT:    addi a3, a3, %lo(__ashldi3)
 ; RV32I-NEXT:    jalr ra, a3, 0
-; RV32I-NEXT:    lw ra, 12(s0)
+; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    jalr zero, ra, 0
   %1 = shl i64 %a, %b
   ret i64 %1