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