1015 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \3; RUN: | FileCheck -check-prefix=RV32I-FPELIM %s4; RUN: llc -mtriple=riscv32 -mattr=+f -target-abi ilp32f \5; RUN: -verify-machineinstrs < %s \6; RUN: | FileCheck -check-prefix=RV32I-FPELIM %s7; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d \8; RUN: -verify-machineinstrs < %s \9; RUN: | FileCheck -check-prefix=RV32I-FPELIM %s10; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all < %s \11; RUN: | FileCheck -check-prefix=RV32I-WITHFP %s12; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all \13; RUN: -mattr=+f -target-abi ilp32f < %s \14; RUN: | FileCheck -check-prefix=RV32I-WITHFP %s15; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all \16; RUN: -mattr=+d -target-abi ilp32d < %s \17; RUN: | FileCheck -check-prefix=RV32I-WITHFP %s18 19; This file contains tests that should have identical output for the ilp32,20; ilp32f, and ilp32d ABIs. i.e. where no arguments are passed according to21; the floating point ABI. As well as calling convention details, we check that22; ra and fp are consistently stored to fp-4 and fp-8.23 24; Check that on RV32, i64 is passed in a pair of registers. Unlike25; the convention for varargs, this need not be an aligned pair.26 27define i32 @callee_i64_in_regs(i32 %a, i64 %b) nounwind {28; RV32I-FPELIM-LABEL: callee_i64_in_regs:29; RV32I-FPELIM: # %bb.0:30; RV32I-FPELIM-NEXT: add a0, a0, a131; RV32I-FPELIM-NEXT: ret32;33; RV32I-WITHFP-LABEL: callee_i64_in_regs:34; RV32I-WITHFP: # %bb.0:35; RV32I-WITHFP-NEXT: addi sp, sp, -1636; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill37; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill38; RV32I-WITHFP-NEXT: addi s0, sp, 1639; RV32I-WITHFP-NEXT: add a0, a0, a140; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload41; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload42; RV32I-WITHFP-NEXT: addi sp, sp, 1643; RV32I-WITHFP-NEXT: ret44 %b_trunc = trunc i64 %b to i3245 %1 = add i32 %a, %b_trunc46 ret i32 %147}48 49define i32 @caller_i64_in_regs() nounwind {50; RV32I-FPELIM-LABEL: caller_i64_in_regs:51; RV32I-FPELIM: # %bb.0:52; RV32I-FPELIM-NEXT: addi sp, sp, -1653; RV32I-FPELIM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill54; RV32I-FPELIM-NEXT: li a0, 155; RV32I-FPELIM-NEXT: li a1, 256; RV32I-FPELIM-NEXT: li a2, 057; RV32I-FPELIM-NEXT: call callee_i64_in_regs58; RV32I-FPELIM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload59; RV32I-FPELIM-NEXT: addi sp, sp, 1660; RV32I-FPELIM-NEXT: ret61;62; RV32I-WITHFP-LABEL: caller_i64_in_regs:63; RV32I-WITHFP: # %bb.0:64; RV32I-WITHFP-NEXT: addi sp, sp, -1665; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill66; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill67; RV32I-WITHFP-NEXT: addi s0, sp, 1668; RV32I-WITHFP-NEXT: li a0, 169; RV32I-WITHFP-NEXT: li a1, 270; RV32I-WITHFP-NEXT: li a2, 071; RV32I-WITHFP-NEXT: call callee_i64_in_regs72; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload73; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload74; RV32I-WITHFP-NEXT: addi sp, sp, 1675; RV32I-WITHFP-NEXT: ret76 %1 = call i32 @callee_i64_in_regs(i32 1, i64 2)77 ret i32 %178}79 80; Check that the stack is used once the GPRs are exhausted81 82define i32 @callee_many_scalars(i8 %a, i16 %b, i32 %c, i64 %d, i32 %e, i32 %f, i64 %g, i32 %h) nounwind {83; RV32I-FPELIM-LABEL: callee_many_scalars:84; RV32I-FPELIM: # %bb.0:85; RV32I-FPELIM-NEXT: lw t0, 4(sp)86; RV32I-FPELIM-NEXT: lw t1, 0(sp)87; RV32I-FPELIM-NEXT: zext.b a0, a088; RV32I-FPELIM-NEXT: slli a1, a1, 1689; RV32I-FPELIM-NEXT: xor a3, a3, a790; RV32I-FPELIM-NEXT: srli a1, a1, 1691; RV32I-FPELIM-NEXT: add a0, a0, a292; RV32I-FPELIM-NEXT: add a0, a0, a193; RV32I-FPELIM-NEXT: add a0, a0, a594; RV32I-FPELIM-NEXT: xor a1, a4, t195; RV32I-FPELIM-NEXT: add a0, a0, a696; RV32I-FPELIM-NEXT: or a1, a3, a197; RV32I-FPELIM-NEXT: seqz a1, a198; RV32I-FPELIM-NEXT: add a0, a0, t099; RV32I-FPELIM-NEXT: add a0, a1, a0100; RV32I-FPELIM-NEXT: ret101;102; RV32I-WITHFP-LABEL: callee_many_scalars:103; RV32I-WITHFP: # %bb.0:104; RV32I-WITHFP-NEXT: addi sp, sp, -16105; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill106; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill107; RV32I-WITHFP-NEXT: addi s0, sp, 16108; RV32I-WITHFP-NEXT: lw t0, 4(s0)109; RV32I-WITHFP-NEXT: lw t1, 0(s0)110; RV32I-WITHFP-NEXT: zext.b a0, a0111; RV32I-WITHFP-NEXT: slli a1, a1, 16112; RV32I-WITHFP-NEXT: xor a3, a3, a7113; RV32I-WITHFP-NEXT: srli a1, a1, 16114; RV32I-WITHFP-NEXT: add a0, a0, a2115; RV32I-WITHFP-NEXT: add a0, a0, a1116; RV32I-WITHFP-NEXT: add a0, a0, a5117; RV32I-WITHFP-NEXT: xor a1, a4, t1118; RV32I-WITHFP-NEXT: add a0, a0, a6119; RV32I-WITHFP-NEXT: or a1, a3, a1120; RV32I-WITHFP-NEXT: seqz a1, a1121; RV32I-WITHFP-NEXT: add a0, a0, t0122; RV32I-WITHFP-NEXT: add a0, a1, a0123; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload124; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload125; RV32I-WITHFP-NEXT: addi sp, sp, 16126; RV32I-WITHFP-NEXT: ret127 %a_ext = zext i8 %a to i32128 %b_ext = zext i16 %b to i32129 %1 = add i32 %a_ext, %b_ext130 %2 = add i32 %1, %c131 %3 = icmp eq i64 %d, %g132 %4 = zext i1 %3 to i32133 %5 = add i32 %4, %2134 %6 = add i32 %5, %e135 %7 = add i32 %6, %f136 %8 = add i32 %7, %h137 ret i32 %8138}139 140define i32 @caller_many_scalars() nounwind {141; RV32I-FPELIM-LABEL: caller_many_scalars:142; RV32I-FPELIM: # %bb.0:143; RV32I-FPELIM-NEXT: addi sp, sp, -16144; RV32I-FPELIM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill145; RV32I-FPELIM-NEXT: li a4, 8146; RV32I-FPELIM-NEXT: li a0, 1147; RV32I-FPELIM-NEXT: li a1, 2148; RV32I-FPELIM-NEXT: li a2, 3149; RV32I-FPELIM-NEXT: li a3, 4150; RV32I-FPELIM-NEXT: li a5, 5151; RV32I-FPELIM-NEXT: li a6, 6152; RV32I-FPELIM-NEXT: li a7, 7153; RV32I-FPELIM-NEXT: sw zero, 0(sp)154; RV32I-FPELIM-NEXT: sw a4, 4(sp)155; RV32I-FPELIM-NEXT: li a4, 0156; RV32I-FPELIM-NEXT: call callee_many_scalars157; RV32I-FPELIM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload158; RV32I-FPELIM-NEXT: addi sp, sp, 16159; RV32I-FPELIM-NEXT: ret160;161; RV32I-WITHFP-LABEL: caller_many_scalars:162; RV32I-WITHFP: # %bb.0:163; RV32I-WITHFP-NEXT: addi sp, sp, -16164; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill165; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill166; RV32I-WITHFP-NEXT: addi s0, sp, 16167; RV32I-WITHFP-NEXT: li a4, 8168; RV32I-WITHFP-NEXT: li a0, 1169; RV32I-WITHFP-NEXT: li a1, 2170; RV32I-WITHFP-NEXT: li a2, 3171; RV32I-WITHFP-NEXT: li a3, 4172; RV32I-WITHFP-NEXT: li a5, 5173; RV32I-WITHFP-NEXT: li a6, 6174; RV32I-WITHFP-NEXT: li a7, 7175; RV32I-WITHFP-NEXT: sw zero, 0(sp)176; RV32I-WITHFP-NEXT: sw a4, 4(sp)177; RV32I-WITHFP-NEXT: li a4, 0178; RV32I-WITHFP-NEXT: call callee_many_scalars179; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload180; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload181; RV32I-WITHFP-NEXT: addi sp, sp, 16182; RV32I-WITHFP-NEXT: ret183 %1 = call i32 @callee_many_scalars(i8 1, i16 2, i32 3, i64 4, i32 5, i32 6, i64 7, i32 8)184 ret i32 %1185}186 187 188; Check that i128 and fp128 are passed indirectly189 190define i32 @callee_large_scalars(i128 %a, fp128 %b) nounwind {191; RV32I-FPELIM-LABEL: callee_large_scalars:192; RV32I-FPELIM: # %bb.0:193; RV32I-FPELIM-NEXT: lw a2, 0(a1)194; RV32I-FPELIM-NEXT: lw a3, 4(a1)195; RV32I-FPELIM-NEXT: lw a4, 8(a1)196; RV32I-FPELIM-NEXT: lw a1, 12(a1)197; RV32I-FPELIM-NEXT: lw a5, 12(a0)198; RV32I-FPELIM-NEXT: lw a6, 4(a0)199; RV32I-FPELIM-NEXT: lw a7, 8(a0)200; RV32I-FPELIM-NEXT: lw a0, 0(a0)201; RV32I-FPELIM-NEXT: xor a1, a5, a1202; RV32I-FPELIM-NEXT: xor a3, a6, a3203; RV32I-FPELIM-NEXT: xor a4, a7, a4204; RV32I-FPELIM-NEXT: xor a0, a0, a2205; RV32I-FPELIM-NEXT: or a1, a3, a1206; RV32I-FPELIM-NEXT: or a0, a0, a4207; RV32I-FPELIM-NEXT: or a0, a0, a1208; RV32I-FPELIM-NEXT: seqz a0, a0209; RV32I-FPELIM-NEXT: ret210;211; RV32I-WITHFP-LABEL: callee_large_scalars:212; RV32I-WITHFP: # %bb.0:213; RV32I-WITHFP-NEXT: addi sp, sp, -16214; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill215; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill216; RV32I-WITHFP-NEXT: addi s0, sp, 16217; RV32I-WITHFP-NEXT: lw a2, 0(a1)218; RV32I-WITHFP-NEXT: lw a3, 4(a1)219; RV32I-WITHFP-NEXT: lw a4, 8(a1)220; RV32I-WITHFP-NEXT: lw a1, 12(a1)221; RV32I-WITHFP-NEXT: lw a5, 12(a0)222; RV32I-WITHFP-NEXT: lw a6, 4(a0)223; RV32I-WITHFP-NEXT: lw a7, 8(a0)224; RV32I-WITHFP-NEXT: lw a0, 0(a0)225; RV32I-WITHFP-NEXT: xor a1, a5, a1226; RV32I-WITHFP-NEXT: xor a3, a6, a3227; RV32I-WITHFP-NEXT: xor a4, a7, a4228; RV32I-WITHFP-NEXT: xor a0, a0, a2229; RV32I-WITHFP-NEXT: or a1, a3, a1230; RV32I-WITHFP-NEXT: or a0, a0, a4231; RV32I-WITHFP-NEXT: or a0, a0, a1232; RV32I-WITHFP-NEXT: seqz a0, a0233; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload234; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload235; RV32I-WITHFP-NEXT: addi sp, sp, 16236; RV32I-WITHFP-NEXT: ret237 %b_bitcast = bitcast fp128 %b to i128238 %1 = icmp eq i128 %a, %b_bitcast239 %2 = zext i1 %1 to i32240 ret i32 %2241}242 243define i32 @caller_large_scalars() nounwind {244; RV32I-FPELIM-LABEL: caller_large_scalars:245; RV32I-FPELIM: # %bb.0:246; RV32I-FPELIM-NEXT: addi sp, sp, -48247; RV32I-FPELIM-NEXT: sw ra, 44(sp) # 4-byte Folded Spill248; RV32I-FPELIM-NEXT: lui a1, 524272249; RV32I-FPELIM-NEXT: li a2, 1250; RV32I-FPELIM-NEXT: addi a0, sp, 24251; RV32I-FPELIM-NEXT: sw zero, 0(sp)252; RV32I-FPELIM-NEXT: sw zero, 4(sp)253; RV32I-FPELIM-NEXT: sw zero, 8(sp)254; RV32I-FPELIM-NEXT: sw a1, 12(sp)255; RV32I-FPELIM-NEXT: mv a1, sp256; RV32I-FPELIM-NEXT: sw a2, 24(sp)257; RV32I-FPELIM-NEXT: sw zero, 28(sp)258; RV32I-FPELIM-NEXT: sw zero, 32(sp)259; RV32I-FPELIM-NEXT: sw zero, 36(sp)260; RV32I-FPELIM-NEXT: call callee_large_scalars261; RV32I-FPELIM-NEXT: lw ra, 44(sp) # 4-byte Folded Reload262; RV32I-FPELIM-NEXT: addi sp, sp, 48263; RV32I-FPELIM-NEXT: ret264;265; RV32I-WITHFP-LABEL: caller_large_scalars:266; RV32I-WITHFP: # %bb.0:267; RV32I-WITHFP-NEXT: addi sp, sp, -48268; RV32I-WITHFP-NEXT: sw ra, 44(sp) # 4-byte Folded Spill269; RV32I-WITHFP-NEXT: sw s0, 40(sp) # 4-byte Folded Spill270; RV32I-WITHFP-NEXT: addi s0, sp, 48271; RV32I-WITHFP-NEXT: lui a1, 524272272; RV32I-WITHFP-NEXT: li a2, 1273; RV32I-WITHFP-NEXT: addi a0, s0, -24274; RV32I-WITHFP-NEXT: sw zero, -48(s0)275; RV32I-WITHFP-NEXT: sw zero, -44(s0)276; RV32I-WITHFP-NEXT: sw zero, -40(s0)277; RV32I-WITHFP-NEXT: sw a1, -36(s0)278; RV32I-WITHFP-NEXT: addi a1, s0, -48279; RV32I-WITHFP-NEXT: sw a2, -24(s0)280; RV32I-WITHFP-NEXT: sw zero, -20(s0)281; RV32I-WITHFP-NEXT: sw zero, -16(s0)282; RV32I-WITHFP-NEXT: sw zero, -12(s0)283; RV32I-WITHFP-NEXT: call callee_large_scalars284; RV32I-WITHFP-NEXT: lw ra, 44(sp) # 4-byte Folded Reload285; RV32I-WITHFP-NEXT: lw s0, 40(sp) # 4-byte Folded Reload286; RV32I-WITHFP-NEXT: addi sp, sp, 48287; RV32I-WITHFP-NEXT: ret288 %1 = call i32 @callee_large_scalars(i128 1, fp128 0xL00000000000000007FFF000000000000)289 ret i32 %1290}291 292; Check that arguments larger than 2*xlen are handled correctly when their293; address is passed on the stack rather than in memory294 295; Must keep define on a single line due to an update_llc_test_checks.py limitation296define i32 @callee_large_scalars_exhausted_regs(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i128 %h, i32 %i, fp128 %j) nounwind {297; RV32I-FPELIM-LABEL: callee_large_scalars_exhausted_regs:298; RV32I-FPELIM: # %bb.0:299; RV32I-FPELIM-NEXT: lw a0, 4(sp)300; RV32I-FPELIM-NEXT: lw a1, 0(a7)301; RV32I-FPELIM-NEXT: lw a2, 4(a7)302; RV32I-FPELIM-NEXT: lw a3, 8(a7)303; RV32I-FPELIM-NEXT: lw a4, 12(a7)304; RV32I-FPELIM-NEXT: lw a5, 12(a0)305; RV32I-FPELIM-NEXT: lw a6, 4(a0)306; RV32I-FPELIM-NEXT: lw a7, 8(a0)307; RV32I-FPELIM-NEXT: lw a0, 0(a0)308; RV32I-FPELIM-NEXT: xor a4, a4, a5309; RV32I-FPELIM-NEXT: xor a2, a2, a6310; RV32I-FPELIM-NEXT: xor a3, a3, a7311; RV32I-FPELIM-NEXT: xor a0, a1, a0312; RV32I-FPELIM-NEXT: or a2, a2, a4313; RV32I-FPELIM-NEXT: or a0, a0, a3314; RV32I-FPELIM-NEXT: or a0, a0, a2315; RV32I-FPELIM-NEXT: seqz a0, a0316; RV32I-FPELIM-NEXT: ret317;318; RV32I-WITHFP-LABEL: callee_large_scalars_exhausted_regs:319; RV32I-WITHFP: # %bb.0:320; RV32I-WITHFP-NEXT: addi sp, sp, -16321; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill322; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill323; RV32I-WITHFP-NEXT: addi s0, sp, 16324; RV32I-WITHFP-NEXT: lw a0, 4(s0)325; RV32I-WITHFP-NEXT: lw a1, 0(a7)326; RV32I-WITHFP-NEXT: lw a2, 4(a7)327; RV32I-WITHFP-NEXT: lw a3, 8(a7)328; RV32I-WITHFP-NEXT: lw a4, 12(a7)329; RV32I-WITHFP-NEXT: lw a5, 12(a0)330; RV32I-WITHFP-NEXT: lw a6, 4(a0)331; RV32I-WITHFP-NEXT: lw a7, 8(a0)332; RV32I-WITHFP-NEXT: lw a0, 0(a0)333; RV32I-WITHFP-NEXT: xor a4, a4, a5334; RV32I-WITHFP-NEXT: xor a2, a2, a6335; RV32I-WITHFP-NEXT: xor a3, a3, a7336; RV32I-WITHFP-NEXT: xor a0, a1, a0337; RV32I-WITHFP-NEXT: or a2, a2, a4338; RV32I-WITHFP-NEXT: or a0, a0, a3339; RV32I-WITHFP-NEXT: or a0, a0, a2340; RV32I-WITHFP-NEXT: seqz a0, a0341; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload342; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload343; RV32I-WITHFP-NEXT: addi sp, sp, 16344; RV32I-WITHFP-NEXT: ret345 %j_bitcast = bitcast fp128 %j to i128346 %1 = icmp eq i128 %h, %j_bitcast347 %2 = zext i1 %1 to i32348 ret i32 %2349}350 351define i32 @caller_large_scalars_exhausted_regs() nounwind {352; RV32I-FPELIM-LABEL: caller_large_scalars_exhausted_regs:353; RV32I-FPELIM: # %bb.0:354; RV32I-FPELIM-NEXT: addi sp, sp, -64355; RV32I-FPELIM-NEXT: sw ra, 60(sp) # 4-byte Folded Spill356; RV32I-FPELIM-NEXT: addi a6, sp, 16357; RV32I-FPELIM-NEXT: li a7, 9358; RV32I-FPELIM-NEXT: lui t0, 524272359; RV32I-FPELIM-NEXT: li t1, 8360; RV32I-FPELIM-NEXT: li a0, 1361; RV32I-FPELIM-NEXT: li a1, 2362; RV32I-FPELIM-NEXT: li a2, 3363; RV32I-FPELIM-NEXT: li a3, 4364; RV32I-FPELIM-NEXT: li a4, 5365; RV32I-FPELIM-NEXT: li a5, 6366; RV32I-FPELIM-NEXT: sw a7, 0(sp)367; RV32I-FPELIM-NEXT: sw a6, 4(sp)368; RV32I-FPELIM-NEXT: li a6, 7369; RV32I-FPELIM-NEXT: sw zero, 16(sp)370; RV32I-FPELIM-NEXT: sw zero, 20(sp)371; RV32I-FPELIM-NEXT: sw zero, 24(sp)372; RV32I-FPELIM-NEXT: sw t0, 28(sp)373; RV32I-FPELIM-NEXT: addi a7, sp, 40374; RV32I-FPELIM-NEXT: sw t1, 40(sp)375; RV32I-FPELIM-NEXT: sw zero, 44(sp)376; RV32I-FPELIM-NEXT: sw zero, 48(sp)377; RV32I-FPELIM-NEXT: sw zero, 52(sp)378; RV32I-FPELIM-NEXT: call callee_large_scalars_exhausted_regs379; RV32I-FPELIM-NEXT: lw ra, 60(sp) # 4-byte Folded Reload380; RV32I-FPELIM-NEXT: addi sp, sp, 64381; RV32I-FPELIM-NEXT: ret382;383; RV32I-WITHFP-LABEL: caller_large_scalars_exhausted_regs:384; RV32I-WITHFP: # %bb.0:385; RV32I-WITHFP-NEXT: addi sp, sp, -64386; RV32I-WITHFP-NEXT: sw ra, 60(sp) # 4-byte Folded Spill387; RV32I-WITHFP-NEXT: sw s0, 56(sp) # 4-byte Folded Spill388; RV32I-WITHFP-NEXT: addi s0, sp, 64389; RV32I-WITHFP-NEXT: addi a6, s0, -48390; RV32I-WITHFP-NEXT: li a7, 9391; RV32I-WITHFP-NEXT: lui t0, 524272392; RV32I-WITHFP-NEXT: li t1, 8393; RV32I-WITHFP-NEXT: li a0, 1394; RV32I-WITHFP-NEXT: li a1, 2395; RV32I-WITHFP-NEXT: li a2, 3396; RV32I-WITHFP-NEXT: li a3, 4397; RV32I-WITHFP-NEXT: li a4, 5398; RV32I-WITHFP-NEXT: li a5, 6399; RV32I-WITHFP-NEXT: sw a7, 0(sp)400; RV32I-WITHFP-NEXT: sw a6, 4(sp)401; RV32I-WITHFP-NEXT: li a6, 7402; RV32I-WITHFP-NEXT: sw zero, -48(s0)403; RV32I-WITHFP-NEXT: sw zero, -44(s0)404; RV32I-WITHFP-NEXT: sw zero, -40(s0)405; RV32I-WITHFP-NEXT: sw t0, -36(s0)406; RV32I-WITHFP-NEXT: addi a7, s0, -24407; RV32I-WITHFP-NEXT: sw t1, -24(s0)408; RV32I-WITHFP-NEXT: sw zero, -20(s0)409; RV32I-WITHFP-NEXT: sw zero, -16(s0)410; RV32I-WITHFP-NEXT: sw zero, -12(s0)411; RV32I-WITHFP-NEXT: call callee_large_scalars_exhausted_regs412; RV32I-WITHFP-NEXT: lw ra, 60(sp) # 4-byte Folded Reload413; RV32I-WITHFP-NEXT: lw s0, 56(sp) # 4-byte Folded Reload414; RV32I-WITHFP-NEXT: addi sp, sp, 64415; RV32I-WITHFP-NEXT: ret416 %1 = call i32 @callee_large_scalars_exhausted_regs(417 i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i128 8, i32 9,418 fp128 0xL00000000000000007FFF000000000000)419 ret i32 %1420}421 422; Ensure that libcalls generated in the middle-end obey the calling convention423 424define i32 @caller_mixed_scalar_libcalls(i64 %a) nounwind {425; RV32I-FPELIM-LABEL: caller_mixed_scalar_libcalls:426; RV32I-FPELIM: # %bb.0:427; RV32I-FPELIM-NEXT: addi sp, sp, -32428; RV32I-FPELIM-NEXT: sw ra, 28(sp) # 4-byte Folded Spill429; RV32I-FPELIM-NEXT: mv a2, a1430; RV32I-FPELIM-NEXT: mv a1, a0431; RV32I-FPELIM-NEXT: addi a0, sp, 8432; RV32I-FPELIM-NEXT: call __floatditf433; RV32I-FPELIM-NEXT: lw a0, 8(sp)434; RV32I-FPELIM-NEXT: lw ra, 28(sp) # 4-byte Folded Reload435; RV32I-FPELIM-NEXT: addi sp, sp, 32436; RV32I-FPELIM-NEXT: ret437;438; RV32I-WITHFP-LABEL: caller_mixed_scalar_libcalls:439; RV32I-WITHFP: # %bb.0:440; RV32I-WITHFP-NEXT: addi sp, sp, -32441; RV32I-WITHFP-NEXT: sw ra, 28(sp) # 4-byte Folded Spill442; RV32I-WITHFP-NEXT: sw s0, 24(sp) # 4-byte Folded Spill443; RV32I-WITHFP-NEXT: addi s0, sp, 32444; RV32I-WITHFP-NEXT: mv a2, a1445; RV32I-WITHFP-NEXT: mv a1, a0446; RV32I-WITHFP-NEXT: addi a0, s0, -24447; RV32I-WITHFP-NEXT: call __floatditf448; RV32I-WITHFP-NEXT: lw a0, -24(s0)449; RV32I-WITHFP-NEXT: lw ra, 28(sp) # 4-byte Folded Reload450; RV32I-WITHFP-NEXT: lw s0, 24(sp) # 4-byte Folded Reload451; RV32I-WITHFP-NEXT: addi sp, sp, 32452; RV32I-WITHFP-NEXT: ret453 %1 = sitofp i64 %a to fp128454 %2 = bitcast fp128 %1 to i128455 %3 = trunc i128 %2 to i32456 ret i32 %3457}458 459; Check passing of coerced integer arrays460 461%struct.small = type { i32, ptr }462 463define i32 @callee_small_coerced_struct([2 x i32] %a.coerce) nounwind {464; RV32I-FPELIM-LABEL: callee_small_coerced_struct:465; RV32I-FPELIM: # %bb.0:466; RV32I-FPELIM-NEXT: xor a0, a0, a1467; RV32I-FPELIM-NEXT: seqz a0, a0468; RV32I-FPELIM-NEXT: ret469;470; RV32I-WITHFP-LABEL: callee_small_coerced_struct:471; RV32I-WITHFP: # %bb.0:472; RV32I-WITHFP-NEXT: addi sp, sp, -16473; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill474; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill475; RV32I-WITHFP-NEXT: addi s0, sp, 16476; RV32I-WITHFP-NEXT: xor a0, a0, a1477; RV32I-WITHFP-NEXT: seqz a0, a0478; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload479; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload480; RV32I-WITHFP-NEXT: addi sp, sp, 16481; RV32I-WITHFP-NEXT: ret482 %1 = extractvalue [2 x i32] %a.coerce, 0483 %2 = extractvalue [2 x i32] %a.coerce, 1484 %3 = icmp eq i32 %1, %2485 %4 = zext i1 %3 to i32486 ret i32 %4487}488 489define i32 @caller_small_coerced_struct() nounwind {490; RV32I-FPELIM-LABEL: caller_small_coerced_struct:491; RV32I-FPELIM: # %bb.0:492; RV32I-FPELIM-NEXT: addi sp, sp, -16493; RV32I-FPELIM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill494; RV32I-FPELIM-NEXT: li a0, 1495; RV32I-FPELIM-NEXT: li a1, 2496; RV32I-FPELIM-NEXT: call callee_small_coerced_struct497; RV32I-FPELIM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload498; RV32I-FPELIM-NEXT: addi sp, sp, 16499; RV32I-FPELIM-NEXT: ret500;501; RV32I-WITHFP-LABEL: caller_small_coerced_struct:502; RV32I-WITHFP: # %bb.0:503; RV32I-WITHFP-NEXT: addi sp, sp, -16504; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill505; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill506; RV32I-WITHFP-NEXT: addi s0, sp, 16507; RV32I-WITHFP-NEXT: li a0, 1508; RV32I-WITHFP-NEXT: li a1, 2509; RV32I-WITHFP-NEXT: call callee_small_coerced_struct510; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload511; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload512; RV32I-WITHFP-NEXT: addi sp, sp, 16513; RV32I-WITHFP-NEXT: ret514 %1 = call i32 @callee_small_coerced_struct([2 x i32] [i32 1, i32 2])515 ret i32 %1516}517 518; Check large struct arguments, which are passed byval519 520%struct.large = type { i32, i32, i32, i32 }521 522define i32 @callee_large_struct(ptr byval(%struct.large) align 4 %a) nounwind {523; RV32I-FPELIM-LABEL: callee_large_struct:524; RV32I-FPELIM: # %bb.0:525; RV32I-FPELIM-NEXT: lw a1, 0(a0)526; RV32I-FPELIM-NEXT: lw a0, 12(a0)527; RV32I-FPELIM-NEXT: add a0, a1, a0528; RV32I-FPELIM-NEXT: ret529;530; RV32I-WITHFP-LABEL: callee_large_struct:531; RV32I-WITHFP: # %bb.0:532; RV32I-WITHFP-NEXT: addi sp, sp, -16533; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill534; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill535; RV32I-WITHFP-NEXT: addi s0, sp, 16536; RV32I-WITHFP-NEXT: lw a1, 0(a0)537; RV32I-WITHFP-NEXT: lw a0, 12(a0)538; RV32I-WITHFP-NEXT: add a0, a1, a0539; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload540; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload541; RV32I-WITHFP-NEXT: addi sp, sp, 16542; RV32I-WITHFP-NEXT: ret543 %1 = getelementptr inbounds %struct.large, ptr %a, i32 0, i32 3544 %2 = load i32, ptr %a545 %3 = load i32, ptr %1546 %4 = add i32 %2, %3547 ret i32 %4548}549 550define i32 @caller_large_struct() nounwind {551; RV32I-FPELIM-LABEL: caller_large_struct:552; RV32I-FPELIM: # %bb.0:553; RV32I-FPELIM-NEXT: addi sp, sp, -48554; RV32I-FPELIM-NEXT: sw ra, 44(sp) # 4-byte Folded Spill555; RV32I-FPELIM-NEXT: li a0, 1556; RV32I-FPELIM-NEXT: li a1, 2557; RV32I-FPELIM-NEXT: li a2, 3558; RV32I-FPELIM-NEXT: li a3, 4559; RV32I-FPELIM-NEXT: sw a0, 24(sp)560; RV32I-FPELIM-NEXT: sw a1, 28(sp)561; RV32I-FPELIM-NEXT: sw a2, 32(sp)562; RV32I-FPELIM-NEXT: sw a3, 36(sp)563; RV32I-FPELIM-NEXT: sw a0, 8(sp)564; RV32I-FPELIM-NEXT: sw a1, 12(sp)565; RV32I-FPELIM-NEXT: sw a2, 16(sp)566; RV32I-FPELIM-NEXT: sw a3, 20(sp)567; RV32I-FPELIM-NEXT: addi a0, sp, 8568; RV32I-FPELIM-NEXT: call callee_large_struct569; RV32I-FPELIM-NEXT: lw ra, 44(sp) # 4-byte Folded Reload570; RV32I-FPELIM-NEXT: addi sp, sp, 48571; RV32I-FPELIM-NEXT: ret572;573; RV32I-WITHFP-LABEL: caller_large_struct:574; RV32I-WITHFP: # %bb.0:575; RV32I-WITHFP-NEXT: addi sp, sp, -48576; RV32I-WITHFP-NEXT: sw ra, 44(sp) # 4-byte Folded Spill577; RV32I-WITHFP-NEXT: sw s0, 40(sp) # 4-byte Folded Spill578; RV32I-WITHFP-NEXT: addi s0, sp, 48579; RV32I-WITHFP-NEXT: li a0, 1580; RV32I-WITHFP-NEXT: li a1, 2581; RV32I-WITHFP-NEXT: li a2, 3582; RV32I-WITHFP-NEXT: li a3, 4583; RV32I-WITHFP-NEXT: sw a0, -24(s0)584; RV32I-WITHFP-NEXT: sw a1, -20(s0)585; RV32I-WITHFP-NEXT: sw a2, -16(s0)586; RV32I-WITHFP-NEXT: sw a3, -12(s0)587; RV32I-WITHFP-NEXT: sw a0, -40(s0)588; RV32I-WITHFP-NEXT: sw a1, -36(s0)589; RV32I-WITHFP-NEXT: sw a2, -32(s0)590; RV32I-WITHFP-NEXT: sw a3, -28(s0)591; RV32I-WITHFP-NEXT: addi a0, s0, -40592; RV32I-WITHFP-NEXT: call callee_large_struct593; RV32I-WITHFP-NEXT: lw ra, 44(sp) # 4-byte Folded Reload594; RV32I-WITHFP-NEXT: lw s0, 40(sp) # 4-byte Folded Reload595; RV32I-WITHFP-NEXT: addi sp, sp, 48596; RV32I-WITHFP-NEXT: ret597 %ls = alloca %struct.large, align 8598 store i32 1, ptr %ls599 %b = getelementptr inbounds %struct.large, ptr %ls, i32 0, i32 1600 store i32 2, ptr %b601 %c = getelementptr inbounds %struct.large, ptr %ls, i32 0, i32 2602 store i32 3, ptr %c603 %d = getelementptr inbounds %struct.large, ptr %ls, i32 0, i32 3604 store i32 4, ptr %d605 %1 = call i32 @callee_large_struct(ptr byval(%struct.large) align 4 %ls)606 ret i32 %1607}608 609; Check 2x*xlen values are aligned appropriately when passed on the stack610; Must keep define on a single line due to an update_llc_test_checks.py limitation611define i32 @callee_aligned_stack(i32 %a, i32 %b, fp128 %c, i32 %d, i32 %e, i64 %f, i32 %g, i32 %h, i64 %i, i32 %j, [2 x i32] %k) nounwind {612; The i64 should be 8-byte aligned on the stack, but the two-element array613; should only be 4-byte aligned614; RV32I-FPELIM-LABEL: callee_aligned_stack:615; RV32I-FPELIM: # %bb.0:616; RV32I-FPELIM-NEXT: lw a0, 0(a2)617; RV32I-FPELIM-NEXT: lw a1, 8(sp)618; RV32I-FPELIM-NEXT: lw a2, 0(sp)619; RV32I-FPELIM-NEXT: lw a3, 20(sp)620; RV32I-FPELIM-NEXT: lw a4, 16(sp)621; RV32I-FPELIM-NEXT: add a0, a0, a7622; RV32I-FPELIM-NEXT: add a1, a2, a1623; RV32I-FPELIM-NEXT: add a0, a0, a1624; RV32I-FPELIM-NEXT: add a3, a4, a3625; RV32I-FPELIM-NEXT: add a0, a0, a3626; RV32I-FPELIM-NEXT: ret627;628; RV32I-WITHFP-LABEL: callee_aligned_stack:629; RV32I-WITHFP: # %bb.0:630; RV32I-WITHFP-NEXT: addi sp, sp, -16631; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill632; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill633; RV32I-WITHFP-NEXT: addi s0, sp, 16634; RV32I-WITHFP-NEXT: lw a0, 0(a2)635; RV32I-WITHFP-NEXT: lw a1, 8(s0)636; RV32I-WITHFP-NEXT: lw a2, 0(s0)637; RV32I-WITHFP-NEXT: lw a3, 20(s0)638; RV32I-WITHFP-NEXT: lw a4, 16(s0)639; RV32I-WITHFP-NEXT: add a0, a0, a7640; RV32I-WITHFP-NEXT: add a1, a2, a1641; RV32I-WITHFP-NEXT: add a0, a0, a1642; RV32I-WITHFP-NEXT: add a3, a4, a3643; RV32I-WITHFP-NEXT: add a0, a0, a3644; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload645; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload646; RV32I-WITHFP-NEXT: addi sp, sp, 16647; RV32I-WITHFP-NEXT: ret648 %1 = bitcast fp128 %c to i128649 %2 = trunc i128 %1 to i32650 %3 = add i32 %2, %g651 %4 = add i32 %3, %h652 %5 = trunc i64 %i to i32653 %6 = add i32 %4, %5654 %7 = add i32 %6, %j655 %8 = extractvalue [2 x i32] %k, 0656 %9 = add i32 %7, %8657 ret i32 %9658}659 660define void @caller_aligned_stack() nounwind {661; The i64 should be 8-byte aligned on the stack, but the two-element array662; should only be 4-byte aligned663; RV32I-FPELIM-LABEL: caller_aligned_stack:664; RV32I-FPELIM: # %bb.0:665; RV32I-FPELIM-NEXT: addi sp, sp, -64666; RV32I-FPELIM-NEXT: sw ra, 60(sp) # 4-byte Folded Spill667; RV32I-FPELIM-NEXT: li a5, 19668; RV32I-FPELIM-NEXT: li a6, 18669; RV32I-FPELIM-NEXT: li a7, 17670; RV32I-FPELIM-NEXT: li t0, 16671; RV32I-FPELIM-NEXT: li t1, 15672; RV32I-FPELIM-NEXT: lui t2, 262153673; RV32I-FPELIM-NEXT: lui t3, 545260674; RV32I-FPELIM-NEXT: lui t4, 964690675; RV32I-FPELIM-NEXT: lui t5, 335544676; RV32I-FPELIM-NEXT: lui t6, 688509677; RV32I-FPELIM-NEXT: li a0, 1678; RV32I-FPELIM-NEXT: li a1, 11679; RV32I-FPELIM-NEXT: addi a2, sp, 32680; RV32I-FPELIM-NEXT: li a3, 12681; RV32I-FPELIM-NEXT: li a4, 13682; RV32I-FPELIM-NEXT: sw a6, 20(sp)683; RV32I-FPELIM-NEXT: sw a5, 24(sp)684; RV32I-FPELIM-NEXT: li a6, 4685; RV32I-FPELIM-NEXT: sw t1, 0(sp)686; RV32I-FPELIM-NEXT: sw t0, 8(sp)687; RV32I-FPELIM-NEXT: sw zero, 12(sp)688; RV32I-FPELIM-NEXT: sw a7, 16(sp)689; RV32I-FPELIM-NEXT: li a7, 14690; RV32I-FPELIM-NEXT: addi t0, t2, 491691; RV32I-FPELIM-NEXT: addi t1, t3, -1967692; RV32I-FPELIM-NEXT: addi t2, t4, -328693; RV32I-FPELIM-NEXT: addi t3, t5, 1311694; RV32I-FPELIM-NEXT: addi a5, t6, -2048695; RV32I-FPELIM-NEXT: sw t3, 32(sp)696; RV32I-FPELIM-NEXT: sw t2, 36(sp)697; RV32I-FPELIM-NEXT: sw t1, 40(sp)698; RV32I-FPELIM-NEXT: sw t0, 44(sp)699; RV32I-FPELIM-NEXT: call callee_aligned_stack700; RV32I-FPELIM-NEXT: lw ra, 60(sp) # 4-byte Folded Reload701; RV32I-FPELIM-NEXT: addi sp, sp, 64702; RV32I-FPELIM-NEXT: ret703;704; RV32I-WITHFP-LABEL: caller_aligned_stack:705; RV32I-WITHFP: # %bb.0:706; RV32I-WITHFP-NEXT: addi sp, sp, -64707; RV32I-WITHFP-NEXT: sw ra, 60(sp) # 4-byte Folded Spill708; RV32I-WITHFP-NEXT: sw s0, 56(sp) # 4-byte Folded Spill709; RV32I-WITHFP-NEXT: addi s0, sp, 64710; RV32I-WITHFP-NEXT: li a5, 19711; RV32I-WITHFP-NEXT: li a6, 18712; RV32I-WITHFP-NEXT: li a7, 17713; RV32I-WITHFP-NEXT: li t0, 16714; RV32I-WITHFP-NEXT: li t1, 15715; RV32I-WITHFP-NEXT: lui t2, 262153716; RV32I-WITHFP-NEXT: lui t3, 545260717; RV32I-WITHFP-NEXT: lui t4, 964690718; RV32I-WITHFP-NEXT: lui t5, 335544719; RV32I-WITHFP-NEXT: lui t6, 688509720; RV32I-WITHFP-NEXT: li a0, 1721; RV32I-WITHFP-NEXT: li a1, 11722; RV32I-WITHFP-NEXT: addi a2, s0, -32723; RV32I-WITHFP-NEXT: li a3, 12724; RV32I-WITHFP-NEXT: li a4, 13725; RV32I-WITHFP-NEXT: sw a6, 20(sp)726; RV32I-WITHFP-NEXT: sw a5, 24(sp)727; RV32I-WITHFP-NEXT: li a6, 4728; RV32I-WITHFP-NEXT: sw t1, 0(sp)729; RV32I-WITHFP-NEXT: sw t0, 8(sp)730; RV32I-WITHFP-NEXT: sw zero, 12(sp)731; RV32I-WITHFP-NEXT: sw a7, 16(sp)732; RV32I-WITHFP-NEXT: li a7, 14733; RV32I-WITHFP-NEXT: addi t0, t2, 491734; RV32I-WITHFP-NEXT: addi t1, t3, -1967735; RV32I-WITHFP-NEXT: addi t2, t4, -328736; RV32I-WITHFP-NEXT: addi t3, t5, 1311737; RV32I-WITHFP-NEXT: addi a5, t6, -2048738; RV32I-WITHFP-NEXT: sw t3, -32(s0)739; RV32I-WITHFP-NEXT: sw t2, -28(s0)740; RV32I-WITHFP-NEXT: sw t1, -24(s0)741; RV32I-WITHFP-NEXT: sw t0, -20(s0)742; RV32I-WITHFP-NEXT: call callee_aligned_stack743; RV32I-WITHFP-NEXT: lw ra, 60(sp) # 4-byte Folded Reload744; RV32I-WITHFP-NEXT: lw s0, 56(sp) # 4-byte Folded Reload745; RV32I-WITHFP-NEXT: addi sp, sp, 64746; RV32I-WITHFP-NEXT: ret747 %1 = call i32 @callee_aligned_stack(i32 1, i32 11,748 fp128 0xLEB851EB851EB851F400091EB851EB851, i32 12, i32 13,749 i64 20000000000, i32 14, i32 15, i64 16, i32 17,750 [2 x i32] [i32 18, i32 19])751 ret void752}753 754; Check return of 2x xlen scalars755 756define i64 @callee_small_scalar_ret() nounwind {757; RV32I-FPELIM-LABEL: callee_small_scalar_ret:758; RV32I-FPELIM: # %bb.0:759; RV32I-FPELIM-NEXT: lui a0, 466866760; RV32I-FPELIM-NEXT: addi a0, a0, 1677761; RV32I-FPELIM-NEXT: li a1, 287762; RV32I-FPELIM-NEXT: ret763;764; RV32I-WITHFP-LABEL: callee_small_scalar_ret:765; RV32I-WITHFP: # %bb.0:766; RV32I-WITHFP-NEXT: addi sp, sp, -16767; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill768; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill769; RV32I-WITHFP-NEXT: addi s0, sp, 16770; RV32I-WITHFP-NEXT: lui a0, 466866771; RV32I-WITHFP-NEXT: addi a0, a0, 1677772; RV32I-WITHFP-NEXT: li a1, 287773; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload774; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload775; RV32I-WITHFP-NEXT: addi sp, sp, 16776; RV32I-WITHFP-NEXT: ret777 ret i64 1234567898765778}779 780define i32 @caller_small_scalar_ret() nounwind {781; RV32I-FPELIM-LABEL: caller_small_scalar_ret:782; RV32I-FPELIM: # %bb.0:783; RV32I-FPELIM-NEXT: addi sp, sp, -16784; RV32I-FPELIM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill785; RV32I-FPELIM-NEXT: call callee_small_scalar_ret786; RV32I-FPELIM-NEXT: lui a2, 56787; RV32I-FPELIM-NEXT: addi a2, a2, 580788; RV32I-FPELIM-NEXT: xor a1, a1, a2789; RV32I-FPELIM-NEXT: lui a2, 200614790; RV32I-FPELIM-NEXT: addi a2, a2, 647791; RV32I-FPELIM-NEXT: xor a0, a0, a2792; RV32I-FPELIM-NEXT: or a0, a0, a1793; RV32I-FPELIM-NEXT: seqz a0, a0794; RV32I-FPELIM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload795; RV32I-FPELIM-NEXT: addi sp, sp, 16796; RV32I-FPELIM-NEXT: ret797;798; RV32I-WITHFP-LABEL: caller_small_scalar_ret:799; RV32I-WITHFP: # %bb.0:800; RV32I-WITHFP-NEXT: addi sp, sp, -16801; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill802; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill803; RV32I-WITHFP-NEXT: addi s0, sp, 16804; RV32I-WITHFP-NEXT: call callee_small_scalar_ret805; RV32I-WITHFP-NEXT: lui a2, 56806; RV32I-WITHFP-NEXT: addi a2, a2, 580807; RV32I-WITHFP-NEXT: xor a1, a1, a2808; RV32I-WITHFP-NEXT: lui a2, 200614809; RV32I-WITHFP-NEXT: addi a2, a2, 647810; RV32I-WITHFP-NEXT: xor a0, a0, a2811; RV32I-WITHFP-NEXT: or a0, a0, a1812; RV32I-WITHFP-NEXT: seqz a0, a0813; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload814; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload815; RV32I-WITHFP-NEXT: addi sp, sp, 16816; RV32I-WITHFP-NEXT: ret817 %1 = call i64 @callee_small_scalar_ret()818 %2 = icmp eq i64 987654321234567, %1819 %3 = zext i1 %2 to i32820 ret i32 %3821}822 823; Check return of 2x xlen structs824 825define %struct.small @callee_small_struct_ret() nounwind {826; RV32I-FPELIM-LABEL: callee_small_struct_ret:827; RV32I-FPELIM: # %bb.0:828; RV32I-FPELIM-NEXT: li a0, 1829; RV32I-FPELIM-NEXT: li a1, 0830; RV32I-FPELIM-NEXT: ret831;832; RV32I-WITHFP-LABEL: callee_small_struct_ret:833; RV32I-WITHFP: # %bb.0:834; RV32I-WITHFP-NEXT: addi sp, sp, -16835; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill836; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill837; RV32I-WITHFP-NEXT: addi s0, sp, 16838; RV32I-WITHFP-NEXT: li a0, 1839; RV32I-WITHFP-NEXT: li a1, 0840; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload841; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload842; RV32I-WITHFP-NEXT: addi sp, sp, 16843; RV32I-WITHFP-NEXT: ret844 ret %struct.small { i32 1, ptr null }845}846 847define i32 @caller_small_struct_ret() nounwind {848; RV32I-FPELIM-LABEL: caller_small_struct_ret:849; RV32I-FPELIM: # %bb.0:850; RV32I-FPELIM-NEXT: addi sp, sp, -16851; RV32I-FPELIM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill852; RV32I-FPELIM-NEXT: call callee_small_struct_ret853; RV32I-FPELIM-NEXT: add a0, a0, a1854; RV32I-FPELIM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload855; RV32I-FPELIM-NEXT: addi sp, sp, 16856; RV32I-FPELIM-NEXT: ret857;858; RV32I-WITHFP-LABEL: caller_small_struct_ret:859; RV32I-WITHFP: # %bb.0:860; RV32I-WITHFP-NEXT: addi sp, sp, -16861; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill862; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill863; RV32I-WITHFP-NEXT: addi s0, sp, 16864; RV32I-WITHFP-NEXT: call callee_small_struct_ret865; RV32I-WITHFP-NEXT: add a0, a0, a1866; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload867; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload868; RV32I-WITHFP-NEXT: addi sp, sp, 16869; RV32I-WITHFP-NEXT: ret870 %1 = call %struct.small @callee_small_struct_ret()871 %2 = extractvalue %struct.small %1, 0872 %3 = extractvalue %struct.small %1, 1873 %4 = ptrtoint ptr %3 to i32874 %5 = add i32 %2, %4875 ret i32 %5876}877 878; Check return of >2x xlen scalars879 880define fp128 @callee_large_scalar_ret() nounwind {881; RV32I-FPELIM-LABEL: callee_large_scalar_ret:882; RV32I-FPELIM: # %bb.0:883; RV32I-FPELIM-NEXT: lui a1, 524272884; RV32I-FPELIM-NEXT: sw zero, 0(a0)885; RV32I-FPELIM-NEXT: sw zero, 4(a0)886; RV32I-FPELIM-NEXT: sw zero, 8(a0)887; RV32I-FPELIM-NEXT: sw a1, 12(a0)888; RV32I-FPELIM-NEXT: ret889;890; RV32I-WITHFP-LABEL: callee_large_scalar_ret:891; RV32I-WITHFP: # %bb.0:892; RV32I-WITHFP-NEXT: addi sp, sp, -16893; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill894; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill895; RV32I-WITHFP-NEXT: addi s0, sp, 16896; RV32I-WITHFP-NEXT: lui a1, 524272897; RV32I-WITHFP-NEXT: sw zero, 0(a0)898; RV32I-WITHFP-NEXT: sw zero, 4(a0)899; RV32I-WITHFP-NEXT: sw zero, 8(a0)900; RV32I-WITHFP-NEXT: sw a1, 12(a0)901; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload902; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload903; RV32I-WITHFP-NEXT: addi sp, sp, 16904; RV32I-WITHFP-NEXT: ret905 ret fp128 0xL00000000000000007FFF000000000000906}907 908define void @caller_large_scalar_ret() nounwind {909; RV32I-FPELIM-LABEL: caller_large_scalar_ret:910; RV32I-FPELIM: # %bb.0:911; RV32I-FPELIM-NEXT: addi sp, sp, -32912; RV32I-FPELIM-NEXT: sw ra, 28(sp) # 4-byte Folded Spill913; RV32I-FPELIM-NEXT: mv a0, sp914; RV32I-FPELIM-NEXT: call callee_large_scalar_ret915; RV32I-FPELIM-NEXT: lw ra, 28(sp) # 4-byte Folded Reload916; RV32I-FPELIM-NEXT: addi sp, sp, 32917; RV32I-FPELIM-NEXT: ret918;919; RV32I-WITHFP-LABEL: caller_large_scalar_ret:920; RV32I-WITHFP: # %bb.0:921; RV32I-WITHFP-NEXT: addi sp, sp, -32922; RV32I-WITHFP-NEXT: sw ra, 28(sp) # 4-byte Folded Spill923; RV32I-WITHFP-NEXT: sw s0, 24(sp) # 4-byte Folded Spill924; RV32I-WITHFP-NEXT: addi s0, sp, 32925; RV32I-WITHFP-NEXT: addi a0, s0, -32926; RV32I-WITHFP-NEXT: call callee_large_scalar_ret927; RV32I-WITHFP-NEXT: lw ra, 28(sp) # 4-byte Folded Reload928; RV32I-WITHFP-NEXT: lw s0, 24(sp) # 4-byte Folded Reload929; RV32I-WITHFP-NEXT: addi sp, sp, 32930; RV32I-WITHFP-NEXT: ret931 %1 = call fp128 @callee_large_scalar_ret()932 ret void933}934 935; Check return of >2x xlen structs936 937define void @callee_large_struct_ret(ptr noalias sret(%struct.large) %agg.result) nounwind {938; RV32I-FPELIM-LABEL: callee_large_struct_ret:939; RV32I-FPELIM: # %bb.0:940; RV32I-FPELIM-NEXT: li a1, 1941; RV32I-FPELIM-NEXT: li a2, 2942; RV32I-FPELIM-NEXT: li a3, 3943; RV32I-FPELIM-NEXT: li a4, 4944; RV32I-FPELIM-NEXT: sw a1, 0(a0)945; RV32I-FPELIM-NEXT: sw a2, 4(a0)946; RV32I-FPELIM-NEXT: sw a3, 8(a0)947; RV32I-FPELIM-NEXT: sw a4, 12(a0)948; RV32I-FPELIM-NEXT: ret949;950; RV32I-WITHFP-LABEL: callee_large_struct_ret:951; RV32I-WITHFP: # %bb.0:952; RV32I-WITHFP-NEXT: addi sp, sp, -16953; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill954; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill955; RV32I-WITHFP-NEXT: addi s0, sp, 16956; RV32I-WITHFP-NEXT: li a1, 1957; RV32I-WITHFP-NEXT: li a2, 2958; RV32I-WITHFP-NEXT: li a3, 3959; RV32I-WITHFP-NEXT: li a4, 4960; RV32I-WITHFP-NEXT: sw a1, 0(a0)961; RV32I-WITHFP-NEXT: sw a2, 4(a0)962; RV32I-WITHFP-NEXT: sw a3, 8(a0)963; RV32I-WITHFP-NEXT: sw a4, 12(a0)964; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload965; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload966; RV32I-WITHFP-NEXT: addi sp, sp, 16967; RV32I-WITHFP-NEXT: ret968 store i32 1, ptr %agg.result, align 4969 %b = getelementptr inbounds %struct.large, ptr %agg.result, i32 0, i32 1970 store i32 2, ptr %b, align 4971 %c = getelementptr inbounds %struct.large, ptr %agg.result, i32 0, i32 2972 store i32 3, ptr %c, align 4973 %d = getelementptr inbounds %struct.large, ptr %agg.result, i32 0, i32 3974 store i32 4, ptr %d, align 4975 ret void976}977 978define i32 @caller_large_struct_ret() nounwind {979; RV32I-FPELIM-LABEL: caller_large_struct_ret:980; RV32I-FPELIM: # %bb.0:981; RV32I-FPELIM-NEXT: addi sp, sp, -32982; RV32I-FPELIM-NEXT: sw ra, 28(sp) # 4-byte Folded Spill983; RV32I-FPELIM-NEXT: addi a0, sp, 8984; RV32I-FPELIM-NEXT: call callee_large_struct_ret985; RV32I-FPELIM-NEXT: lw a0, 8(sp)986; RV32I-FPELIM-NEXT: lw a1, 20(sp)987; RV32I-FPELIM-NEXT: add a0, a0, a1988; RV32I-FPELIM-NEXT: lw ra, 28(sp) # 4-byte Folded Reload989; RV32I-FPELIM-NEXT: addi sp, sp, 32990; RV32I-FPELIM-NEXT: ret991;992; RV32I-WITHFP-LABEL: caller_large_struct_ret:993; RV32I-WITHFP: # %bb.0:994; RV32I-WITHFP-NEXT: addi sp, sp, -32995; RV32I-WITHFP-NEXT: sw ra, 28(sp) # 4-byte Folded Spill996; RV32I-WITHFP-NEXT: sw s0, 24(sp) # 4-byte Folded Spill997; RV32I-WITHFP-NEXT: addi s0, sp, 32998; RV32I-WITHFP-NEXT: addi a0, s0, -24999; RV32I-WITHFP-NEXT: call callee_large_struct_ret1000; RV32I-WITHFP-NEXT: lw a0, -24(s0)1001; RV32I-WITHFP-NEXT: lw a1, -12(s0)1002; RV32I-WITHFP-NEXT: add a0, a0, a11003; RV32I-WITHFP-NEXT: lw ra, 28(sp) # 4-byte Folded Reload1004; RV32I-WITHFP-NEXT: lw s0, 24(sp) # 4-byte Folded Reload1005; RV32I-WITHFP-NEXT: addi sp, sp, 321006; RV32I-WITHFP-NEXT: ret1007 %1 = alloca %struct.large1008 call void @callee_large_struct_ret(ptr sret(%struct.large) %1)1009 %2 = load i32, ptr %11010 %3 = getelementptr inbounds %struct.large, ptr %1, i32 0, i32 31011 %4 = load i32, ptr %31012 %5 = add i32 %2, %41013 ret i32 %51014}1015