xref: /llvm-project/llvm/test/CodeGen/LoongArch/calling-conv-common.ll (revision 1897bf61f0bc85c8637997d0f2aa7d94d375d787)
12cf03140SWeining Lu; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
22cf03140SWeining Lu; RUN: llc --mtriple=loongarch64 --target-abi=lp64s < %s | FileCheck %s
32cf03140SWeining Lu; RUN: llc --mtriple=loongarch64 --mattr=+d --target-abi=lp64d < %s | FileCheck %s
42cf03140SWeining Lu
52cf03140SWeining Lu;; This file contains tests that should have identical output for all ABIs, i.e.
62cf03140SWeining Lu;; where no arguments are passed via floating point registers.
72cf03140SWeining Lu
82cf03140SWeining Lu;; Check that on LA64, i128 is passed in a pair of GPRs.
92cf03140SWeining Ludefine i64 @callee_i128_in_regs(i64 %a, i128 %b) nounwind {
102cf03140SWeining Lu; CHECK-LABEL: callee_i128_in_regs:
112cf03140SWeining Lu; CHECK:       # %bb.0:
122cf03140SWeining Lu; CHECK-NEXT:    add.d $a0, $a0, $a1
132cf03140SWeining Lu; CHECK-NEXT:    ret
142cf03140SWeining Lu  %b_trunc = trunc i128 %b to i64
152cf03140SWeining Lu  %1 = add i64 %a, %b_trunc
162cf03140SWeining Lu  ret i64 %1
172cf03140SWeining Lu}
182cf03140SWeining Lu
192cf03140SWeining Ludefine i64 @caller_i128_in_regs() nounwind {
202cf03140SWeining Lu; CHECK-LABEL: caller_i128_in_regs:
212cf03140SWeining Lu; CHECK:       # %bb.0:
222cf03140SWeining Lu; CHECK-NEXT:    addi.d $sp, $sp, -16
232cf03140SWeining Lu; CHECK-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
242cf03140SWeining Lu; CHECK-NEXT:    ori $a0, $zero, 1
252cf03140SWeining Lu; CHECK-NEXT:    ori $a1, $zero, 2
262cf03140SWeining Lu; CHECK-NEXT:    move $a2, $zero
272cf03140SWeining Lu; CHECK-NEXT:    bl %plt(callee_i128_in_regs)
282cf03140SWeining Lu; CHECK-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
292cf03140SWeining Lu; CHECK-NEXT:    addi.d $sp, $sp, 16
302cf03140SWeining Lu; CHECK-NEXT:    ret
312cf03140SWeining Lu  %1 = call i64 @callee_i128_in_regs(i64 1, i128 2)
322cf03140SWeining Lu  ret i64 %1
332cf03140SWeining Lu}
342cf03140SWeining Lu
352cf03140SWeining Lu;; Check that the stack is used once the GPRs are exhausted.
362cf03140SWeining Ludefine i64 @callee_many_scalars(i8 %a, i16 %b, i32 %c, i64 %d, i128 %e, i64 %f, i128 %g, i64 %h) nounwind {
372cf03140SWeining Lu; CHECK-LABEL: callee_many_scalars:
382cf03140SWeining Lu; CHECK:       # %bb.0:
39a5c90e48Swanglei; CHECK-NEXT:    ld.d $t0, $sp, 8
40a5c90e48Swanglei; CHECK-NEXT:    ld.d $t1, $sp, 0
412cf03140SWeining Lu; CHECK-NEXT:    andi $a0, $a0, 255
42a5c90e48Swanglei; CHECK-NEXT:    bstrpick.d $a1, $a1, 15, 0
43a5c90e48Swanglei; CHECK-NEXT:    bstrpick.d $a2, $a2, 31, 0
442cf03140SWeining Lu; CHECK-NEXT:    add.d $a0, $a0, $a1
45a5c90e48Swanglei; CHECK-NEXT:    add.d $a0, $a0, $a2
462cf03140SWeining Lu; CHECK-NEXT:    add.d $a0, $a0, $a3
47a5c90e48Swanglei; CHECK-NEXT:    xor $a1, $a5, $t1
48a5c90e48Swanglei; CHECK-NEXT:    xor $a2, $a4, $a7
49a5c90e48Swanglei; CHECK-NEXT:    or $a1, $a2, $a1
50a5c90e48Swanglei; CHECK-NEXT:    sltui $a1, $a1, 1
512cf03140SWeining Lu; CHECK-NEXT:    add.d $a0, $a1, $a0
522cf03140SWeining Lu; CHECK-NEXT:    add.d $a0, $a0, $a6
53a5c90e48Swanglei; CHECK-NEXT:    add.d $a0, $a0, $t0
542cf03140SWeining Lu; CHECK-NEXT:    ret
552cf03140SWeining Lu  %a_ext = zext i8 %a to i64
562cf03140SWeining Lu  %b_ext = zext i16 %b to i64
572cf03140SWeining Lu  %c_ext = zext i32 %c to i64
582cf03140SWeining Lu  %1 = add i64 %a_ext, %b_ext
592cf03140SWeining Lu  %2 = add i64 %1, %c_ext
602cf03140SWeining Lu  %3 = add i64 %2, %d
612cf03140SWeining Lu  %4 = icmp eq i128 %e, %g
622cf03140SWeining Lu  %5 = zext i1 %4 to i64
632cf03140SWeining Lu  %6 = add i64 %5, %3
642cf03140SWeining Lu  %7 = add i64 %6, %f
652cf03140SWeining Lu  %8 = add i64 %7, %h
662cf03140SWeining Lu  ret i64 %8
672cf03140SWeining Lu}
682cf03140SWeining Lu
692cf03140SWeining Ludefine i64 @caller_many_scalars() nounwind {
702cf03140SWeining Lu; CHECK-LABEL: caller_many_scalars:
712cf03140SWeining Lu; CHECK:       # %bb.0:
722cf03140SWeining Lu; CHECK-NEXT:    addi.d $sp, $sp, -32
732cf03140SWeining Lu; CHECK-NEXT:    st.d $ra, $sp, 24 # 8-byte Folded Spill
742cf03140SWeining Lu; CHECK-NEXT:    ori $a0, $zero, 8
752cf03140SWeining Lu; CHECK-NEXT:    st.d $a0, $sp, 8
762cf03140SWeining Lu; CHECK-NEXT:    ori $a0, $zero, 1
772cf03140SWeining Lu; CHECK-NEXT:    ori $a1, $zero, 2
782cf03140SWeining Lu; CHECK-NEXT:    ori $a2, $zero, 3
792cf03140SWeining Lu; CHECK-NEXT:    ori $a3, $zero, 4
802cf03140SWeining Lu; CHECK-NEXT:    ori $a4, $zero, 5
812cf03140SWeining Lu; CHECK-NEXT:    ori $a6, $zero, 6
822cf03140SWeining Lu; CHECK-NEXT:    ori $a7, $zero, 7
83a5c90e48Swanglei; CHECK-NEXT:    st.d $zero, $sp, 0
842cf03140SWeining Lu; CHECK-NEXT:    move $a5, $zero
852cf03140SWeining Lu; CHECK-NEXT:    bl %plt(callee_many_scalars)
862cf03140SWeining Lu; CHECK-NEXT:    ld.d $ra, $sp, 24 # 8-byte Folded Reload
872cf03140SWeining Lu; CHECK-NEXT:    addi.d $sp, $sp, 32
882cf03140SWeining Lu; CHECK-NEXT:    ret
892cf03140SWeining Lu  %1 = call i64 @callee_many_scalars(i8 1, i16 2, i32 3, i64 4, i128 5, i64 6, i128 7, i64 8)
902cf03140SWeining Lu  ret i64 %1
912cf03140SWeining Lu}
922cf03140SWeining Lu
932cf03140SWeining Lu;; Check that i256 is passed indirectly.
942cf03140SWeining Lu
952cf03140SWeining Ludefine i64 @callee_large_scalars(i256 %a, i256 %b) nounwind {
962cf03140SWeining Lu; CHECK-LABEL: callee_large_scalars:
972cf03140SWeining Lu; CHECK:       # %bb.0:
98a5c90e48Swanglei; CHECK-NEXT:    ld.d $a2, $a1, 0
99a5c90e48Swanglei; CHECK-NEXT:    ld.d $a3, $a0, 0
100a5c90e48Swanglei; CHECK-NEXT:    ld.d $a4, $a1, 8
101a5c90e48Swanglei; CHECK-NEXT:    ld.d $a5, $a1, 24
102a5c90e48Swanglei; CHECK-NEXT:    ld.d $a6, $a0, 24
103a5c90e48Swanglei; CHECK-NEXT:    ld.d $a7, $a0, 8
104a5c90e48Swanglei; CHECK-NEXT:    ld.d $a1, $a1, 16
105a5c90e48Swanglei; CHECK-NEXT:    ld.d $a0, $a0, 16
106a5c90e48Swanglei; CHECK-NEXT:    xor $a5, $a6, $a5
107a5c90e48Swanglei; CHECK-NEXT:    xor $a4, $a7, $a4
108a5c90e48Swanglei; CHECK-NEXT:    or $a4, $a4, $a5
1092cf03140SWeining Lu; CHECK-NEXT:    xor $a0, $a0, $a1
110a5c90e48Swanglei; CHECK-NEXT:    xor $a1, $a3, $a2
111a5c90e48Swanglei; CHECK-NEXT:    or $a0, $a1, $a0
112a5c90e48Swanglei; CHECK-NEXT:    or $a0, $a0, $a4
1132cf03140SWeining Lu; CHECK-NEXT:    sltui $a0, $a0, 1
1142cf03140SWeining Lu; CHECK-NEXT:    ret
1152cf03140SWeining Lu  %1 = icmp eq i256 %a, %b
1162cf03140SWeining Lu  %2 = zext i1 %1 to i64
1172cf03140SWeining Lu  ret i64 %2
1182cf03140SWeining Lu}
1192cf03140SWeining Lu
1202cf03140SWeining Ludefine i64 @caller_large_scalars() nounwind {
1212cf03140SWeining Lu; CHECK-LABEL: caller_large_scalars:
1222cf03140SWeining Lu; CHECK:       # %bb.0:
1232cf03140SWeining Lu; CHECK-NEXT:    addi.d $sp, $sp, -80
1242cf03140SWeining Lu; CHECK-NEXT:    st.d $ra, $sp, 72 # 8-byte Folded Spill
1252cf03140SWeining Lu; CHECK-NEXT:    st.d $zero, $sp, 24
126*1897bf61SAmi-zhang; CHECK-NEXT:    vrepli.b $vr0, 0
127*1897bf61SAmi-zhang; CHECK-NEXT:    vst $vr0, $sp, 8
128a5c90e48Swanglei; CHECK-NEXT:    ori $a0, $zero, 2
129a5c90e48Swanglei; CHECK-NEXT:    st.d $a0, $sp, 0
1302cf03140SWeining Lu; CHECK-NEXT:    st.d $zero, $sp, 56
131*1897bf61SAmi-zhang; CHECK-NEXT:    vst $vr0, $sp, 40
132a5c90e48Swanglei; CHECK-NEXT:    ori $a2, $zero, 1
1332cf03140SWeining Lu; CHECK-NEXT:    addi.d $a0, $sp, 32
1342cf03140SWeining Lu; CHECK-NEXT:    addi.d $a1, $sp, 0
135a5c90e48Swanglei; CHECK-NEXT:    st.d $a2, $sp, 32
1362cf03140SWeining Lu; CHECK-NEXT:    bl %plt(callee_large_scalars)
1372cf03140SWeining Lu; CHECK-NEXT:    ld.d $ra, $sp, 72 # 8-byte Folded Reload
1382cf03140SWeining Lu; CHECK-NEXT:    addi.d $sp, $sp, 80
1392cf03140SWeining Lu; CHECK-NEXT:    ret
1402cf03140SWeining Lu  %1 = call i64 @callee_large_scalars(i256 1, i256 2)
1412cf03140SWeining Lu  ret i64 %1
1422cf03140SWeining Lu}
1432cf03140SWeining Lu
1442cf03140SWeining Lu;; Check that arguments larger than 2*GRLen are handled correctly when their
1452cf03140SWeining Lu;; address is passed on the stack rather than in memory.
1462cf03140SWeining Lu
1472cf03140SWeining Lu;; Must keep define on a single line due to an update_llc_test_checks.py limitation
1482cf03140SWeining Ludefine i64 @callee_large_scalars_exhausted_regs(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, i64 %f, i64 %g, i256 %h, i64 %i, i256 %j) nounwind {
1492cf03140SWeining Lu; CHECK-LABEL: callee_large_scalars_exhausted_regs:
1502cf03140SWeining Lu; CHECK:       # %bb.0:
1512cf03140SWeining Lu; CHECK-NEXT:    ld.d $a0, $sp, 8
152a5c90e48Swanglei; CHECK-NEXT:    ld.d $a1, $a0, 0
153a5c90e48Swanglei; CHECK-NEXT:    ld.d $a2, $a7, 0
154a5c90e48Swanglei; CHECK-NEXT:    ld.d $a3, $a0, 8
155a5c90e48Swanglei; CHECK-NEXT:    ld.d $a4, $a0, 24
156a5c90e48Swanglei; CHECK-NEXT:    ld.d $a5, $a7, 24
157a5c90e48Swanglei; CHECK-NEXT:    ld.d $a6, $a7, 8
158a5c90e48Swanglei; CHECK-NEXT:    ld.d $a0, $a0, 16
159a5c90e48Swanglei; CHECK-NEXT:    ld.d $a7, $a7, 16
160a5c90e48Swanglei; CHECK-NEXT:    xor $a4, $a5, $a4
161a5c90e48Swanglei; CHECK-NEXT:    xor $a3, $a6, $a3
162a5c90e48Swanglei; CHECK-NEXT:    or $a3, $a3, $a4
163a5c90e48Swanglei; CHECK-NEXT:    xor $a0, $a7, $a0
1642cf03140SWeining Lu; CHECK-NEXT:    xor $a1, $a2, $a1
165a5c90e48Swanglei; CHECK-NEXT:    or $a0, $a1, $a0
166a5c90e48Swanglei; CHECK-NEXT:    or $a0, $a0, $a3
1672cf03140SWeining Lu; CHECK-NEXT:    sltui $a0, $a0, 1
1682cf03140SWeining Lu; CHECK-NEXT:    ret
1692cf03140SWeining Lu  %1 = icmp eq i256 %h, %j
1702cf03140SWeining Lu  %2 = zext i1 %1 to i64
1712cf03140SWeining Lu  ret i64 %2
1722cf03140SWeining Lu}
1732cf03140SWeining Lu
1742cf03140SWeining Ludefine i64 @caller_large_scalars_exhausted_regs() nounwind {
1752cf03140SWeining Lu; CHECK-LABEL: caller_large_scalars_exhausted_regs:
1762cf03140SWeining Lu; CHECK:       # %bb.0:
1772cf03140SWeining Lu; CHECK-NEXT:    addi.d $sp, $sp, -96
1782cf03140SWeining Lu; CHECK-NEXT:    st.d $ra, $sp, 88 # 8-byte Folded Spill
1792cf03140SWeining Lu; CHECK-NEXT:    addi.d $a0, $sp, 16
1802cf03140SWeining Lu; CHECK-NEXT:    st.d $a0, $sp, 8
1812cf03140SWeining Lu; CHECK-NEXT:    ori $a0, $zero, 9
1822cf03140SWeining Lu; CHECK-NEXT:    st.d $a0, $sp, 0
1832cf03140SWeining Lu; CHECK-NEXT:    st.d $zero, $sp, 40
184*1897bf61SAmi-zhang; CHECK-NEXT:    vrepli.b $vr0, 0
185*1897bf61SAmi-zhang; CHECK-NEXT:    vst $vr0, $sp, 24
186a5c90e48Swanglei; CHECK-NEXT:    ori $a0, $zero, 10
187a5c90e48Swanglei; CHECK-NEXT:    st.d $a0, $sp, 16
1882cf03140SWeining Lu; CHECK-NEXT:    st.d $zero, $sp, 72
189*1897bf61SAmi-zhang; CHECK-NEXT:    ori $a0, $zero, 8
190*1897bf61SAmi-zhang; CHECK-NEXT:    st.d $a0, $sp, 48
1912cf03140SWeining Lu; CHECK-NEXT:    ori $a0, $zero, 1
1922cf03140SWeining Lu; CHECK-NEXT:    ori $a1, $zero, 2
1932cf03140SWeining Lu; CHECK-NEXT:    ori $a2, $zero, 3
1942cf03140SWeining Lu; CHECK-NEXT:    ori $a3, $zero, 4
1952cf03140SWeining Lu; CHECK-NEXT:    ori $a4, $zero, 5
1962cf03140SWeining Lu; CHECK-NEXT:    ori $a5, $zero, 6
1972cf03140SWeining Lu; CHECK-NEXT:    ori $a6, $zero, 7
1982cf03140SWeining Lu; CHECK-NEXT:    addi.d $a7, $sp, 48
199*1897bf61SAmi-zhang; CHECK-NEXT:    vst $vr0, $sp, 56
2002cf03140SWeining Lu; CHECK-NEXT:    bl %plt(callee_large_scalars_exhausted_regs)
2012cf03140SWeining Lu; CHECK-NEXT:    ld.d $ra, $sp, 88 # 8-byte Folded Reload
2022cf03140SWeining Lu; CHECK-NEXT:    addi.d $sp, $sp, 96
2032cf03140SWeining Lu; CHECK-NEXT:    ret
2042cf03140SWeining Lu  %1 = call i64 @callee_large_scalars_exhausted_regs(
2052cf03140SWeining Lu      i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i256 8, i64 9,
2062cf03140SWeining Lu      i256 10)
2072cf03140SWeining Lu  ret i64 %1
2082cf03140SWeining Lu}
2092cf03140SWeining Lu
2102cf03140SWeining Lu;; Check large struct arguments, which are passed byval
2112cf03140SWeining Lu
2122cf03140SWeining Lu%struct.large = type { i64, i64, i64, i64 }
2132cf03140SWeining Lu
2142cf03140SWeining Ludefine i64 @callee_large_struct(ptr byval(%struct.large) align 8 %a) nounwind {
2152cf03140SWeining Lu; CHECK-LABEL: callee_large_struct:
2162cf03140SWeining Lu; CHECK:       # %bb.0:
217a5c90e48Swanglei; CHECK-NEXT:    ld.d $a1, $a0, 0
218a5c90e48Swanglei; CHECK-NEXT:    ld.d $a0, $a0, 24
219a5c90e48Swanglei; CHECK-NEXT:    add.d $a0, $a1, $a0
2202cf03140SWeining Lu; CHECK-NEXT:    ret
2212cf03140SWeining Lu  %1 = getelementptr inbounds %struct.large, ptr %a, i64 0, i32 0
2222cf03140SWeining Lu  %2 = getelementptr inbounds %struct.large, ptr %a, i64 0, i32 3
2232cf03140SWeining Lu  %3 = load i64, ptr %1
2242cf03140SWeining Lu  %4 = load i64, ptr %2
2252cf03140SWeining Lu  %5 = add i64 %3, %4
2262cf03140SWeining Lu  ret i64 %5
2272cf03140SWeining Lu}
2282cf03140SWeining Lu
2292cf03140SWeining Ludefine i64 @caller_large_struct() nounwind {
2302cf03140SWeining Lu; CHECK-LABEL: caller_large_struct:
2312cf03140SWeining Lu; CHECK:       # %bb.0:
2322cf03140SWeining Lu; CHECK-NEXT:    addi.d $sp, $sp, -80
2332cf03140SWeining Lu; CHECK-NEXT:    st.d $ra, $sp, 72 # 8-byte Folded Spill
2342cf03140SWeining Lu; CHECK-NEXT:    ori $a0, $zero, 1
2352cf03140SWeining Lu; CHECK-NEXT:    st.d $a0, $sp, 40
236a5c90e48Swanglei; CHECK-NEXT:    ori $a1, $zero, 2
237a5c90e48Swanglei; CHECK-NEXT:    st.d $a1, $sp, 48
238a5c90e48Swanglei; CHECK-NEXT:    ori $a2, $zero, 3
239a5c90e48Swanglei; CHECK-NEXT:    st.d $a2, $sp, 56
240a5c90e48Swanglei; CHECK-NEXT:    ori $a3, $zero, 4
241a5c90e48Swanglei; CHECK-NEXT:    st.d $a3, $sp, 64
2422cf03140SWeining Lu; CHECK-NEXT:    st.d $a0, $sp, 8
243a5c90e48Swanglei; CHECK-NEXT:    st.d $a1, $sp, 16
244a5c90e48Swanglei; CHECK-NEXT:    st.d $a2, $sp, 24
245a5c90e48Swanglei; CHECK-NEXT:    st.d $a3, $sp, 32
2462cf03140SWeining Lu; CHECK-NEXT:    addi.d $a0, $sp, 8
2472cf03140SWeining Lu; CHECK-NEXT:    bl %plt(callee_large_struct)
2482cf03140SWeining Lu; CHECK-NEXT:    ld.d $ra, $sp, 72 # 8-byte Folded Reload
2492cf03140SWeining Lu; CHECK-NEXT:    addi.d $sp, $sp, 80
2502cf03140SWeining Lu; CHECK-NEXT:    ret
2512cf03140SWeining Lu  %ls = alloca %struct.large, align 8
2522cf03140SWeining Lu  %a = getelementptr inbounds %struct.large, ptr %ls, i64 0, i32 0
2532cf03140SWeining Lu  store i64 1, ptr %a
2542cf03140SWeining Lu  %b = getelementptr inbounds %struct.large, ptr %ls, i64 0, i32 1
2552cf03140SWeining Lu  store i64 2, ptr %b
2562cf03140SWeining Lu  %c = getelementptr inbounds %struct.large, ptr %ls, i64 0, i32 2
2572cf03140SWeining Lu  store i64 3, ptr %c
2582cf03140SWeining Lu  %d = getelementptr inbounds %struct.large, ptr %ls, i64 0, i32 3
2592cf03140SWeining Lu  store i64 4, ptr %d
2602cf03140SWeining Lu  %1 = call i64 @callee_large_struct(ptr byval(%struct.large) align 8 %ls)
2612cf03140SWeining Lu  ret i64 %1
2622cf03140SWeining Lu}
2632cf03140SWeining Lu
2642cf03140SWeining Lu;; Check return scalar which size is 2*GRLen.
2652cf03140SWeining Lu
2662cf03140SWeining Ludefine i128 @callee_small_scalar_ret() nounwind {
2672cf03140SWeining Lu; CHECK-LABEL: callee_small_scalar_ret:
2682cf03140SWeining Lu; CHECK:       # %bb.0:
2692cf03140SWeining Lu; CHECK-NEXT:    addi.w $a0, $zero, -1
2702cf03140SWeining Lu; CHECK-NEXT:    move $a1, $a0
2712cf03140SWeining Lu; CHECK-NEXT:    ret
2722cf03140SWeining Lu  ret i128 -1
2732cf03140SWeining Lu}
2742cf03140SWeining Lu
2752cf03140SWeining Ludefine i64 @caller_small_scalar_ret() nounwind {
2762cf03140SWeining Lu; CHECK-LABEL: caller_small_scalar_ret:
2772cf03140SWeining Lu; CHECK:       # %bb.0:
2782cf03140SWeining Lu; CHECK-NEXT:    addi.d $sp, $sp, -16
2792cf03140SWeining Lu; CHECK-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
2802cf03140SWeining Lu; CHECK-NEXT:    bl %plt(callee_small_scalar_ret)
2812cf03140SWeining Lu; CHECK-NEXT:    addi.w $a2, $zero, -2
2822cf03140SWeining Lu; CHECK-NEXT:    xor $a0, $a0, $a2
2832cf03140SWeining Lu; CHECK-NEXT:    orn $a0, $a0, $a1
2842cf03140SWeining Lu; CHECK-NEXT:    sltui $a0, $a0, 1
2852cf03140SWeining Lu; CHECK-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
2862cf03140SWeining Lu; CHECK-NEXT:    addi.d $sp, $sp, 16
2872cf03140SWeining Lu; CHECK-NEXT:    ret
2882cf03140SWeining Lu  %1 = call i128 @callee_small_scalar_ret()
2892cf03140SWeining Lu  %2 = icmp eq i128 -2, %1
2902cf03140SWeining Lu  %3 = zext i1 %2 to i64
2912cf03140SWeining Lu  ret i64 %3
2922cf03140SWeining Lu}
2932cf03140SWeining Lu
2942cf03140SWeining Lu;; Check return struct which size is 2*GRLen.
2952cf03140SWeining Lu
2962cf03140SWeining Lu%struct.small = type { i64, ptr }
2972cf03140SWeining Lu
2982cf03140SWeining Ludefine %struct.small @callee_small_struct_ret() nounwind {
2992cf03140SWeining Lu; CHECK-LABEL: callee_small_struct_ret:
3002cf03140SWeining Lu; CHECK:       # %bb.0:
3012cf03140SWeining Lu; CHECK-NEXT:    ori $a0, $zero, 1
3022cf03140SWeining Lu; CHECK-NEXT:    move $a1, $zero
3032cf03140SWeining Lu; CHECK-NEXT:    ret
3042cf03140SWeining Lu  ret %struct.small { i64 1, ptr null }
3052cf03140SWeining Lu}
3062cf03140SWeining Lu
3072cf03140SWeining Ludefine i64 @caller_small_struct_ret() nounwind {
3082cf03140SWeining Lu; CHECK-LABEL: caller_small_struct_ret:
3092cf03140SWeining Lu; CHECK:       # %bb.0:
3102cf03140SWeining Lu; CHECK-NEXT:    addi.d $sp, $sp, -16
3112cf03140SWeining Lu; CHECK-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
3122cf03140SWeining Lu; CHECK-NEXT:    bl %plt(callee_small_struct_ret)
3132cf03140SWeining Lu; CHECK-NEXT:    add.d $a0, $a0, $a1
3142cf03140SWeining Lu; CHECK-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
3152cf03140SWeining Lu; CHECK-NEXT:    addi.d $sp, $sp, 16
3162cf03140SWeining Lu; CHECK-NEXT:    ret
3172cf03140SWeining Lu  %1 = call %struct.small @callee_small_struct_ret()
3182cf03140SWeining Lu  %2 = extractvalue %struct.small %1, 0
3192cf03140SWeining Lu  %3 = extractvalue %struct.small %1, 1
3202cf03140SWeining Lu  %4 = ptrtoint ptr %3 to i64
3212cf03140SWeining Lu  %5 = add i64 %2, %4
3222cf03140SWeining Lu  ret i64 %5
3232cf03140SWeining Lu}
3242cf03140SWeining Lu
3252cf03140SWeining Lu;; Check return scalar which size is more than 2*GRLen.
3262cf03140SWeining Lu
3272cf03140SWeining Ludefine i256 @callee_large_scalar_ret() nounwind {
3282cf03140SWeining Lu; CHECK-LABEL: callee_large_scalar_ret:
3292cf03140SWeining Lu; CHECK:       # %bb.0:
3302cf03140SWeining Lu; CHECK-NEXT:    addi.w $a1, $zero, -1
3312cf03140SWeining Lu; CHECK-NEXT:    st.d $a1, $a0, 24
3322cf03140SWeining Lu; CHECK-NEXT:    st.d $a1, $a0, 16
3332cf03140SWeining Lu; CHECK-NEXT:    st.d $a1, $a0, 8
3342cf03140SWeining Lu; CHECK-NEXT:    lu12i.w $a1, -30141
3352cf03140SWeining Lu; CHECK-NEXT:    ori $a1, $a1, 747
3362cf03140SWeining Lu; CHECK-NEXT:    st.d $a1, $a0, 0
3372cf03140SWeining Lu; CHECK-NEXT:    ret
3382cf03140SWeining Lu  ret i256 -123456789
3392cf03140SWeining Lu}
3402cf03140SWeining Lu
3412cf03140SWeining Ludefine void @caller_large_scalar_ret() nounwind {
3422cf03140SWeining Lu; CHECK-LABEL: caller_large_scalar_ret:
3432cf03140SWeining Lu; CHECK:       # %bb.0:
3442cf03140SWeining Lu; CHECK-NEXT:    addi.d $sp, $sp, -48
3452cf03140SWeining Lu; CHECK-NEXT:    st.d $ra, $sp, 40 # 8-byte Folded Spill
3462cf03140SWeining Lu; CHECK-NEXT:    addi.d $a0, $sp, 0
3472cf03140SWeining Lu; CHECK-NEXT:    bl %plt(callee_large_scalar_ret)
3482cf03140SWeining Lu; CHECK-NEXT:    ld.d $ra, $sp, 40 # 8-byte Folded Reload
3492cf03140SWeining Lu; CHECK-NEXT:    addi.d $sp, $sp, 48
3502cf03140SWeining Lu; CHECK-NEXT:    ret
3512cf03140SWeining Lu  %1 = call i256 @callee_large_scalar_ret()
3522cf03140SWeining Lu  ret void
3532cf03140SWeining Lu}
3542cf03140SWeining Lu
3552cf03140SWeining Lu;; Check return struct which size is more than 2*GRLen.
3562cf03140SWeining Lu
3572cf03140SWeining Ludefine void @callee_large_struct_ret(ptr noalias sret(%struct.large) %agg.result) nounwind {
3582cf03140SWeining Lu; CHECK-LABEL: callee_large_struct_ret:
3592cf03140SWeining Lu; CHECK:       # %bb.0:
3602cf03140SWeining Lu; CHECK-NEXT:    ori $a1, $zero, 1
36147601815SWeining Lu; CHECK-NEXT:    st.d $a1, $a0, 0
362a5c90e48Swanglei; CHECK-NEXT:    ori $a1, $zero, 2
363a5c90e48Swanglei; CHECK-NEXT:    st.d $a1, $a0, 8
364a5c90e48Swanglei; CHECK-NEXT:    ori $a1, $zero, 3
365a5c90e48Swanglei; CHECK-NEXT:    st.d $a1, $a0, 16
366a5c90e48Swanglei; CHECK-NEXT:    ori $a1, $zero, 4
367a5c90e48Swanglei; CHECK-NEXT:    st.d $a1, $a0, 24
3682cf03140SWeining Lu; CHECK-NEXT:    ret
3692cf03140SWeining Lu  %a = getelementptr inbounds %struct.large, ptr %agg.result, i64 0, i32 0
3702cf03140SWeining Lu  store i64 1, ptr %a, align 4
3712cf03140SWeining Lu  %b = getelementptr inbounds %struct.large, ptr %agg.result, i64 0, i32 1
3722cf03140SWeining Lu  store i64 2, ptr %b, align 4
3732cf03140SWeining Lu  %c = getelementptr inbounds %struct.large, ptr %agg.result, i64 0, i32 2
3742cf03140SWeining Lu  store i64 3, ptr %c, align 4
3752cf03140SWeining Lu  %d = getelementptr inbounds %struct.large, ptr %agg.result, i64 0, i32 3
3762cf03140SWeining Lu  store i64 4, ptr %d, align 4
3772cf03140SWeining Lu  ret void
3782cf03140SWeining Lu}
3792cf03140SWeining Lu
3802cf03140SWeining Ludefine i64 @caller_large_struct_ret() nounwind {
3812cf03140SWeining Lu; CHECK-LABEL: caller_large_struct_ret:
3822cf03140SWeining Lu; CHECK:       # %bb.0:
3832cf03140SWeining Lu; CHECK-NEXT:    addi.d $sp, $sp, -48
3842cf03140SWeining Lu; CHECK-NEXT:    st.d $ra, $sp, 40 # 8-byte Folded Spill
3852cf03140SWeining Lu; CHECK-NEXT:    addi.d $a0, $sp, 8
3862cf03140SWeining Lu; CHECK-NEXT:    bl %plt(callee_large_struct_ret)
387a5c90e48Swanglei; CHECK-NEXT:    ld.d $a0, $sp, 8
388a5c90e48Swanglei; CHECK-NEXT:    ld.d $a1, $sp, 32
389a5c90e48Swanglei; CHECK-NEXT:    add.d $a0, $a0, $a1
3902cf03140SWeining Lu; CHECK-NEXT:    ld.d $ra, $sp, 40 # 8-byte Folded Reload
3912cf03140SWeining Lu; CHECK-NEXT:    addi.d $sp, $sp, 48
3922cf03140SWeining Lu; CHECK-NEXT:    ret
3932cf03140SWeining Lu  %1 = alloca %struct.large
3942cf03140SWeining Lu  call void @callee_large_struct_ret(ptr sret(%struct.large) %1)
3952cf03140SWeining Lu  %2 = getelementptr inbounds %struct.large, ptr %1, i64 0, i32 0
3962cf03140SWeining Lu  %3 = load i64, ptr %2
3972cf03140SWeining Lu  %4 = getelementptr inbounds %struct.large, ptr %1, i64 0, i32 3
3982cf03140SWeining Lu  %5 = load i64, ptr %4
3992cf03140SWeining Lu  %6 = add i64 %3, %5
4002cf03140SWeining Lu  ret i64 %6
4012cf03140SWeining Lu}
402