aboutsummaryrefslogtreecommitdiff
path: root/llvm/test/CodeGen/RISCV
diff options
context:
space:
mode:
authorbvlgah <octopus.busts_0w@icloud.com>2024-03-28 18:09:18 +0800
committerGitHub <noreply@github.com>2024-03-28 13:09:18 +0300
commite640d9e725ef06b9787ab0ab884598f4f5532e48 (patch)
treeaf831d72b50801cf0a59721a1cb250c6c08603ef /llvm/test/CodeGen/RISCV
parent856e815ca1c416de263438e90e8120947e33a03c (diff)
downloadllvm-e640d9e725ef06b9787ab0ab884598f4f5532e48.zip
llvm-e640d9e725ef06b9787ab0ab884598f4f5532e48.tar.gz
llvm-e640d9e725ef06b9787ab0ab884598f4f5532e48.tar.bz2
[RISCV][GlobalISel] Fix legalizing ‘llvm.va_copy’ intrinsic (#86863)
Hi, I spotted a problem when running benchmarking programs on a RISCV64 device. ## Issue Segmentation faults only occurred while running the programs compiled with `GlobalISel` enabled. Here is a small but complete example (it is adopted from [Google's benchmark framework](https://github.com/llvm/llvm-test-suite/blob/95a9f0d0b45056274f0bb4b0e0dd019023e414dc/MicroBenchmarks/libs/benchmark/src/colorprint.cc#L85-L119) to reproduce the issue, ```cpp #include <cstdarg> #include <cstdio> #include <iostream> #include <memory> #include <string> std::string FormatString(const char* msg, va_list args) { // we might need a second shot at this, so pre-emptivly make a copy va_list args_cp; va_copy(args_cp, args); std::size_t size = 256; char local_buff[256]; auto ret = vsnprintf(local_buff, size, msg, args_cp); va_end(args_cp); // currently there is no error handling for failure, so this is hack. // BM_CHECK(ret >= 0); if (ret == 0) // handle empty expansion return {}; else if (static_cast<size_t>(ret) < size) return local_buff; else { // we did not provide a long enough buffer on our first attempt. size = static_cast<size_t>(ret) + 1; // + 1 for the null byte std::unique_ptr<char[]> buff(new char[size]); ret = vsnprintf(buff.get(), size, msg, args); // BM_CHECK(ret > 0 && (static_cast<size_t>(ret)) < size); return buff.get(); } } std::string FormatString(const char* msg, ...) { va_list args; va_start(args, msg); auto tmp = FormatString(msg, args); va_end(args); return tmp; } int main() { std::string Str = FormatString("%-*s %13s %15s %12s", static_cast<int>(20), "Benchmark", "Time", "CPU", "Iterations"); std::cout << Str << std::endl; } ``` Use `clang++ -fglobal-isel -o main main.cpp` to compile it. ## Cause I have examined MIR, it shows that these segmentation faults resulted from a small mistake about legalizing the intrinsic function `llvm.va_copy`. https://github.com/llvm/llvm-project/blob/36e74cfdbde208e384c72bcb52ea638303fb7d67/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp#L451-L453 `DstLst` and `Tmp` are placed in the wrong order. ## Changes I have tweaked the test case `CodeGen/RISCV/GlobalISel/vararg.ll` so that `s0` is used as the frame pointer (not in all checks) which points to the starting address of the save area. I believe that it helps reason about how `llvm.va_copy` is handled.
Diffstat (limited to 'llvm/test/CodeGen/RISCV')
-rw-r--r--llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vacopy.mir2
-rw-r--r--llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll936
2 files changed, 932 insertions, 6 deletions
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vacopy.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vacopy.mir
index f9eda12..16542f58 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vacopy.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vacopy.mir
@@ -14,7 +14,7 @@ body: |
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[COPY1]](p0) :: (load (p0))
- ; CHECK-NEXT: G_STORE [[COPY]](p0), [[LOAD]](p0) :: (store (p0))
+ ; CHECK-NEXT: G_STORE [[LOAD]](p0), [[COPY]](p0) :: (store (p0))
; CHECK-NEXT: PseudoRET
%0:_(p0) = COPY $x10
%1:_(p0) = COPY $x11
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll b/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll
index 7b110e5..d55adf3 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll
@@ -17,6 +17,12 @@
; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -global-isel -mattr=+d -target-abi lp64d \
; RUN: -verify-machineinstrs \
; RUN: | FileCheck -check-prefixes=RV64,LP64D %s
+; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv32 -global-isel \
+; RUN: -frame-pointer=all -target-abi ilp32 -verify-machineinstrs \
+; RUN: | FileCheck -check-prefixes=RV32-WITHFP %s
+; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -global-isel \
+; RUN: -frame-pointer=all -target-abi lp64 -verify-machineinstrs \
+; RUN: | FileCheck -check-prefixes=RV64-WITHFP %s
; The same vararg calling convention is used for ilp32/ilp32f/ilp32d and for
; lp64/lp64f/lp64d. Different CHECK lines are required due to slight
@@ -79,6 +85,67 @@ define i32 @va1(ptr %fmt, ...) {
; RV64-NEXT: lw a0, 0(a0)
; RV64-NEXT: addi sp, sp, 80
; RV64-NEXT: ret
+;
+; RV32-WITHFP-LABEL: va1:
+; RV32-WITHFP: # %bb.0:
+; RV32-WITHFP-NEXT: addi sp, sp, -48
+; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 48
+; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: .cfi_offset ra, -36
+; RV32-WITHFP-NEXT: .cfi_offset s0, -40
+; RV32-WITHFP-NEXT: addi s0, sp, 16
+; RV32-WITHFP-NEXT: .cfi_def_cfa s0, 32
+; RV32-WITHFP-NEXT: sw a1, 4(s0)
+; RV32-WITHFP-NEXT: sw a2, 8(s0)
+; RV32-WITHFP-NEXT: sw a3, 12(s0)
+; RV32-WITHFP-NEXT: sw a4, 16(s0)
+; RV32-WITHFP-NEXT: addi a0, s0, 4
+; RV32-WITHFP-NEXT: sw a0, -12(s0)
+; RV32-WITHFP-NEXT: lw a0, -12(s0)
+; RV32-WITHFP-NEXT: sw a5, 20(s0)
+; RV32-WITHFP-NEXT: sw a6, 24(s0)
+; RV32-WITHFP-NEXT: sw a7, 28(s0)
+; RV32-WITHFP-NEXT: addi a1, a0, 4
+; RV32-WITHFP-NEXT: sw a1, -12(s0)
+; RV32-WITHFP-NEXT: lw a0, 0(a0)
+; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: addi sp, sp, 48
+; RV32-WITHFP-NEXT: ret
+;
+; RV64-WITHFP-LABEL: va1:
+; RV64-WITHFP: # %bb.0:
+; RV64-WITHFP-NEXT: addi sp, sp, -96
+; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 96
+; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: .cfi_offset ra, -72
+; RV64-WITHFP-NEXT: .cfi_offset s0, -80
+; RV64-WITHFP-NEXT: addi s0, sp, 32
+; RV64-WITHFP-NEXT: .cfi_def_cfa s0, 64
+; RV64-WITHFP-NEXT: sd a1, 8(s0)
+; RV64-WITHFP-NEXT: sd a2, 16(s0)
+; RV64-WITHFP-NEXT: sd a3, 24(s0)
+; RV64-WITHFP-NEXT: sd a4, 32(s0)
+; RV64-WITHFP-NEXT: sd a5, 40(s0)
+; RV64-WITHFP-NEXT: addi a0, s0, 8
+; RV64-WITHFP-NEXT: sd a0, -24(s0)
+; RV64-WITHFP-NEXT: lw a0, -20(s0)
+; RV64-WITHFP-NEXT: lwu a1, -24(s0)
+; RV64-WITHFP-NEXT: sd a6, 48(s0)
+; RV64-WITHFP-NEXT: sd a7, 56(s0)
+; RV64-WITHFP-NEXT: slli a0, a0, 32
+; RV64-WITHFP-NEXT: or a0, a0, a1
+; RV64-WITHFP-NEXT: addi a1, a0, 4
+; RV64-WITHFP-NEXT: srli a2, a1, 32
+; RV64-WITHFP-NEXT: sw a1, -24(s0)
+; RV64-WITHFP-NEXT: sw a2, -20(s0)
+; RV64-WITHFP-NEXT: lw a0, 0(a0)
+; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: addi sp, sp, 96
+; RV64-WITHFP-NEXT: ret
%va = alloca ptr
call void @llvm.va_start(ptr %va)
%argp.cur = load ptr, ptr %va, align 4
@@ -131,6 +198,58 @@ define i32 @va1_va_arg(ptr %fmt, ...) nounwind {
; RV64-NEXT: lw a0, 0(a0)
; RV64-NEXT: addi sp, sp, 80
; RV64-NEXT: ret
+;
+; RV32-WITHFP-LABEL: va1_va_arg:
+; RV32-WITHFP: # %bb.0:
+; RV32-WITHFP-NEXT: addi sp, sp, -48
+; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: addi s0, sp, 16
+; RV32-WITHFP-NEXT: sw a1, 4(s0)
+; RV32-WITHFP-NEXT: sw a2, 8(s0)
+; RV32-WITHFP-NEXT: sw a3, 12(s0)
+; RV32-WITHFP-NEXT: sw a4, 16(s0)
+; RV32-WITHFP-NEXT: sw a5, 20(s0)
+; RV32-WITHFP-NEXT: sw a6, 24(s0)
+; RV32-WITHFP-NEXT: sw a7, 28(s0)
+; RV32-WITHFP-NEXT: addi a0, s0, 4
+; RV32-WITHFP-NEXT: sw a0, -12(s0)
+; RV32-WITHFP-NEXT: lw a0, -12(s0)
+; RV32-WITHFP-NEXT: addi a0, a0, 3
+; RV32-WITHFP-NEXT: andi a0, a0, -4
+; RV32-WITHFP-NEXT: addi a1, a0, 4
+; RV32-WITHFP-NEXT: sw a1, -12(s0)
+; RV32-WITHFP-NEXT: lw a0, 0(a0)
+; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: addi sp, sp, 48
+; RV32-WITHFP-NEXT: ret
+;
+; RV64-WITHFP-LABEL: va1_va_arg:
+; RV64-WITHFP: # %bb.0:
+; RV64-WITHFP-NEXT: addi sp, sp, -96
+; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: addi s0, sp, 32
+; RV64-WITHFP-NEXT: sd a1, 8(s0)
+; RV64-WITHFP-NEXT: sd a2, 16(s0)
+; RV64-WITHFP-NEXT: sd a3, 24(s0)
+; RV64-WITHFP-NEXT: sd a4, 32(s0)
+; RV64-WITHFP-NEXT: sd a5, 40(s0)
+; RV64-WITHFP-NEXT: sd a6, 48(s0)
+; RV64-WITHFP-NEXT: sd a7, 56(s0)
+; RV64-WITHFP-NEXT: addi a0, s0, 8
+; RV64-WITHFP-NEXT: sd a0, -24(s0)
+; RV64-WITHFP-NEXT: ld a0, -24(s0)
+; RV64-WITHFP-NEXT: addi a0, a0, 3
+; RV64-WITHFP-NEXT: andi a0, a0, -4
+; RV64-WITHFP-NEXT: addi a1, a0, 4
+; RV64-WITHFP-NEXT: sd a1, -24(s0)
+; RV64-WITHFP-NEXT: lw a0, 0(a0)
+; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: addi sp, sp, 96
+; RV64-WITHFP-NEXT: ret
%va = alloca ptr
call void @llvm.va_start(ptr %va)
%1 = va_arg ptr %va, i32
@@ -212,6 +331,78 @@ define i32 @va1_va_arg_alloca(ptr %fmt, ...) nounwind {
; RV64-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
; RV64-NEXT: addi sp, sp, 96
; RV64-NEXT: ret
+;
+; RV32-WITHFP-LABEL: va1_va_arg_alloca:
+; RV32-WITHFP: # %bb.0:
+; RV32-WITHFP-NEXT: addi sp, sp, -48
+; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: addi s0, sp, 16
+; RV32-WITHFP-NEXT: sw a1, 4(s0)
+; RV32-WITHFP-NEXT: sw a2, 8(s0)
+; RV32-WITHFP-NEXT: sw a3, 12(s0)
+; RV32-WITHFP-NEXT: sw a4, 16(s0)
+; RV32-WITHFP-NEXT: sw a5, 20(s0)
+; RV32-WITHFP-NEXT: sw a6, 24(s0)
+; RV32-WITHFP-NEXT: sw a7, 28(s0)
+; RV32-WITHFP-NEXT: addi a0, s0, 4
+; RV32-WITHFP-NEXT: sw a0, -16(s0)
+; RV32-WITHFP-NEXT: lw a0, -16(s0)
+; RV32-WITHFP-NEXT: addi a0, a0, 3
+; RV32-WITHFP-NEXT: andi a0, a0, -4
+; RV32-WITHFP-NEXT: addi a1, a0, 4
+; RV32-WITHFP-NEXT: sw a1, -16(s0)
+; RV32-WITHFP-NEXT: lw s1, 0(a0)
+; RV32-WITHFP-NEXT: addi a0, s1, 15
+; RV32-WITHFP-NEXT: andi a0, a0, -16
+; RV32-WITHFP-NEXT: sub a0, sp, a0
+; RV32-WITHFP-NEXT: mv sp, a0
+; RV32-WITHFP-NEXT: call notdead
+; RV32-WITHFP-NEXT: mv a0, s1
+; RV32-WITHFP-NEXT: addi sp, s0, -16
+; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: addi sp, sp, 48
+; RV32-WITHFP-NEXT: ret
+;
+; RV64-WITHFP-LABEL: va1_va_arg_alloca:
+; RV64-WITHFP: # %bb.0:
+; RV64-WITHFP-NEXT: addi sp, sp, -96
+; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: addi s0, sp, 32
+; RV64-WITHFP-NEXT: sd a1, 8(s0)
+; RV64-WITHFP-NEXT: sd a2, 16(s0)
+; RV64-WITHFP-NEXT: sd a3, 24(s0)
+; RV64-WITHFP-NEXT: sd a4, 32(s0)
+; RV64-WITHFP-NEXT: sd a5, 40(s0)
+; RV64-WITHFP-NEXT: sd a6, 48(s0)
+; RV64-WITHFP-NEXT: sd a7, 56(s0)
+; RV64-WITHFP-NEXT: addi a0, s0, 8
+; RV64-WITHFP-NEXT: sd a0, -32(s0)
+; RV64-WITHFP-NEXT: ld a0, -32(s0)
+; RV64-WITHFP-NEXT: addi a0, a0, 3
+; RV64-WITHFP-NEXT: andi a0, a0, -4
+; RV64-WITHFP-NEXT: addi a1, a0, 4
+; RV64-WITHFP-NEXT: sd a1, -32(s0)
+; RV64-WITHFP-NEXT: lw s1, 0(a0)
+; RV64-WITHFP-NEXT: slli a0, s1, 32
+; RV64-WITHFP-NEXT: srli a0, a0, 32
+; RV64-WITHFP-NEXT: addi a0, a0, 15
+; RV64-WITHFP-NEXT: andi a0, a0, -16
+; RV64-WITHFP-NEXT: sub a0, sp, a0
+; RV64-WITHFP-NEXT: mv sp, a0
+; RV64-WITHFP-NEXT: call notdead
+; RV64-WITHFP-NEXT: mv a0, s1
+; RV64-WITHFP-NEXT: addi sp, s0, -32
+; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: addi sp, sp, 96
+; RV64-WITHFP-NEXT: ret
%va = alloca ptr
call void @llvm.va_start(ptr %va)
%1 = va_arg ptr %va, i32
@@ -273,6 +464,36 @@ define void @va1_caller() nounwind {
; LP64D-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; LP64D-NEXT: addi sp, sp, 16
; LP64D-NEXT: ret
+;
+; RV32-WITHFP-LABEL: va1_caller:
+; RV32-WITHFP: # %bb.0:
+; RV32-WITHFP-NEXT: addi sp, sp, -16
+; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: addi s0, sp, 16
+; RV32-WITHFP-NEXT: lui a3, 261888
+; RV32-WITHFP-NEXT: li a4, 2
+; RV32-WITHFP-NEXT: li a2, 0
+; RV32-WITHFP-NEXT: call va1
+; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: addi sp, sp, 16
+; RV32-WITHFP-NEXT: ret
+;
+; RV64-WITHFP-LABEL: va1_caller:
+; RV64-WITHFP: # %bb.0:
+; RV64-WITHFP-NEXT: addi sp, sp, -16
+; RV64-WITHFP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: addi s0, sp, 16
+; RV64-WITHFP-NEXT: lui a0, %hi(.LCPI3_0)
+; RV64-WITHFP-NEXT: ld a1, %lo(.LCPI3_0)(a0)
+; RV64-WITHFP-NEXT: li a2, 2
+; RV64-WITHFP-NEXT: call va1
+; RV64-WITHFP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: addi sp, sp, 16
+; RV64-WITHFP-NEXT: ret
%1 = call i32 (ptr, ...) @va1(ptr undef, double 1.0, i32 2)
ret void
}
@@ -395,6 +616,59 @@ define i64 @va2(ptr %fmt, ...) nounwind {
; RV64-NEXT: ld a0, 0(a1)
; RV64-NEXT: addi sp, sp, 80
; RV64-NEXT: ret
+;
+; RV32-WITHFP-LABEL: va2:
+; RV32-WITHFP: # %bb.0:
+; RV32-WITHFP-NEXT: addi sp, sp, -48
+; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: addi s0, sp, 16
+; RV32-WITHFP-NEXT: sw a1, 4(s0)
+; RV32-WITHFP-NEXT: sw a2, 8(s0)
+; RV32-WITHFP-NEXT: sw a3, 12(s0)
+; RV32-WITHFP-NEXT: sw a4, 16(s0)
+; RV32-WITHFP-NEXT: addi a0, s0, 4
+; RV32-WITHFP-NEXT: sw a0, -12(s0)
+; RV32-WITHFP-NEXT: lw a0, -12(s0)
+; RV32-WITHFP-NEXT: sw a5, 20(s0)
+; RV32-WITHFP-NEXT: sw a6, 24(s0)
+; RV32-WITHFP-NEXT: sw a7, 28(s0)
+; RV32-WITHFP-NEXT: addi a0, a0, 7
+; RV32-WITHFP-NEXT: andi a1, a0, -8
+; RV32-WITHFP-NEXT: addi a0, a0, 8
+; RV32-WITHFP-NEXT: sw a0, -12(s0)
+; RV32-WITHFP-NEXT: lw a0, 0(a1)
+; RV32-WITHFP-NEXT: lw a1, 4(a1)
+; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: addi sp, sp, 48
+; RV32-WITHFP-NEXT: ret
+;
+; RV64-WITHFP-LABEL: va2:
+; RV64-WITHFP: # %bb.0:
+; RV64-WITHFP-NEXT: addi sp, sp, -96
+; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: addi s0, sp, 32
+; RV64-WITHFP-NEXT: sd a1, 8(s0)
+; RV64-WITHFP-NEXT: sd a2, 16(s0)
+; RV64-WITHFP-NEXT: sd a3, 24(s0)
+; RV64-WITHFP-NEXT: sd a4, 32(s0)
+; RV64-WITHFP-NEXT: addi a0, s0, 8
+; RV64-WITHFP-NEXT: sd a0, -24(s0)
+; RV64-WITHFP-NEXT: ld a0, -24(s0)
+; RV64-WITHFP-NEXT: sd a5, 40(s0)
+; RV64-WITHFP-NEXT: sd a6, 48(s0)
+; RV64-WITHFP-NEXT: sd a7, 56(s0)
+; RV64-WITHFP-NEXT: addi a1, a0, 7
+; RV64-WITHFP-NEXT: andi a1, a1, -8
+; RV64-WITHFP-NEXT: addi a0, a0, 15
+; RV64-WITHFP-NEXT: sd a0, -24(s0)
+; RV64-WITHFP-NEXT: ld a0, 0(a1)
+; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: addi sp, sp, 96
+; RV64-WITHFP-NEXT: ret
%va = alloca ptr
call void @llvm.va_start(ptr %va)
%argp.cur = load ptr, ptr %va
@@ -459,6 +733,61 @@ define i64 @va2_va_arg(ptr %fmt, ...) nounwind {
; RV64-NEXT: srli a0, a0, 32
; RV64-NEXT: addi sp, sp, 80
; RV64-NEXT: ret
+;
+; RV32-WITHFP-LABEL: va2_va_arg:
+; RV32-WITHFP: # %bb.0:
+; RV32-WITHFP-NEXT: addi sp, sp, -48
+; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: addi s0, sp, 16
+; RV32-WITHFP-NEXT: sw a1, 4(s0)
+; RV32-WITHFP-NEXT: sw a2, 8(s0)
+; RV32-WITHFP-NEXT: sw a3, 12(s0)
+; RV32-WITHFP-NEXT: sw a4, 16(s0)
+; RV32-WITHFP-NEXT: sw a5, 20(s0)
+; RV32-WITHFP-NEXT: sw a6, 24(s0)
+; RV32-WITHFP-NEXT: sw a7, 28(s0)
+; RV32-WITHFP-NEXT: addi a0, s0, 4
+; RV32-WITHFP-NEXT: sw a0, -12(s0)
+; RV32-WITHFP-NEXT: lw a0, -12(s0)
+; RV32-WITHFP-NEXT: addi a0, a0, 3
+; RV32-WITHFP-NEXT: andi a0, a0, -4
+; RV32-WITHFP-NEXT: addi a1, a0, 4
+; RV32-WITHFP-NEXT: sw a1, -12(s0)
+; RV32-WITHFP-NEXT: lw a0, 0(a0)
+; RV32-WITHFP-NEXT: li a1, 0
+; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: addi sp, sp, 48
+; RV32-WITHFP-NEXT: ret
+;
+; RV64-WITHFP-LABEL: va2_va_arg:
+; RV64-WITHFP: # %bb.0:
+; RV64-WITHFP-NEXT: addi sp, sp, -96
+; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: addi s0, sp, 32
+; RV64-WITHFP-NEXT: sd a1, 8(s0)
+; RV64-WITHFP-NEXT: sd a2, 16(s0)
+; RV64-WITHFP-NEXT: sd a3, 24(s0)
+; RV64-WITHFP-NEXT: sd a4, 32(s0)
+; RV64-WITHFP-NEXT: sd a5, 40(s0)
+; RV64-WITHFP-NEXT: sd a6, 48(s0)
+; RV64-WITHFP-NEXT: sd a7, 56(s0)
+; RV64-WITHFP-NEXT: addi a0, s0, 8
+; RV64-WITHFP-NEXT: sd a0, -24(s0)
+; RV64-WITHFP-NEXT: ld a0, -24(s0)
+; RV64-WITHFP-NEXT: addi a0, a0, 3
+; RV64-WITHFP-NEXT: andi a0, a0, -4
+; RV64-WITHFP-NEXT: addi a1, a0, 4
+; RV64-WITHFP-NEXT: sd a1, -24(s0)
+; RV64-WITHFP-NEXT: lw a0, 0(a0)
+; RV64-WITHFP-NEXT: slli a0, a0, 32
+; RV64-WITHFP-NEXT: srli a0, a0, 32
+; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: addi sp, sp, 96
+; RV64-WITHFP-NEXT: ret
%va = alloca ptr
call void @llvm.va_start(ptr %va)
%1 = va_arg ptr %va, i32
@@ -487,6 +816,32 @@ define void @va2_caller() nounwind {
; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64-NEXT: addi sp, sp, 16
; RV64-NEXT: ret
+;
+; RV32-WITHFP-LABEL: va2_caller:
+; RV32-WITHFP: # %bb.0:
+; RV32-WITHFP-NEXT: addi sp, sp, -16
+; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: addi s0, sp, 16
+; RV32-WITHFP-NEXT: li a1, 1
+; RV32-WITHFP-NEXT: call va2
+; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: addi sp, sp, 16
+; RV32-WITHFP-NEXT: ret
+;
+; RV64-WITHFP-LABEL: va2_caller:
+; RV64-WITHFP: # %bb.0:
+; RV64-WITHFP-NEXT: addi sp, sp, -16
+; RV64-WITHFP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: addi s0, sp, 16
+; RV64-WITHFP-NEXT: li a1, 1
+; RV64-WITHFP-NEXT: call va2
+; RV64-WITHFP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: addi sp, sp, 16
+; RV64-WITHFP-NEXT: ret
%1 = call i64 (ptr, ...) @va2(ptr undef, i32 1)
ret void
}
@@ -617,6 +972,61 @@ define i64 @va3(i32 %a, i64 %b, ...) nounwind {
; RV64-NEXT: add a0, a1, a0
; RV64-NEXT: addi sp, sp, 64
; RV64-NEXT: ret
+;
+; RV32-WITHFP-LABEL: va3:
+; RV32-WITHFP: # %bb.0:
+; RV32-WITHFP-NEXT: addi sp, sp, -48
+; RV32-WITHFP-NEXT: sw ra, 20(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: sw s0, 16(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: addi s0, sp, 24
+; RV32-WITHFP-NEXT: sw a3, 4(s0)
+; RV32-WITHFP-NEXT: sw a4, 8(s0)
+; RV32-WITHFP-NEXT: addi a0, s0, 4
+; RV32-WITHFP-NEXT: sw a0, -12(s0)
+; RV32-WITHFP-NEXT: lw a0, -12(s0)
+; RV32-WITHFP-NEXT: sw a5, 12(s0)
+; RV32-WITHFP-NEXT: sw a6, 16(s0)
+; RV32-WITHFP-NEXT: sw a7, 20(s0)
+; RV32-WITHFP-NEXT: addi a0, a0, 7
+; RV32-WITHFP-NEXT: andi a3, a0, -8
+; RV32-WITHFP-NEXT: addi a0, a0, 8
+; RV32-WITHFP-NEXT: sw a0, -12(s0)
+; RV32-WITHFP-NEXT: lw a4, 0(a3)
+; RV32-WITHFP-NEXT: lw a3, 4(a3)
+; RV32-WITHFP-NEXT: add a0, a1, a4
+; RV32-WITHFP-NEXT: sltu a1, a0, a4
+; RV32-WITHFP-NEXT: add a2, a2, a3
+; RV32-WITHFP-NEXT: add a1, a2, a1
+; RV32-WITHFP-NEXT: lw ra, 20(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: lw s0, 16(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: addi sp, sp, 48
+; RV32-WITHFP-NEXT: ret
+;
+; RV64-WITHFP-LABEL: va3:
+; RV64-WITHFP: # %bb.0:
+; RV64-WITHFP-NEXT: addi sp, sp, -80
+; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: addi s0, sp, 32
+; RV64-WITHFP-NEXT: sd a2, 0(s0)
+; RV64-WITHFP-NEXT: sd a3, 8(s0)
+; RV64-WITHFP-NEXT: sd a4, 16(s0)
+; RV64-WITHFP-NEXT: mv a0, s0
+; RV64-WITHFP-NEXT: sd a0, -24(s0)
+; RV64-WITHFP-NEXT: ld a0, -24(s0)
+; RV64-WITHFP-NEXT: sd a5, 24(s0)
+; RV64-WITHFP-NEXT: sd a6, 32(s0)
+; RV64-WITHFP-NEXT: sd a7, 40(s0)
+; RV64-WITHFP-NEXT: addi a2, a0, 7
+; RV64-WITHFP-NEXT: andi a2, a2, -8
+; RV64-WITHFP-NEXT: addi a0, a0, 15
+; RV64-WITHFP-NEXT: sd a0, -24(s0)
+; RV64-WITHFP-NEXT: ld a0, 0(a2)
+; RV64-WITHFP-NEXT: add a0, a1, a0
+; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: addi sp, sp, 80
+; RV64-WITHFP-NEXT: ret
%va = alloca ptr
call void @llvm.va_start(ptr %va)
%argp.cur = load ptr, ptr %va
@@ -682,6 +1092,61 @@ define i64 @va3_va_arg(i32 %a, i64 %b, ...) nounwind {
; RV64-NEXT: add a0, a1, a0
; RV64-NEXT: addi sp, sp, 64
; RV64-NEXT: ret
+;
+; RV32-WITHFP-LABEL: va3_va_arg:
+; RV32-WITHFP: # %bb.0:
+; RV32-WITHFP-NEXT: addi sp, sp, -48
+; RV32-WITHFP-NEXT: sw ra, 20(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: sw s0, 16(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: addi s0, sp, 24
+; RV32-WITHFP-NEXT: sw a3, 4(s0)
+; RV32-WITHFP-NEXT: sw a4, 8(s0)
+; RV32-WITHFP-NEXT: sw a5, 12(s0)
+; RV32-WITHFP-NEXT: sw a6, 16(s0)
+; RV32-WITHFP-NEXT: sw a7, 20(s0)
+; RV32-WITHFP-NEXT: addi a0, s0, 4
+; RV32-WITHFP-NEXT: sw a0, -12(s0)
+; RV32-WITHFP-NEXT: lw a0, -12(s0)
+; RV32-WITHFP-NEXT: addi a0, a0, 3
+; RV32-WITHFP-NEXT: andi a0, a0, -4
+; RV32-WITHFP-NEXT: addi a3, a0, 4
+; RV32-WITHFP-NEXT: sw a3, -12(s0)
+; RV32-WITHFP-NEXT: lw a3, 0(a0)
+; RV32-WITHFP-NEXT: add a0, a1, a3
+; RV32-WITHFP-NEXT: sltu a1, a0, a3
+; RV32-WITHFP-NEXT: add a1, a2, a1
+; RV32-WITHFP-NEXT: lw ra, 20(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: lw s0, 16(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: addi sp, sp, 48
+; RV32-WITHFP-NEXT: ret
+;
+; RV64-WITHFP-LABEL: va3_va_arg:
+; RV64-WITHFP: # %bb.0:
+; RV64-WITHFP-NEXT: addi sp, sp, -80
+; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: addi s0, sp, 32
+; RV64-WITHFP-NEXT: sd a2, 0(s0)
+; RV64-WITHFP-NEXT: sd a3, 8(s0)
+; RV64-WITHFP-NEXT: sd a4, 16(s0)
+; RV64-WITHFP-NEXT: sd a5, 24(s0)
+; RV64-WITHFP-NEXT: sd a6, 32(s0)
+; RV64-WITHFP-NEXT: sd a7, 40(s0)
+; RV64-WITHFP-NEXT: mv a0, s0
+; RV64-WITHFP-NEXT: sd a0, -24(s0)
+; RV64-WITHFP-NEXT: ld a0, -24(s0)
+; RV64-WITHFP-NEXT: addi a0, a0, 3
+; RV64-WITHFP-NEXT: andi a0, a0, -4
+; RV64-WITHFP-NEXT: addi a2, a0, 4
+; RV64-WITHFP-NEXT: sd a2, -24(s0)
+; RV64-WITHFP-NEXT: lw a0, 0(a0)
+; RV64-WITHFP-NEXT: slli a0, a0, 32
+; RV64-WITHFP-NEXT: srli a0, a0, 32
+; RV64-WITHFP-NEXT: add a0, a1, a0
+; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: addi sp, sp, 80
+; RV64-WITHFP-NEXT: ret
%va = alloca ptr
call void @llvm.va_start(ptr %va)
%1 = va_arg ptr %va, i32
@@ -718,6 +1183,39 @@ define void @va3_caller() nounwind {
; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64-NEXT: addi sp, sp, 16
; RV64-NEXT: ret
+;
+; RV32-WITHFP-LABEL: va3_caller:
+; RV32-WITHFP: # %bb.0:
+; RV32-WITHFP-NEXT: addi sp, sp, -16
+; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: addi s0, sp, 16
+; RV32-WITHFP-NEXT: lui a0, 5
+; RV32-WITHFP-NEXT: addi a3, a0, -480
+; RV32-WITHFP-NEXT: li a0, 2
+; RV32-WITHFP-NEXT: li a1, 1111
+; RV32-WITHFP-NEXT: li a2, 0
+; RV32-WITHFP-NEXT: call va3
+; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: addi sp, sp, 16
+; RV32-WITHFP-NEXT: ret
+;
+; RV64-WITHFP-LABEL: va3_caller:
+; RV64-WITHFP: # %bb.0:
+; RV64-WITHFP-NEXT: addi sp, sp, -16
+; RV64-WITHFP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: addi s0, sp, 16
+; RV64-WITHFP-NEXT: lui a0, 5
+; RV64-WITHFP-NEXT: addiw a2, a0, -480
+; RV64-WITHFP-NEXT: li a0, 2
+; RV64-WITHFP-NEXT: li a1, 1111
+; RV64-WITHFP-NEXT: call va3
+; RV64-WITHFP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: addi sp, sp, 16
+; RV64-WITHFP-NEXT: ret
%1 = call i64 (i32, i64, ...) @va3(i32 2, i64 1111, i32 20000)
ret void
}
@@ -745,9 +1243,8 @@ define i32 @va4_va_copy(i32 %argno, ...) nounwind {
; RV32-NEXT: addi a1, a0, 4
; RV32-NEXT: sw a1, 4(sp)
; RV32-NEXT: lw a1, 4(sp)
-; RV32-NEXT: mv a2, sp
; RV32-NEXT: lw s0, 0(a0)
-; RV32-NEXT: sw a2, 0(a1)
+; RV32-NEXT: sw a1, 0(sp)
; RV32-NEXT: lw a0, 0(sp)
; RV32-NEXT: call notdead
; RV32-NEXT: lw a0, 4(sp)
@@ -796,9 +1293,8 @@ define i32 @va4_va_copy(i32 %argno, ...) nounwind {
; RV64-NEXT: addi a1, a0, 4
; RV64-NEXT: sd a1, 8(sp)
; RV64-NEXT: ld a1, 8(sp)
-; RV64-NEXT: mv a2, sp
; RV64-NEXT: lw s0, 0(a0)
-; RV64-NEXT: sd a2, 0(a1)
+; RV64-NEXT: sd a1, 0(sp)
; RV64-NEXT: lw a0, 4(sp)
; RV64-NEXT: lwu a1, 0(sp)
; RV64-NEXT: slli a0, a0, 32
@@ -829,6 +1325,115 @@ define i32 @va4_va_copy(i32 %argno, ...) nounwind {
; RV64-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
; RV64-NEXT: addi sp, sp, 96
; RV64-NEXT: ret
+;
+; RV32-WITHFP-LABEL: va4_va_copy:
+; RV32-WITHFP: # %bb.0:
+; RV32-WITHFP-NEXT: addi sp, sp, -64
+; RV32-WITHFP-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: addi s0, sp, 32
+; RV32-WITHFP-NEXT: sw a1, 4(s0)
+; RV32-WITHFP-NEXT: sw a2, 8(s0)
+; RV32-WITHFP-NEXT: sw a3, 12(s0)
+; RV32-WITHFP-NEXT: sw a4, 16(s0)
+; RV32-WITHFP-NEXT: sw a5, 20(s0)
+; RV32-WITHFP-NEXT: sw a6, 24(s0)
+; RV32-WITHFP-NEXT: sw a7, 28(s0)
+; RV32-WITHFP-NEXT: addi a0, s0, 4
+; RV32-WITHFP-NEXT: sw a0, -16(s0)
+; RV32-WITHFP-NEXT: lw a0, -16(s0)
+; RV32-WITHFP-NEXT: addi a0, a0, 3
+; RV32-WITHFP-NEXT: andi a0, a0, -4
+; RV32-WITHFP-NEXT: addi a1, a0, 4
+; RV32-WITHFP-NEXT: sw a1, -16(s0)
+; RV32-WITHFP-NEXT: lw a1, -16(s0)
+; RV32-WITHFP-NEXT: lw s1, 0(a0)
+; RV32-WITHFP-NEXT: sw a1, -20(s0)
+; RV32-WITHFP-NEXT: lw a0, -20(s0)
+; RV32-WITHFP-NEXT: call notdead
+; RV32-WITHFP-NEXT: lw a0, -16(s0)
+; RV32-WITHFP-NEXT: addi a0, a0, 3
+; RV32-WITHFP-NEXT: andi a0, a0, -4
+; RV32-WITHFP-NEXT: addi a1, a0, 4
+; RV32-WITHFP-NEXT: sw a1, -16(s0)
+; RV32-WITHFP-NEXT: lw a1, -16(s0)
+; RV32-WITHFP-NEXT: lw a0, 0(a0)
+; RV32-WITHFP-NEXT: addi a1, a1, 3
+; RV32-WITHFP-NEXT: andi a1, a1, -4
+; RV32-WITHFP-NEXT: addi a2, a1, 4
+; RV32-WITHFP-NEXT: sw a2, -16(s0)
+; RV32-WITHFP-NEXT: lw a2, -16(s0)
+; RV32-WITHFP-NEXT: lw a1, 0(a1)
+; RV32-WITHFP-NEXT: addi a2, a2, 3
+; RV32-WITHFP-NEXT: andi a2, a2, -4
+; RV32-WITHFP-NEXT: addi a3, a2, 4
+; RV32-WITHFP-NEXT: sw a3, -16(s0)
+; RV32-WITHFP-NEXT: lw a2, 0(a2)
+; RV32-WITHFP-NEXT: add a0, a0, s1
+; RV32-WITHFP-NEXT: add a1, a1, a2
+; RV32-WITHFP-NEXT: add a0, a0, a1
+; RV32-WITHFP-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: addi sp, sp, 64
+; RV32-WITHFP-NEXT: ret
+;
+; RV64-WITHFP-LABEL: va4_va_copy:
+; RV64-WITHFP: # %bb.0:
+; RV64-WITHFP-NEXT: addi sp, sp, -112
+; RV64-WITHFP-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: addi s0, sp, 48
+; RV64-WITHFP-NEXT: sd a1, 8(s0)
+; RV64-WITHFP-NEXT: sd a2, 16(s0)
+; RV64-WITHFP-NEXT: sd a3, 24(s0)
+; RV64-WITHFP-NEXT: sd a4, 32(s0)
+; RV64-WITHFP-NEXT: sd a5, 40(s0)
+; RV64-WITHFP-NEXT: sd a6, 48(s0)
+; RV64-WITHFP-NEXT: sd a7, 56(s0)
+; RV64-WITHFP-NEXT: addi a0, s0, 8
+; RV64-WITHFP-NEXT: sd a0, -32(s0)
+; RV64-WITHFP-NEXT: ld a0, -32(s0)
+; RV64-WITHFP-NEXT: addi a0, a0, 3
+; RV64-WITHFP-NEXT: andi a0, a0, -4
+; RV64-WITHFP-NEXT: addi a1, a0, 4
+; RV64-WITHFP-NEXT: sd a1, -32(s0)
+; RV64-WITHFP-NEXT: ld a1, -32(s0)
+; RV64-WITHFP-NEXT: lw s1, 0(a0)
+; RV64-WITHFP-NEXT: sd a1, -40(s0)
+; RV64-WITHFP-NEXT: lw a0, -36(s0)
+; RV64-WITHFP-NEXT: lwu a1, -40(s0)
+; RV64-WITHFP-NEXT: slli a0, a0, 32
+; RV64-WITHFP-NEXT: or a0, a0, a1
+; RV64-WITHFP-NEXT: call notdead
+; RV64-WITHFP-NEXT: ld a0, -32(s0)
+; RV64-WITHFP-NEXT: addi a0, a0, 3
+; RV64-WITHFP-NEXT: andi a0, a0, -4
+; RV64-WITHFP-NEXT: addi a1, a0, 4
+; RV64-WITHFP-NEXT: sd a1, -32(s0)
+; RV64-WITHFP-NEXT: ld a1, -32(s0)
+; RV64-WITHFP-NEXT: lw a0, 0(a0)
+; RV64-WITHFP-NEXT: addi a1, a1, 3
+; RV64-WITHFP-NEXT: andi a1, a1, -4
+; RV64-WITHFP-NEXT: addi a2, a1, 4
+; RV64-WITHFP-NEXT: sd a2, -32(s0)
+; RV64-WITHFP-NEXT: ld a2, -32(s0)
+; RV64-WITHFP-NEXT: lw a1, 0(a1)
+; RV64-WITHFP-NEXT: addi a2, a2, 3
+; RV64-WITHFP-NEXT: andi a2, a2, -4
+; RV64-WITHFP-NEXT: addi a3, a2, 4
+; RV64-WITHFP-NEXT: sd a3, -32(s0)
+; RV64-WITHFP-NEXT: lw a2, 0(a2)
+; RV64-WITHFP-NEXT: add a0, a0, s1
+; RV64-WITHFP-NEXT: add a1, a1, a2
+; RV64-WITHFP-NEXT: addw a0, a0, a1
+; RV64-WITHFP-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: addi sp, sp, 112
+; RV64-WITHFP-NEXT: ret
%vargs = alloca ptr
%wargs = alloca ptr
call void @llvm.va_start(ptr %vargs)
@@ -899,6 +1504,60 @@ define i32 @va6_no_fixed_args(...) nounwind {
; RV64-NEXT: lw a0, 0(a0)
; RV64-NEXT: addi sp, sp, 80
; RV64-NEXT: ret
+;
+; RV32-WITHFP-LABEL: va6_no_fixed_args:
+; RV32-WITHFP: # %bb.0:
+; RV32-WITHFP-NEXT: addi sp, sp, -48
+; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: addi s0, sp, 16
+; RV32-WITHFP-NEXT: sw a0, 0(s0)
+; RV32-WITHFP-NEXT: sw a1, 4(s0)
+; RV32-WITHFP-NEXT: sw a2, 8(s0)
+; RV32-WITHFP-NEXT: sw a3, 12(s0)
+; RV32-WITHFP-NEXT: sw a4, 16(s0)
+; RV32-WITHFP-NEXT: sw a5, 20(s0)
+; RV32-WITHFP-NEXT: sw a6, 24(s0)
+; RV32-WITHFP-NEXT: sw a7, 28(s0)
+; RV32-WITHFP-NEXT: mv a0, s0
+; RV32-WITHFP-NEXT: sw a0, -12(s0)
+; RV32-WITHFP-NEXT: lw a0, -12(s0)
+; RV32-WITHFP-NEXT: addi a0, a0, 3
+; RV32-WITHFP-NEXT: andi a0, a0, -4
+; RV32-WITHFP-NEXT: addi a1, a0, 4
+; RV32-WITHFP-NEXT: sw a1, -12(s0)
+; RV32-WITHFP-NEXT: lw a0, 0(a0)
+; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: addi sp, sp, 48
+; RV32-WITHFP-NEXT: ret
+;
+; RV64-WITHFP-LABEL: va6_no_fixed_args:
+; RV64-WITHFP: # %bb.0:
+; RV64-WITHFP-NEXT: addi sp, sp, -96
+; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: addi s0, sp, 32
+; RV64-WITHFP-NEXT: sd a0, 0(s0)
+; RV64-WITHFP-NEXT: sd a1, 8(s0)
+; RV64-WITHFP-NEXT: sd a2, 16(s0)
+; RV64-WITHFP-NEXT: sd a3, 24(s0)
+; RV64-WITHFP-NEXT: sd a4, 32(s0)
+; RV64-WITHFP-NEXT: sd a5, 40(s0)
+; RV64-WITHFP-NEXT: sd a6, 48(s0)
+; RV64-WITHFP-NEXT: sd a7, 56(s0)
+; RV64-WITHFP-NEXT: mv a0, s0
+; RV64-WITHFP-NEXT: sd a0, -24(s0)
+; RV64-WITHFP-NEXT: ld a0, -24(s0)
+; RV64-WITHFP-NEXT: addi a0, a0, 3
+; RV64-WITHFP-NEXT: andi a0, a0, -4
+; RV64-WITHFP-NEXT: addi a1, a0, 4
+; RV64-WITHFP-NEXT: sd a1, -24(s0)
+; RV64-WITHFP-NEXT: lw a0, 0(a0)
+; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: addi sp, sp, 96
+; RV64-WITHFP-NEXT: ret
%va = alloca ptr
call void @llvm.va_start(ptr %va)
%1 = va_arg ptr %va, i32
@@ -993,6 +1652,85 @@ define i32 @va_large_stack(ptr %fmt, ...) {
; RV64-NEXT: addiw a1, a1, 336
; RV64-NEXT: add sp, sp, a1
; RV64-NEXT: ret
+;
+; RV32-WITHFP-LABEL: va_large_stack:
+; RV32-WITHFP: # %bb.0:
+; RV32-WITHFP-NEXT: addi sp, sp, -2032
+; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 2032
+; RV32-WITHFP-NEXT: sw ra, 1996(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: sw s0, 1992(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: .cfi_offset ra, -36
+; RV32-WITHFP-NEXT: .cfi_offset s0, -40
+; RV32-WITHFP-NEXT: addi s0, sp, 2000
+; RV32-WITHFP-NEXT: .cfi_def_cfa s0, 32
+; RV32-WITHFP-NEXT: lui a0, 24414
+; RV32-WITHFP-NEXT: addi a0, a0, -1728
+; RV32-WITHFP-NEXT: sub sp, sp, a0
+; RV32-WITHFP-NEXT: lui a0, 24414
+; RV32-WITHFP-NEXT: addi a0, a0, 272
+; RV32-WITHFP-NEXT: sub a0, s0, a0
+; RV32-WITHFP-NEXT: sw a1, 4(s0)
+; RV32-WITHFP-NEXT: sw a2, 8(s0)
+; RV32-WITHFP-NEXT: sw a3, 12(s0)
+; RV32-WITHFP-NEXT: sw a4, 16(s0)
+; RV32-WITHFP-NEXT: addi a1, s0, 4
+; RV32-WITHFP-NEXT: sw a1, 0(a0)
+; RV32-WITHFP-NEXT: lw a1, 0(a0)
+; RV32-WITHFP-NEXT: sw a5, 20(s0)
+; RV32-WITHFP-NEXT: sw a6, 24(s0)
+; RV32-WITHFP-NEXT: sw a7, 28(s0)
+; RV32-WITHFP-NEXT: addi a2, a1, 4
+; RV32-WITHFP-NEXT: sw a2, 0(a0)
+; RV32-WITHFP-NEXT: lw a0, 0(a1)
+; RV32-WITHFP-NEXT: lui a1, 24414
+; RV32-WITHFP-NEXT: addi a1, a1, -1728
+; RV32-WITHFP-NEXT: add sp, sp, a1
+; RV32-WITHFP-NEXT: lw ra, 1996(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: lw s0, 1992(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: addi sp, sp, 2032
+; RV32-WITHFP-NEXT: ret
+;
+; RV64-WITHFP-LABEL: va_large_stack:
+; RV64-WITHFP: # %bb.0:
+; RV64-WITHFP-NEXT: addi sp, sp, -2032
+; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 2032
+; RV64-WITHFP-NEXT: sd ra, 1960(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: sd s0, 1952(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: .cfi_offset ra, -72
+; RV64-WITHFP-NEXT: .cfi_offset s0, -80
+; RV64-WITHFP-NEXT: addi s0, sp, 1968
+; RV64-WITHFP-NEXT: .cfi_def_cfa s0, 64
+; RV64-WITHFP-NEXT: lui a0, 24414
+; RV64-WITHFP-NEXT: addiw a0, a0, -1680
+; RV64-WITHFP-NEXT: sub sp, sp, a0
+; RV64-WITHFP-NEXT: lui a0, 24414
+; RV64-WITHFP-NEXT: addiw a0, a0, 288
+; RV64-WITHFP-NEXT: sub a0, s0, a0
+; RV64-WITHFP-NEXT: sd a1, 8(s0)
+; RV64-WITHFP-NEXT: sd a2, 16(s0)
+; RV64-WITHFP-NEXT: sd a3, 24(s0)
+; RV64-WITHFP-NEXT: sd a4, 32(s0)
+; RV64-WITHFP-NEXT: sd a5, 40(s0)
+; RV64-WITHFP-NEXT: addi a1, s0, 8
+; RV64-WITHFP-NEXT: sd a1, 0(a0)
+; RV64-WITHFP-NEXT: lw a1, 4(a0)
+; RV64-WITHFP-NEXT: lwu a2, 0(a0)
+; RV64-WITHFP-NEXT: sd a6, 48(s0)
+; RV64-WITHFP-NEXT: sd a7, 56(s0)
+; RV64-WITHFP-NEXT: slli a1, a1, 32
+; RV64-WITHFP-NEXT: or a1, a1, a2
+; RV64-WITHFP-NEXT: addi a2, a1, 4
+; RV64-WITHFP-NEXT: srli a3, a2, 32
+; RV64-WITHFP-NEXT: sw a2, 0(a0)
+; RV64-WITHFP-NEXT: sw a3, 4(a0)
+; RV64-WITHFP-NEXT: lw a0, 0(a1)
+; RV64-WITHFP-NEXT: lui a1, 24414
+; RV64-WITHFP-NEXT: addiw a1, a1, -1680
+; RV64-WITHFP-NEXT: add sp, sp, a1
+; RV64-WITHFP-NEXT: ld ra, 1960(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: ld s0, 1952(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: addi sp, sp, 2032
+; RV64-WITHFP-NEXT: ret
%large = alloca [ 100000000 x i8 ]
%va = alloca ptr
call void @llvm.va_start(ptr %va)
@@ -1004,5 +1742,193 @@ define i32 @va_large_stack(ptr %fmt, ...) {
ret i32 %1
}
+define i32 @va_vprintf(ptr %fmt, ptr %arg_start) {
+; RV32-LABEL: va_vprintf:
+; RV32: # %bb.0:
+; RV32-NEXT: addi sp, sp, -16
+; RV32-NEXT: .cfi_def_cfa_offset 16
+; RV32-NEXT: sw a1, 12(sp)
+; RV32-NEXT: lw a0, 12(sp)
+; RV32-NEXT: sw a0, 8(sp)
+; RV32-NEXT: lw a0, 8(sp)
+; RV32-NEXT: addi a0, a0, 3
+; RV32-NEXT: andi a0, a0, -4
+; RV32-NEXT: addi a1, a0, 4
+; RV32-NEXT: sw a1, 8(sp)
+; RV32-NEXT: lw a0, 0(a0)
+; RV32-NEXT: addi sp, sp, 16
+; RV32-NEXT: ret
+;
+; RV64-LABEL: va_vprintf:
+; RV64: # %bb.0:
+; RV64-NEXT: addi sp, sp, -16
+; RV64-NEXT: .cfi_def_cfa_offset 16
+; RV64-NEXT: sd a1, 8(sp)
+; RV64-NEXT: ld a0, 8(sp)
+; RV64-NEXT: sd a0, 0(sp)
+; RV64-NEXT: ld a0, 0(sp)
+; RV64-NEXT: addi a0, a0, 3
+; RV64-NEXT: andi a0, a0, -4
+; RV64-NEXT: addi a1, a0, 4
+; RV64-NEXT: sd a1, 0(sp)
+; RV64-NEXT: lw a0, 0(a0)
+; RV64-NEXT: addi sp, sp, 16
+; RV64-NEXT: ret
+;
+; RV32-WITHFP-LABEL: va_vprintf:
+; RV32-WITHFP: # %bb.0:
+; RV32-WITHFP-NEXT: addi sp, sp, -16
+; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 16
+; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: .cfi_offset ra, -4
+; RV32-WITHFP-NEXT: .cfi_offset s0, -8
+; RV32-WITHFP-NEXT: addi s0, sp, 16
+; RV32-WITHFP-NEXT: .cfi_def_cfa s0, 0
+; RV32-WITHFP-NEXT: sw a1, -12(s0)
+; RV32-WITHFP-NEXT: lw a0, -12(s0)
+; RV32-WITHFP-NEXT: sw a0, -16(s0)
+; RV32-WITHFP-NEXT: lw a0, -16(s0)
+; RV32-WITHFP-NEXT: addi a0, a0, 3
+; RV32-WITHFP-NEXT: andi a0, a0, -4
+; RV32-WITHFP-NEXT: addi a1, a0, 4
+; RV32-WITHFP-NEXT: sw a1, -16(s0)
+; RV32-WITHFP-NEXT: lw a0, 0(a0)
+; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: addi sp, sp, 16
+; RV32-WITHFP-NEXT: ret
+;
+; RV64-WITHFP-LABEL: va_vprintf:
+; RV64-WITHFP: # %bb.0:
+; RV64-WITHFP-NEXT: addi sp, sp, -32
+; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 32
+; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: .cfi_offset ra, -8
+; RV64-WITHFP-NEXT: .cfi_offset s0, -16
+; RV64-WITHFP-NEXT: addi s0, sp, 32
+; RV64-WITHFP-NEXT: .cfi_def_cfa s0, 0
+; RV64-WITHFP-NEXT: sd a1, -24(s0)
+; RV64-WITHFP-NEXT: ld a0, -24(s0)
+; RV64-WITHFP-NEXT: sd a0, -32(s0)
+; RV64-WITHFP-NEXT: ld a0, -32(s0)
+; RV64-WITHFP-NEXT: addi a0, a0, 3
+; RV64-WITHFP-NEXT: andi a0, a0, -4
+; RV64-WITHFP-NEXT: addi a1, a0, 4
+; RV64-WITHFP-NEXT: sd a1, -32(s0)
+; RV64-WITHFP-NEXT: lw a0, 0(a0)
+; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: addi sp, sp, 32
+; RV64-WITHFP-NEXT: ret
+ %args = alloca ptr
+ %args_cp = alloca ptr
+ store ptr %arg_start, ptr %args
+ call void @llvm.va_copy(ptr %args_cp, ptr %args)
+ %width = va_arg ptr %args_cp, i32
+ call void @llvm.va_end(ptr %args_cp)
+ ret i32 %width
+}
-
+define i32 @va_printf(ptr %fmt, ...) {
+; RV32-LABEL: va_printf:
+; RV32: # %bb.0:
+; RV32-NEXT: addi sp, sp, -48
+; RV32-NEXT: .cfi_def_cfa_offset 48
+; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32-NEXT: .cfi_offset ra, -36
+; RV32-NEXT: sw a1, 20(sp)
+; RV32-NEXT: sw a2, 24(sp)
+; RV32-NEXT: sw a3, 28(sp)
+; RV32-NEXT: sw a4, 32(sp)
+; RV32-NEXT: addi a1, sp, 20
+; RV32-NEXT: sw a1, 8(sp)
+; RV32-NEXT: lw a1, 8(sp)
+; RV32-NEXT: sw a5, 36(sp)
+; RV32-NEXT: sw a6, 40(sp)
+; RV32-NEXT: sw a7, 44(sp)
+; RV32-NEXT: call va_vprintf
+; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32-NEXT: addi sp, sp, 48
+; RV32-NEXT: ret
+;
+; RV64-LABEL: va_printf:
+; RV64: # %bb.0:
+; RV64-NEXT: addi sp, sp, -80
+; RV64-NEXT: .cfi_def_cfa_offset 80
+; RV64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64-NEXT: .cfi_offset ra, -72
+; RV64-NEXT: sd a1, 24(sp)
+; RV64-NEXT: sd a2, 32(sp)
+; RV64-NEXT: sd a3, 40(sp)
+; RV64-NEXT: sd a4, 48(sp)
+; RV64-NEXT: addi a1, sp, 24
+; RV64-NEXT: sd a1, 0(sp)
+; RV64-NEXT: ld a1, 0(sp)
+; RV64-NEXT: sd a5, 56(sp)
+; RV64-NEXT: sd a6, 64(sp)
+; RV64-NEXT: sd a7, 72(sp)
+; RV64-NEXT: call va_vprintf
+; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64-NEXT: addi sp, sp, 80
+; RV64-NEXT: ret
+;
+; RV32-WITHFP-LABEL: va_printf:
+; RV32-WITHFP: # %bb.0:
+; RV32-WITHFP-NEXT: addi sp, sp, -48
+; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 48
+; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
+; RV32-WITHFP-NEXT: .cfi_offset ra, -36
+; RV32-WITHFP-NEXT: .cfi_offset s0, -40
+; RV32-WITHFP-NEXT: addi s0, sp, 16
+; RV32-WITHFP-NEXT: .cfi_def_cfa s0, 32
+; RV32-WITHFP-NEXT: sw a1, 4(s0)
+; RV32-WITHFP-NEXT: sw a2, 8(s0)
+; RV32-WITHFP-NEXT: sw a3, 12(s0)
+; RV32-WITHFP-NEXT: sw a4, 16(s0)
+; RV32-WITHFP-NEXT: addi a1, s0, 4
+; RV32-WITHFP-NEXT: sw a1, -12(s0)
+; RV32-WITHFP-NEXT: lw a1, -12(s0)
+; RV32-WITHFP-NEXT: sw a5, 20(s0)
+; RV32-WITHFP-NEXT: sw a6, 24(s0)
+; RV32-WITHFP-NEXT: sw a7, 28(s0)
+; RV32-WITHFP-NEXT: call va_vprintf
+; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: addi sp, sp, 48
+; RV32-WITHFP-NEXT: ret
+;
+; RV64-WITHFP-LABEL: va_printf:
+; RV64-WITHFP: # %bb.0:
+; RV64-WITHFP-NEXT: addi sp, sp, -96
+; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 96
+; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
+; RV64-WITHFP-NEXT: .cfi_offset ra, -72
+; RV64-WITHFP-NEXT: .cfi_offset s0, -80
+; RV64-WITHFP-NEXT: addi s0, sp, 32
+; RV64-WITHFP-NEXT: .cfi_def_cfa s0, 64
+; RV64-WITHFP-NEXT: sd a1, 8(s0)
+; RV64-WITHFP-NEXT: sd a2, 16(s0)
+; RV64-WITHFP-NEXT: sd a3, 24(s0)
+; RV64-WITHFP-NEXT: sd a4, 32(s0)
+; RV64-WITHFP-NEXT: addi a1, s0, 8
+; RV64-WITHFP-NEXT: sd a1, -24(s0)
+; RV64-WITHFP-NEXT: ld a1, -24(s0)
+; RV64-WITHFP-NEXT: sd a5, 40(s0)
+; RV64-WITHFP-NEXT: sd a6, 48(s0)
+; RV64-WITHFP-NEXT: sd a7, 56(s0)
+; RV64-WITHFP-NEXT: call va_vprintf
+; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: addi sp, sp, 96
+; RV64-WITHFP-NEXT: ret
+ %args = alloca ptr
+ call void @llvm.va_start(ptr %args)
+ %arg_start = load ptr, ptr %args
+ %ret_val = call i32 @va_vprintf(ptr %fmt, ptr %arg_start)
+ call void @llvm.va_end(ptr %args)
+ ret i32 %ret_val
+}