brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.8 KiB · f7653af Raw
411 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc --mtriple=loongarch64 --target-abi=lp64s < %s | FileCheck %s3; RUN: llc --mtriple=loongarch64 --mattr=+d --target-abi=lp64d < %s | FileCheck %s4 5;; This file contains tests that should have identical output for all ABIs, i.e.6;; where no arguments are passed via floating point registers.7 8;; Check that on LA64, i128 is passed in a pair of GPRs.9define i64 @callee_i128_in_regs(i64 %a, i128 %b) nounwind {10; CHECK-LABEL: callee_i128_in_regs:11; CHECK:       # %bb.0:12; CHECK-NEXT:    add.d $a0, $a0, $a113; CHECK-NEXT:    ret14  %b_trunc = trunc i128 %b to i6415  %1 = add i64 %a, %b_trunc16  ret i64 %117}18 19define i64 @caller_i128_in_regs() nounwind {20; CHECK-LABEL: caller_i128_in_regs:21; CHECK:       # %bb.0:22; CHECK-NEXT:    addi.d $sp, $sp, -1623; CHECK-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill24; CHECK-NEXT:    ori $a0, $zero, 125; CHECK-NEXT:    ori $a1, $zero, 226; CHECK-NEXT:    move $a2, $zero27; CHECK-NEXT:    pcaddu18i $ra, %call36(callee_i128_in_regs)28; CHECK-NEXT:    jirl $ra, $ra, 029; CHECK-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload30; CHECK-NEXT:    addi.d $sp, $sp, 1631; CHECK-NEXT:    ret32  %1 = call i64 @callee_i128_in_regs(i64 1, i128 2)33  ret i64 %134}35 36;; Check that the stack is used once the GPRs are exhausted.37define i64 @callee_many_scalars(i8 %a, i16 %b, i32 %c, i64 %d, i128 %e, i64 %f, i128 %g, i64 %h) nounwind {38; CHECK-LABEL: callee_many_scalars:39; CHECK:       # %bb.0:40; CHECK-NEXT:    ld.d $t0, $sp, 841; CHECK-NEXT:    ld.d $t1, $sp, 042; CHECK-NEXT:    andi $a0, $a0, 25543; CHECK-NEXT:    bstrpick.d $a1, $a1, 15, 044; CHECK-NEXT:    bstrpick.d $a2, $a2, 31, 045; CHECK-NEXT:    add.d $a0, $a0, $a146; CHECK-NEXT:    add.d $a0, $a0, $a247; CHECK-NEXT:    add.d $a0, $a0, $a348; CHECK-NEXT:    xor $a1, $a5, $t149; CHECK-NEXT:    xor $a2, $a4, $a750; CHECK-NEXT:    or $a1, $a2, $a151; CHECK-NEXT:    sltui $a1, $a1, 152; CHECK-NEXT:    add.d $a0, $a1, $a053; CHECK-NEXT:    add.d $a0, $a0, $a654; CHECK-NEXT:    add.d $a0, $a0, $t055; CHECK-NEXT:    ret56  %a_ext = zext i8 %a to i6457  %b_ext = zext i16 %b to i6458  %c_ext = zext i32 %c to i6459  %1 = add i64 %a_ext, %b_ext60  %2 = add i64 %1, %c_ext61  %3 = add i64 %2, %d62  %4 = icmp eq i128 %e, %g63  %5 = zext i1 %4 to i6464  %6 = add i64 %5, %365  %7 = add i64 %6, %f66  %8 = add i64 %7, %h67  ret i64 %868}69 70define i64 @caller_many_scalars() nounwind {71; CHECK-LABEL: caller_many_scalars:72; CHECK:       # %bb.0:73; CHECK-NEXT:    addi.d $sp, $sp, -3274; CHECK-NEXT:    st.d $ra, $sp, 24 # 8-byte Folded Spill75; CHECK-NEXT:    ori $a0, $zero, 876; CHECK-NEXT:    st.d $a0, $sp, 877; CHECK-NEXT:    ori $a0, $zero, 178; CHECK-NEXT:    ori $a1, $zero, 279; CHECK-NEXT:    ori $a2, $zero, 380; CHECK-NEXT:    ori $a3, $zero, 481; CHECK-NEXT:    ori $a4, $zero, 582; CHECK-NEXT:    ori $a6, $zero, 683; CHECK-NEXT:    ori $a7, $zero, 784; CHECK-NEXT:    st.d $zero, $sp, 085; CHECK-NEXT:    move $a5, $zero86; CHECK-NEXT:    pcaddu18i $ra, %call36(callee_many_scalars)87; CHECK-NEXT:    jirl $ra, $ra, 088; CHECK-NEXT:    ld.d $ra, $sp, 24 # 8-byte Folded Reload89; CHECK-NEXT:    addi.d $sp, $sp, 3290; CHECK-NEXT:    ret91  %1 = call i64 @callee_many_scalars(i8 1, i16 2, i32 3, i64 4, i128 5, i64 6, i128 7, i64 8)92  ret i64 %193}94 95;; Check that i256 is passed indirectly.96 97define i64 @callee_large_scalars(i256 %a, i256 %b) nounwind {98; CHECK-LABEL: callee_large_scalars:99; CHECK:       # %bb.0:100; CHECK-NEXT:    ld.d $a2, $a1, 0101; CHECK-NEXT:    ld.d $a3, $a0, 0102; CHECK-NEXT:    ld.d $a4, $a1, 8103; CHECK-NEXT:    ld.d $a5, $a1, 24104; CHECK-NEXT:    ld.d $a6, $a0, 24105; CHECK-NEXT:    ld.d $a7, $a0, 8106; CHECK-NEXT:    ld.d $a1, $a1, 16107; CHECK-NEXT:    ld.d $a0, $a0, 16108; CHECK-NEXT:    xor $a5, $a6, $a5109; CHECK-NEXT:    xor $a4, $a7, $a4110; CHECK-NEXT:    or $a4, $a4, $a5111; CHECK-NEXT:    xor $a0, $a0, $a1112; CHECK-NEXT:    xor $a1, $a3, $a2113; CHECK-NEXT:    or $a0, $a1, $a0114; CHECK-NEXT:    or $a0, $a0, $a4115; CHECK-NEXT:    sltui $a0, $a0, 1116; CHECK-NEXT:    ret117  %1 = icmp eq i256 %a, %b118  %2 = zext i1 %1 to i64119  ret i64 %2120}121 122define i64 @caller_large_scalars() nounwind {123; CHECK-LABEL: caller_large_scalars:124; CHECK:       # %bb.0:125; CHECK-NEXT:    addi.d $sp, $sp, -96126; CHECK-NEXT:    st.d $ra, $sp, 88 # 8-byte Folded Spill127; CHECK-NEXT:    st.d $zero, $sp, 40128; CHECK-NEXT:    vrepli.b $vr0, 0129; CHECK-NEXT:    vst $vr0, $sp, 24130; CHECK-NEXT:    ori $a0, $zero, 2131; CHECK-NEXT:    st.d $a0, $sp, 16132; CHECK-NEXT:    st.d $zero, $sp, 72133; CHECK-NEXT:    vst $vr0, $sp, 56134; CHECK-NEXT:    ori $a2, $zero, 1135; CHECK-NEXT:    addi.d $a0, $sp, 48136; CHECK-NEXT:    addi.d $a1, $sp, 16137; CHECK-NEXT:    st.d $a2, $sp, 48138; CHECK-NEXT:    pcaddu18i $ra, %call36(callee_large_scalars)139; CHECK-NEXT:    jirl $ra, $ra, 0140; CHECK-NEXT:    ld.d $ra, $sp, 88 # 8-byte Folded Reload141; CHECK-NEXT:    addi.d $sp, $sp, 96142; CHECK-NEXT:    ret143  %1 = call i64 @callee_large_scalars(i256 1, i256 2)144  ret i64 %1145}146 147;; Check that arguments larger than 2*GRLen are handled correctly when their148;; address is passed on the stack rather than in memory.149 150;; Must keep define on a single line due to an update_llc_test_checks.py limitation151define 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 {152; CHECK-LABEL: callee_large_scalars_exhausted_regs:153; CHECK:       # %bb.0:154; CHECK-NEXT:    ld.d $a0, $sp, 8155; CHECK-NEXT:    ld.d $a1, $a0, 0156; CHECK-NEXT:    ld.d $a2, $a7, 0157; CHECK-NEXT:    ld.d $a3, $a0, 8158; CHECK-NEXT:    ld.d $a4, $a0, 24159; CHECK-NEXT:    ld.d $a5, $a7, 24160; CHECK-NEXT:    ld.d $a6, $a7, 8161; CHECK-NEXT:    ld.d $a0, $a0, 16162; CHECK-NEXT:    ld.d $a7, $a7, 16163; CHECK-NEXT:    xor $a4, $a5, $a4164; CHECK-NEXT:    xor $a3, $a6, $a3165; CHECK-NEXT:    or $a3, $a3, $a4166; CHECK-NEXT:    xor $a0, $a7, $a0167; CHECK-NEXT:    xor $a1, $a2, $a1168; CHECK-NEXT:    or $a0, $a1, $a0169; CHECK-NEXT:    or $a0, $a0, $a3170; CHECK-NEXT:    sltui $a0, $a0, 1171; CHECK-NEXT:    ret172  %1 = icmp eq i256 %h, %j173  %2 = zext i1 %1 to i64174  ret i64 %2175}176 177define i64 @caller_large_scalars_exhausted_regs() nounwind {178; CHECK-LABEL: caller_large_scalars_exhausted_regs:179; CHECK:       # %bb.0:180; CHECK-NEXT:    addi.d $sp, $sp, -112181; CHECK-NEXT:    st.d $ra, $sp, 104 # 8-byte Folded Spill182; CHECK-NEXT:    addi.d $a0, $sp, 32183; CHECK-NEXT:    st.d $a0, $sp, 8184; CHECK-NEXT:    ori $a0, $zero, 9185; CHECK-NEXT:    st.d $a0, $sp, 0186; CHECK-NEXT:    st.d $zero, $sp, 56187; CHECK-NEXT:    vrepli.b $vr0, 0188; CHECK-NEXT:    vst $vr0, $sp, 40189; CHECK-NEXT:    ori $a0, $zero, 10190; CHECK-NEXT:    st.d $a0, $sp, 32191; CHECK-NEXT:    st.d $zero, $sp, 88192; CHECK-NEXT:    ori $a0, $zero, 8193; CHECK-NEXT:    st.d $a0, $sp, 64194; CHECK-NEXT:    ori $a0, $zero, 1195; CHECK-NEXT:    ori $a1, $zero, 2196; CHECK-NEXT:    ori $a2, $zero, 3197; CHECK-NEXT:    ori $a3, $zero, 4198; CHECK-NEXT:    ori $a4, $zero, 5199; CHECK-NEXT:    ori $a5, $zero, 6200; CHECK-NEXT:    ori $a6, $zero, 7201; CHECK-NEXT:    addi.d $a7, $sp, 64202; CHECK-NEXT:    vst $vr0, $sp, 72203; CHECK-NEXT:    pcaddu18i $ra, %call36(callee_large_scalars_exhausted_regs)204; CHECK-NEXT:    jirl $ra, $ra, 0205; CHECK-NEXT:    ld.d $ra, $sp, 104 # 8-byte Folded Reload206; CHECK-NEXT:    addi.d $sp, $sp, 112207; CHECK-NEXT:    ret208  %1 = call i64 @callee_large_scalars_exhausted_regs(209      i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i256 8, i64 9,210      i256 10)211  ret i64 %1212}213 214;; Check large struct arguments, which are passed byval215 216%struct.large = type { i64, i64, i64, i64 }217 218define i64 @callee_large_struct(ptr byval(%struct.large) align 8 %a) nounwind {219; CHECK-LABEL: callee_large_struct:220; CHECK:       # %bb.0:221; CHECK-NEXT:    ld.d $a1, $a0, 0222; CHECK-NEXT:    ld.d $a0, $a0, 24223; CHECK-NEXT:    add.d $a0, $a1, $a0224; CHECK-NEXT:    ret225  %1 = getelementptr inbounds %struct.large, ptr %a, i64 0, i32 0226  %2 = getelementptr inbounds %struct.large, ptr %a, i64 0, i32 3227  %3 = load i64, ptr %1228  %4 = load i64, ptr %2229  %5 = add i64 %3, %4230  ret i64 %5231}232 233define i64 @caller_large_struct() nounwind {234; CHECK-LABEL: caller_large_struct:235; CHECK:       # %bb.0:236; CHECK-NEXT:    addi.d $sp, $sp, -80237; CHECK-NEXT:    st.d $ra, $sp, 72 # 8-byte Folded Spill238; CHECK-NEXT:    ori $a0, $zero, 1239; CHECK-NEXT:    st.d $a0, $sp, 40240; CHECK-NEXT:    ori $a1, $zero, 2241; CHECK-NEXT:    st.d $a1, $sp, 48242; CHECK-NEXT:    ori $a2, $zero, 3243; CHECK-NEXT:    st.d $a2, $sp, 56244; CHECK-NEXT:    ori $a3, $zero, 4245; CHECK-NEXT:    st.d $a3, $sp, 64246; CHECK-NEXT:    st.d $a0, $sp, 8247; CHECK-NEXT:    st.d $a1, $sp, 16248; CHECK-NEXT:    st.d $a2, $sp, 24249; CHECK-NEXT:    st.d $a3, $sp, 32250; CHECK-NEXT:    addi.d $a0, $sp, 8251; CHECK-NEXT:    pcaddu18i $ra, %call36(callee_large_struct)252; CHECK-NEXT:    jirl $ra, $ra, 0253; CHECK-NEXT:    ld.d $ra, $sp, 72 # 8-byte Folded Reload254; CHECK-NEXT:    addi.d $sp, $sp, 80255; CHECK-NEXT:    ret256  %ls = alloca %struct.large, align 8257  %a = getelementptr inbounds %struct.large, ptr %ls, i64 0, i32 0258  store i64 1, ptr %a259  %b = getelementptr inbounds %struct.large, ptr %ls, i64 0, i32 1260  store i64 2, ptr %b261  %c = getelementptr inbounds %struct.large, ptr %ls, i64 0, i32 2262  store i64 3, ptr %c263  %d = getelementptr inbounds %struct.large, ptr %ls, i64 0, i32 3264  store i64 4, ptr %d265  %1 = call i64 @callee_large_struct(ptr byval(%struct.large) align 8 %ls)266  ret i64 %1267}268 269;; Check return scalar which size is 2*GRLen.270 271define i128 @callee_small_scalar_ret() nounwind {272; CHECK-LABEL: callee_small_scalar_ret:273; CHECK:       # %bb.0:274; CHECK-NEXT:    addi.w $a0, $zero, -1275; CHECK-NEXT:    move $a1, $a0276; CHECK-NEXT:    ret277  ret i128 -1278}279 280define i64 @caller_small_scalar_ret() nounwind {281; CHECK-LABEL: caller_small_scalar_ret:282; CHECK:       # %bb.0:283; CHECK-NEXT:    addi.d $sp, $sp, -16284; CHECK-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill285; CHECK-NEXT:    pcaddu18i $ra, %call36(callee_small_scalar_ret)286; CHECK-NEXT:    jirl $ra, $ra, 0287; CHECK-NEXT:    addi.w $a2, $zero, -2288; CHECK-NEXT:    xor $a0, $a0, $a2289; CHECK-NEXT:    orn $a0, $a0, $a1290; CHECK-NEXT:    sltui $a0, $a0, 1291; CHECK-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload292; CHECK-NEXT:    addi.d $sp, $sp, 16293; CHECK-NEXT:    ret294  %1 = call i128 @callee_small_scalar_ret()295  %2 = icmp eq i128 -2, %1296  %3 = zext i1 %2 to i64297  ret i64 %3298}299 300;; Check return struct which size is 2*GRLen.301 302%struct.small = type { i64, ptr }303 304define %struct.small @callee_small_struct_ret() nounwind {305; CHECK-LABEL: callee_small_struct_ret:306; CHECK:       # %bb.0:307; CHECK-NEXT:    ori $a0, $zero, 1308; CHECK-NEXT:    move $a1, $zero309; CHECK-NEXT:    ret310  ret %struct.small { i64 1, ptr null }311}312 313define i64 @caller_small_struct_ret() nounwind {314; CHECK-LABEL: caller_small_struct_ret:315; CHECK:       # %bb.0:316; CHECK-NEXT:    addi.d $sp, $sp, -16317; CHECK-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill318; CHECK-NEXT:    pcaddu18i $ra, %call36(callee_small_struct_ret)319; CHECK-NEXT:    jirl $ra, $ra, 0320; CHECK-NEXT:    add.d $a0, $a0, $a1321; CHECK-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload322; CHECK-NEXT:    addi.d $sp, $sp, 16323; CHECK-NEXT:    ret324  %1 = call %struct.small @callee_small_struct_ret()325  %2 = extractvalue %struct.small %1, 0326  %3 = extractvalue %struct.small %1, 1327  %4 = ptrtoint ptr %3 to i64328  %5 = add i64 %2, %4329  ret i64 %5330}331 332;; Check return scalar which size is more than 2*GRLen.333 334define i256 @callee_large_scalar_ret() nounwind {335; CHECK-LABEL: callee_large_scalar_ret:336; CHECK:       # %bb.0:337; CHECK-NEXT:    addi.w $a1, $zero, -1338; CHECK-NEXT:    st.d $a1, $a0, 24339; CHECK-NEXT:    st.d $a1, $a0, 16340; CHECK-NEXT:    st.d $a1, $a0, 8341; CHECK-NEXT:    lu12i.w $a1, -30141342; CHECK-NEXT:    ori $a1, $a1, 747343; CHECK-NEXT:    st.d $a1, $a0, 0344; CHECK-NEXT:    ret345  ret i256 -123456789346}347 348define void @caller_large_scalar_ret() nounwind {349; CHECK-LABEL: caller_large_scalar_ret:350; CHECK:       # %bb.0:351; CHECK-NEXT:    addi.d $sp, $sp, -48352; CHECK-NEXT:    st.d $ra, $sp, 40 # 8-byte Folded Spill353; CHECK-NEXT:    addi.d $a0, $sp, 0354; CHECK-NEXT:    pcaddu18i $ra, %call36(callee_large_scalar_ret)355; CHECK-NEXT:    jirl $ra, $ra, 0356; CHECK-NEXT:    ld.d $ra, $sp, 40 # 8-byte Folded Reload357; CHECK-NEXT:    addi.d $sp, $sp, 48358; CHECK-NEXT:    ret359  %1 = call i256 @callee_large_scalar_ret()360  ret void361}362 363;; Check return struct which size is more than 2*GRLen.364 365define void @callee_large_struct_ret(ptr noalias sret(%struct.large) %agg.result) nounwind {366; CHECK-LABEL: callee_large_struct_ret:367; CHECK:       # %bb.0:368; CHECK-NEXT:    ori $a1, $zero, 1369; CHECK-NEXT:    st.d $a1, $a0, 0370; CHECK-NEXT:    ori $a1, $zero, 2371; CHECK-NEXT:    st.d $a1, $a0, 8372; CHECK-NEXT:    ori $a1, $zero, 3373; CHECK-NEXT:    st.d $a1, $a0, 16374; CHECK-NEXT:    ori $a1, $zero, 4375; CHECK-NEXT:    st.d $a1, $a0, 24376; CHECK-NEXT:    ret377  %a = getelementptr inbounds %struct.large, ptr %agg.result, i64 0, i32 0378  store i64 1, ptr %a, align 4379  %b = getelementptr inbounds %struct.large, ptr %agg.result, i64 0, i32 1380  store i64 2, ptr %b, align 4381  %c = getelementptr inbounds %struct.large, ptr %agg.result, i64 0, i32 2382  store i64 3, ptr %c, align 4383  %d = getelementptr inbounds %struct.large, ptr %agg.result, i64 0, i32 3384  store i64 4, ptr %d, align 4385  ret void386}387 388define i64 @caller_large_struct_ret() nounwind {389; CHECK-LABEL: caller_large_struct_ret:390; CHECK:       # %bb.0:391; CHECK-NEXT:    addi.d $sp, $sp, -48392; CHECK-NEXT:    st.d $ra, $sp, 40 # 8-byte Folded Spill393; CHECK-NEXT:    addi.d $a0, $sp, 8394; CHECK-NEXT:    pcaddu18i $ra, %call36(callee_large_struct_ret)395; CHECK-NEXT:    jirl $ra, $ra, 0396; CHECK-NEXT:    ld.d $a0, $sp, 8397; CHECK-NEXT:    ld.d $a1, $sp, 32398; CHECK-NEXT:    add.d $a0, $a0, $a1399; CHECK-NEXT:    ld.d $ra, $sp, 40 # 8-byte Folded Reload400; CHECK-NEXT:    addi.d $sp, $sp, 48401; CHECK-NEXT:    ret402  %1 = alloca %struct.large403  call void @callee_large_struct_ret(ptr sret(%struct.large) %1)404  %2 = getelementptr inbounds %struct.large, ptr %1, i64 0, i32 0405  %3 = load i64, ptr %2406  %4 = getelementptr inbounds %struct.large, ptr %1, i64 0, i32 3407  %5 = load i64, ptr %4408  %6 = add i64 %3, %5409  ret i64 %6410}411