1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+d \ 3; RUN: -target-abi ilp32d < %s \ 4; RUN: | FileCheck -check-prefix=RV32-ILP32D %s 5 6; This file contains tests that will have differing output for the ilp32 and 7; ilp32f ABIs. 8 9define i32 @callee_double_in_fpr(i32 %a, double %b) nounwind { 10; RV32-ILP32D-LABEL: callee_double_in_fpr: 11; RV32-ILP32D: # %bb.0: 12; RV32-ILP32D-NEXT: fcvt.w.d a1, fa0, rtz 13; RV32-ILP32D-NEXT: add a0, a0, a1 14; RV32-ILP32D-NEXT: ret 15 %b_fptosi = fptosi double %b to i32 16 %1 = add i32 %a, %b_fptosi 17 ret i32 %1 18} 19 20define i32 @caller_double_in_fpr() nounwind { 21; RV32-ILP32D-LABEL: caller_double_in_fpr: 22; RV32-ILP32D: # %bb.0: 23; RV32-ILP32D-NEXT: addi sp, sp, -16 24; RV32-ILP32D-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 25; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI1_0) 26; RV32-ILP32D-NEXT: fld fa0, %lo(.LCPI1_0)(a0) 27; RV32-ILP32D-NEXT: li a0, 1 28; RV32-ILP32D-NEXT: call callee_double_in_fpr 29; RV32-ILP32D-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 30; RV32-ILP32D-NEXT: addi sp, sp, 16 31; RV32-ILP32D-NEXT: ret 32 %1 = call i32 @callee_double_in_fpr(i32 1, double 2.0) 33 ret i32 %1 34} 35 36; Must keep define on a single line due to an update_llc_test_checks.py limitation 37define i32 @callee_double_in_fpr_exhausted_gprs(i64 %a, i64 %b, i64 %c, i64 %d, i32 %e, double %f) nounwind { 38; RV32-ILP32D-LABEL: callee_double_in_fpr_exhausted_gprs: 39; RV32-ILP32D: # %bb.0: 40; RV32-ILP32D-NEXT: lw a0, 0(sp) 41; RV32-ILP32D-NEXT: fcvt.w.d a1, fa0, rtz 42; RV32-ILP32D-NEXT: add a0, a0, a1 43; RV32-ILP32D-NEXT: ret 44 %f_fptosi = fptosi double %f to i32 45 %1 = add i32 %e, %f_fptosi 46 ret i32 %1 47} 48 49define i32 @caller_double_in_fpr_exhausted_gprs() nounwind { 50; RV32-ILP32D-LABEL: caller_double_in_fpr_exhausted_gprs: 51; RV32-ILP32D: # %bb.0: 52; RV32-ILP32D-NEXT: addi sp, sp, -16 53; RV32-ILP32D-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 54; RV32-ILP32D-NEXT: li a1, 5 55; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI3_0) 56; RV32-ILP32D-NEXT: fld fa0, %lo(.LCPI3_0)(a0) 57; RV32-ILP32D-NEXT: li a0, 1 58; RV32-ILP32D-NEXT: li a2, 2 59; RV32-ILP32D-NEXT: li a4, 3 60; RV32-ILP32D-NEXT: li a6, 4 61; RV32-ILP32D-NEXT: sw a1, 0(sp) 62; RV32-ILP32D-NEXT: li a1, 0 63; RV32-ILP32D-NEXT: li a3, 0 64; RV32-ILP32D-NEXT: li a5, 0 65; RV32-ILP32D-NEXT: li a7, 0 66; RV32-ILP32D-NEXT: call callee_double_in_fpr_exhausted_gprs 67; RV32-ILP32D-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 68; RV32-ILP32D-NEXT: addi sp, sp, 16 69; RV32-ILP32D-NEXT: ret 70 %1 = call i32 @callee_double_in_fpr_exhausted_gprs( 71 i64 1, i64 2, i64 3, i64 4, i32 5, double 6.0) 72 ret i32 %1 73} 74 75; Must keep define on a single line due to an update_llc_test_checks.py limitation 76define i32 @callee_double_in_gpr_exhausted_fprs(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i) nounwind { 77; RV32-ILP32D-LABEL: callee_double_in_gpr_exhausted_fprs: 78; RV32-ILP32D: # %bb.0: 79; RV32-ILP32D-NEXT: addi sp, sp, -16 80; RV32-ILP32D-NEXT: sw a0, 8(sp) 81; RV32-ILP32D-NEXT: sw a1, 12(sp) 82; RV32-ILP32D-NEXT: fld fa5, 8(sp) 83; RV32-ILP32D-NEXT: fcvt.w.d a0, fa7, rtz 84; RV32-ILP32D-NEXT: fcvt.w.d a1, fa5, rtz 85; RV32-ILP32D-NEXT: add a0, a0, a1 86; RV32-ILP32D-NEXT: addi sp, sp, 16 87; RV32-ILP32D-NEXT: ret 88 %h_fptosi = fptosi double %h to i32 89 %i_fptosi = fptosi double %i to i32 90 %1 = add i32 %h_fptosi, %i_fptosi 91 ret i32 %1 92} 93 94define i32 @caller_double_in_gpr_exhausted_fprs() nounwind { 95; RV32-ILP32D-LABEL: caller_double_in_gpr_exhausted_fprs: 96; RV32-ILP32D: # %bb.0: 97; RV32-ILP32D-NEXT: addi sp, sp, -16 98; RV32-ILP32D-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 99; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI5_0) 100; RV32-ILP32D-NEXT: lui a1, %hi(.LCPI5_1) 101; RV32-ILP32D-NEXT: fld fa0, %lo(.LCPI5_0)(a0) 102; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI5_2) 103; RV32-ILP32D-NEXT: fld fa1, %lo(.LCPI5_1)(a1) 104; RV32-ILP32D-NEXT: lui a1, %hi(.LCPI5_3) 105; RV32-ILP32D-NEXT: fld fa2, %lo(.LCPI5_2)(a0) 106; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI5_4) 107; RV32-ILP32D-NEXT: fld fa3, %lo(.LCPI5_3)(a1) 108; RV32-ILP32D-NEXT: lui a1, %hi(.LCPI5_5) 109; RV32-ILP32D-NEXT: fld fa4, %lo(.LCPI5_4)(a0) 110; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI5_6) 111; RV32-ILP32D-NEXT: fld fa5, %lo(.LCPI5_5)(a1) 112; RV32-ILP32D-NEXT: lui a1, %hi(.LCPI5_7) 113; RV32-ILP32D-NEXT: fld fa6, %lo(.LCPI5_6)(a0) 114; RV32-ILP32D-NEXT: fld fa7, %lo(.LCPI5_7)(a1) 115; RV32-ILP32D-NEXT: lui a1, 262688 116; RV32-ILP32D-NEXT: li a0, 0 117; RV32-ILP32D-NEXT: call callee_double_in_gpr_exhausted_fprs 118; RV32-ILP32D-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 119; RV32-ILP32D-NEXT: addi sp, sp, 16 120; RV32-ILP32D-NEXT: ret 121 %1 = call i32 @callee_double_in_gpr_exhausted_fprs( 122 double 1.0, double 2.0, double 3.0, double 4.0, double 5.0, double 6.0, 123 double 7.0, double 8.0, double 9.0) 124 ret i32 %1 125} 126 127; Must keep define on a single line due to an update_llc_test_checks.py limitation 128define i32 @callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs(i64 %a, double %b, i64 %c, double %d, i64 %e, double %f, i32 %g, double %h, double %i, double %j, double %k, double %l, double %m) nounwind { 129; RV32-ILP32D-LABEL: callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs: 130; RV32-ILP32D: # %bb.0: 131; RV32-ILP32D-NEXT: addi sp, sp, -16 132; RV32-ILP32D-NEXT: lw a0, 16(sp) 133; RV32-ILP32D-NEXT: sw a7, 8(sp) 134; RV32-ILP32D-NEXT: sw a0, 12(sp) 135; RV32-ILP32D-NEXT: fld fa5, 8(sp) 136; RV32-ILP32D-NEXT: fcvt.w.d a0, fa5, rtz 137; RV32-ILP32D-NEXT: add a0, a6, a0 138; RV32-ILP32D-NEXT: addi sp, sp, 16 139; RV32-ILP32D-NEXT: ret 140 %m_fptosi = fptosi double %m to i32 141 %1 = add i32 %g, %m_fptosi 142 ret i32 %1 143} 144 145define i32 @caller_double_in_gpr_and_stack_almost_exhausted_gprs_fprs() nounwind { 146; RV32-ILP32D-LABEL: caller_double_in_gpr_and_stack_almost_exhausted_gprs_fprs: 147; RV32-ILP32D: # %bb.0: 148; RV32-ILP32D-NEXT: addi sp, sp, -16 149; RV32-ILP32D-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 150; RV32-ILP32D-NEXT: lui a1, 262816 151; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI7_0) 152; RV32-ILP32D-NEXT: lui a2, %hi(.LCPI7_1) 153; RV32-ILP32D-NEXT: lui a3, %hi(.LCPI7_2) 154; RV32-ILP32D-NEXT: lui a4, %hi(.LCPI7_3) 155; RV32-ILP32D-NEXT: lui a5, %hi(.LCPI7_4) 156; RV32-ILP32D-NEXT: lui a6, %hi(.LCPI7_5) 157; RV32-ILP32D-NEXT: lui a7, %hi(.LCPI7_6) 158; RV32-ILP32D-NEXT: fld fa0, %lo(.LCPI7_0)(a0) 159; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI7_7) 160; RV32-ILP32D-NEXT: fld fa1, %lo(.LCPI7_1)(a2) 161; RV32-ILP32D-NEXT: fld fa2, %lo(.LCPI7_2)(a3) 162; RV32-ILP32D-NEXT: fld fa3, %lo(.LCPI7_3)(a4) 163; RV32-ILP32D-NEXT: fld fa4, %lo(.LCPI7_4)(a5) 164; RV32-ILP32D-NEXT: fld fa5, %lo(.LCPI7_5)(a6) 165; RV32-ILP32D-NEXT: fld fa6, %lo(.LCPI7_6)(a7) 166; RV32-ILP32D-NEXT: fld fa7, %lo(.LCPI7_7)(a0) 167; RV32-ILP32D-NEXT: li a0, 1 168; RV32-ILP32D-NEXT: li a2, 3 169; RV32-ILP32D-NEXT: li a4, 5 170; RV32-ILP32D-NEXT: li a6, 7 171; RV32-ILP32D-NEXT: sw a1, 0(sp) 172; RV32-ILP32D-NEXT: li a1, 0 173; RV32-ILP32D-NEXT: li a3, 0 174; RV32-ILP32D-NEXT: li a5, 0 175; RV32-ILP32D-NEXT: li a7, 0 176; RV32-ILP32D-NEXT: call callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs 177; RV32-ILP32D-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 178; RV32-ILP32D-NEXT: addi sp, sp, 16 179; RV32-ILP32D-NEXT: ret 180 %1 = call i32 @callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs( 181 i64 1, double 2.0, i64 3, double 4.0, i64 5, double 6.0, i32 7, double 8.0, 182 double 9.0, double 10.0, double 11.0, double 12.0, double 13.0) 183 ret i32 %1 184} 185 186 187; Must keep define on a single line due to an update_llc_test_checks.py limitation 188define i32 @callee_double_on_stack_exhausted_gprs_fprs(i64 %a, double %b, i64 %c, double %d, i64 %e, double %f, i64 %g, double %h, double %i, double %j, double %k, double %l, double %m) nounwind { 189; RV32-ILP32D-LABEL: callee_double_on_stack_exhausted_gprs_fprs: 190; RV32-ILP32D: # %bb.0: 191; RV32-ILP32D-NEXT: fld fa5, 0(sp) 192; RV32-ILP32D-NEXT: fcvt.w.d a0, fa5, rtz 193; RV32-ILP32D-NEXT: add a0, a6, a0 194; RV32-ILP32D-NEXT: ret 195 %g_trunc = trunc i64 %g to i32 196 %m_fptosi = fptosi double %m to i32 197 %1 = add i32 %g_trunc, %m_fptosi 198 ret i32 %1 199} 200 201define i32 @caller_double_on_stack_exhausted_gprs_fprs() nounwind { 202; RV32-ILP32D-LABEL: caller_double_on_stack_exhausted_gprs_fprs: 203; RV32-ILP32D: # %bb.0: 204; RV32-ILP32D-NEXT: addi sp, sp, -16 205; RV32-ILP32D-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 206; RV32-ILP32D-NEXT: lui a1, 262816 207; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI9_0) 208; RV32-ILP32D-NEXT: lui a2, %hi(.LCPI9_1) 209; RV32-ILP32D-NEXT: lui a3, %hi(.LCPI9_2) 210; RV32-ILP32D-NEXT: lui a4, %hi(.LCPI9_3) 211; RV32-ILP32D-NEXT: lui a5, %hi(.LCPI9_4) 212; RV32-ILP32D-NEXT: lui a6, %hi(.LCPI9_5) 213; RV32-ILP32D-NEXT: lui a7, %hi(.LCPI9_6) 214; RV32-ILP32D-NEXT: fld fa0, %lo(.LCPI9_0)(a0) 215; RV32-ILP32D-NEXT: lui t0, %hi(.LCPI9_7) 216; RV32-ILP32D-NEXT: fld fa1, %lo(.LCPI9_1)(a2) 217; RV32-ILP32D-NEXT: li a0, 1 218; RV32-ILP32D-NEXT: fld fa2, %lo(.LCPI9_2)(a3) 219; RV32-ILP32D-NEXT: fld fa3, %lo(.LCPI9_3)(a4) 220; RV32-ILP32D-NEXT: fld fa4, %lo(.LCPI9_4)(a5) 221; RV32-ILP32D-NEXT: fld fa5, %lo(.LCPI9_5)(a6) 222; RV32-ILP32D-NEXT: fld fa6, %lo(.LCPI9_6)(a7) 223; RV32-ILP32D-NEXT: fld fa7, %lo(.LCPI9_7)(t0) 224; RV32-ILP32D-NEXT: li a2, 3 225; RV32-ILP32D-NEXT: li a4, 5 226; RV32-ILP32D-NEXT: li a6, 7 227; RV32-ILP32D-NEXT: sw zero, 0(sp) 228; RV32-ILP32D-NEXT: sw a1, 4(sp) 229; RV32-ILP32D-NEXT: li a1, 0 230; RV32-ILP32D-NEXT: li a3, 0 231; RV32-ILP32D-NEXT: li a5, 0 232; RV32-ILP32D-NEXT: li a7, 0 233; RV32-ILP32D-NEXT: call callee_double_on_stack_exhausted_gprs_fprs 234; RV32-ILP32D-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 235; RV32-ILP32D-NEXT: addi sp, sp, 16 236; RV32-ILP32D-NEXT: ret 237 %1 = call i32 @callee_double_on_stack_exhausted_gprs_fprs( 238 i64 1, double 2.0, i64 3, double 4.0, i64 5, double 6.0, i64 7, double 8.0, 239 double 9.0, double 10.0, double 11.0, double 12.0, double 13.0) 240 ret i32 %1 241} 242 243define double @callee_double_ret() nounwind { 244; RV32-ILP32D-LABEL: callee_double_ret: 245; RV32-ILP32D: # %bb.0: 246; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI10_0) 247; RV32-ILP32D-NEXT: fld fa0, %lo(.LCPI10_0)(a0) 248; RV32-ILP32D-NEXT: ret 249 ret double 1.0 250} 251 252define i32 @caller_double_ret() nounwind { 253; RV32-ILP32D-LABEL: caller_double_ret: 254; RV32-ILP32D: # %bb.0: 255; RV32-ILP32D-NEXT: addi sp, sp, -16 256; RV32-ILP32D-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 257; RV32-ILP32D-NEXT: call callee_double_ret 258; RV32-ILP32D-NEXT: fsd fa0, 0(sp) 259; RV32-ILP32D-NEXT: lw a0, 0(sp) 260; RV32-ILP32D-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 261; RV32-ILP32D-NEXT: addi sp, sp, 16 262; RV32-ILP32D-NEXT: ret 263 %1 = call double @callee_double_ret() 264 %2 = bitcast double %1 to i64 265 %3 = trunc i64 %2 to i32 266 ret i32 %3 267} 268