1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi=ilp32 -verify-machineinstrs < %s \ 3; RUN: | FileCheck -check-prefix=RV32IFD %s 4; RUN: llc -mtriple=riscv32 -mattr=+zdinx -target-abi=ilp32 -verify-machineinstrs < %s \ 5; RUN: | FileCheck -check-prefix=RV32IZFINXZDINX %s 6 7; Basic correctness checks for calling convention lowering for RV32D. This can 8; be somewhat error-prone for soft-float RV32D due to the fact that f64 is legal 9; but i64 is not, and there is no instruction to move values directly between 10; the GPRs and 64-bit FPRs. 11 12define double @callee_double_inreg(double %a, double %b) nounwind { 13; RV32IFD-LABEL: callee_double_inreg: 14; RV32IFD: # %bb.0: 15; RV32IFD-NEXT: addi sp, sp, -16 16; RV32IFD-NEXT: sw a2, 8(sp) 17; RV32IFD-NEXT: sw a3, 12(sp) 18; RV32IFD-NEXT: fld fa5, 8(sp) 19; RV32IFD-NEXT: sw a0, 8(sp) 20; RV32IFD-NEXT: sw a1, 12(sp) 21; RV32IFD-NEXT: fld fa4, 8(sp) 22; RV32IFD-NEXT: fadd.d fa5, fa4, fa5 23; RV32IFD-NEXT: fsd fa5, 8(sp) 24; RV32IFD-NEXT: lw a0, 8(sp) 25; RV32IFD-NEXT: lw a1, 12(sp) 26; RV32IFD-NEXT: addi sp, sp, 16 27; RV32IFD-NEXT: ret 28; 29; RV32IZFINXZDINX-LABEL: callee_double_inreg: 30; RV32IZFINXZDINX: # %bb.0: 31; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a2 32; RV32IZFINXZDINX-NEXT: ret 33 %1 = fadd double %a, %b 34 ret double %1 35} 36 37; TODO: code quality for loading and then passing f64 constants is poor. 38 39define double @caller_double_inreg() nounwind { 40; RV32IFD-LABEL: caller_double_inreg: 41; RV32IFD: # %bb.0: 42; RV32IFD-NEXT: addi sp, sp, -16 43; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 44; RV32IFD-NEXT: lui a0, 262236 45; RV32IFD-NEXT: lui a2, 377487 46; RV32IFD-NEXT: lui a3, 262364 47; RV32IFD-NEXT: addi a1, a0, 655 48; RV32IFD-NEXT: addi a0, a2, 1475 49; RV32IFD-NEXT: addi a3, a3, 655 50; RV32IFD-NEXT: mv a2, a0 51; RV32IFD-NEXT: call callee_double_inreg 52; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 53; RV32IFD-NEXT: addi sp, sp, 16 54; RV32IFD-NEXT: ret 55; 56; RV32IZFINXZDINX-LABEL: caller_double_inreg: 57; RV32IZFINXZDINX: # %bb.0: 58; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 59; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 60; RV32IZFINXZDINX-NEXT: lui a0, 262236 61; RV32IZFINXZDINX-NEXT: lui a2, 377487 62; RV32IZFINXZDINX-NEXT: lui a3, 262364 63; RV32IZFINXZDINX-NEXT: addi a1, a0, 655 64; RV32IZFINXZDINX-NEXT: addi a0, a2, 1475 65; RV32IZFINXZDINX-NEXT: addi a3, a3, 655 66; RV32IZFINXZDINX-NEXT: mv a2, a0 67; RV32IZFINXZDINX-NEXT: call callee_double_inreg 68; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 69; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 70; RV32IZFINXZDINX-NEXT: ret 71 %1 = call double @callee_double_inreg(double 2.720000e+00, double 3.720000e+00) 72 ret double %1 73} 74 75define double @callee_double_split_reg_stack(i32 %a, i64 %b, i64 %c, double %d, double %e) nounwind { 76; RV32IFD-LABEL: callee_double_split_reg_stack: 77; RV32IFD: # %bb.0: 78; RV32IFD-NEXT: addi sp, sp, -16 79; RV32IFD-NEXT: lw a0, 16(sp) 80; RV32IFD-NEXT: sw a7, 8(sp) 81; RV32IFD-NEXT: sw a0, 12(sp) 82; RV32IFD-NEXT: fld fa5, 8(sp) 83; RV32IFD-NEXT: sw a5, 8(sp) 84; RV32IFD-NEXT: sw a6, 12(sp) 85; RV32IFD-NEXT: fld fa4, 8(sp) 86; RV32IFD-NEXT: fadd.d fa5, fa4, fa5 87; RV32IFD-NEXT: fsd fa5, 8(sp) 88; RV32IFD-NEXT: lw a0, 8(sp) 89; RV32IFD-NEXT: lw a1, 12(sp) 90; RV32IFD-NEXT: addi sp, sp, 16 91; RV32IFD-NEXT: ret 92; 93; RV32IZFINXZDINX-LABEL: callee_double_split_reg_stack: 94; RV32IZFINXZDINX: # %bb.0: 95; RV32IZFINXZDINX-NEXT: mv a0, a7 96; RV32IZFINXZDINX-NEXT: lw a1, 0(sp) 97; RV32IZFINXZDINX-NEXT: mv a3, a6 98; RV32IZFINXZDINX-NEXT: mv a2, a5 99; RV32IZFINXZDINX-NEXT: fadd.d a0, a2, a0 100; RV32IZFINXZDINX-NEXT: ret 101 %1 = fadd double %d, %e 102 ret double %1 103} 104 105define double @caller_double_split_reg_stack() nounwind { 106; RV32IFD-LABEL: caller_double_split_reg_stack: 107; RV32IFD: # %bb.0: 108; RV32IFD-NEXT: addi sp, sp, -16 109; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 110; RV32IFD-NEXT: lui a2, 262510 111; RV32IFD-NEXT: lui a3, 262446 112; RV32IFD-NEXT: lui a4, 713032 113; RV32IFD-NEXT: li a0, 1 114; RV32IFD-NEXT: li a1, 2 115; RV32IFD-NEXT: addi a2, a2, 327 116; RV32IFD-NEXT: addi a6, a3, 327 117; RV32IFD-NEXT: addi a5, a4, -1311 118; RV32IFD-NEXT: li a3, 3 119; RV32IFD-NEXT: sw a2, 0(sp) 120; RV32IFD-NEXT: li a2, 0 121; RV32IFD-NEXT: li a4, 0 122; RV32IFD-NEXT: mv a7, a5 123; RV32IFD-NEXT: call callee_double_split_reg_stack 124; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 125; RV32IFD-NEXT: addi sp, sp, 16 126; RV32IFD-NEXT: ret 127; 128; RV32IZFINXZDINX-LABEL: caller_double_split_reg_stack: 129; RV32IZFINXZDINX: # %bb.0: 130; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 131; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 132; RV32IZFINXZDINX-NEXT: lui a2, 262510 133; RV32IZFINXZDINX-NEXT: lui a3, 262446 134; RV32IZFINXZDINX-NEXT: lui a4, 713032 135; RV32IZFINXZDINX-NEXT: li a0, 1 136; RV32IZFINXZDINX-NEXT: li a1, 2 137; RV32IZFINXZDINX-NEXT: addi a2, a2, 327 138; RV32IZFINXZDINX-NEXT: addi a6, a3, 327 139; RV32IZFINXZDINX-NEXT: addi a5, a4, -1311 140; RV32IZFINXZDINX-NEXT: li a3, 3 141; RV32IZFINXZDINX-NEXT: sw a2, 0(sp) 142; RV32IZFINXZDINX-NEXT: li a2, 0 143; RV32IZFINXZDINX-NEXT: li a4, 0 144; RV32IZFINXZDINX-NEXT: mv a7, a5 145; RV32IZFINXZDINX-NEXT: call callee_double_split_reg_stack 146; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 147; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 148; RV32IZFINXZDINX-NEXT: ret 149 %1 = call double @callee_double_split_reg_stack(i32 1, i64 2, i64 3, double 4.72, double 5.72) 150 ret double %1 151} 152 153define double @callee_double_stack(i64 %a, i64 %b, i64 %c, i64 %d, double %e, double %f) nounwind { 154; RV32IFD-LABEL: callee_double_stack: 155; RV32IFD: # %bb.0: 156; RV32IFD-NEXT: addi sp, sp, -16 157; RV32IFD-NEXT: fld fa5, 24(sp) 158; RV32IFD-NEXT: fld fa4, 16(sp) 159; RV32IFD-NEXT: fadd.d fa5, fa4, fa5 160; RV32IFD-NEXT: fsd fa5, 8(sp) 161; RV32IFD-NEXT: lw a0, 8(sp) 162; RV32IFD-NEXT: lw a1, 12(sp) 163; RV32IFD-NEXT: addi sp, sp, 16 164; RV32IFD-NEXT: ret 165; 166; RV32IZFINXZDINX-LABEL: callee_double_stack: 167; RV32IZFINXZDINX: # %bb.0: 168; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) 169; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) 170; RV32IZFINXZDINX-NEXT: lw a2, 0(sp) 171; RV32IZFINXZDINX-NEXT: lw a3, 4(sp) 172; RV32IZFINXZDINX-NEXT: fadd.d a0, a2, a0 173; RV32IZFINXZDINX-NEXT: ret 174 %1 = fadd double %e, %f 175 ret double %1 176} 177 178define double @caller_double_stack() nounwind { 179; RV32IFD-LABEL: caller_double_stack: 180; RV32IFD: # %bb.0: 181; RV32IFD-NEXT: addi sp, sp, -32 182; RV32IFD-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 183; RV32IFD-NEXT: lui a1, 262510 184; RV32IFD-NEXT: lui a3, 713032 185; RV32IFD-NEXT: lui a5, 262574 186; RV32IFD-NEXT: li a0, 1 187; RV32IFD-NEXT: li a2, 2 188; RV32IFD-NEXT: li a4, 3 189; RV32IFD-NEXT: li a6, 4 190; RV32IFD-NEXT: addi a1, a1, 327 191; RV32IFD-NEXT: addi a3, a3, -1311 192; RV32IFD-NEXT: addi a5, a5, 327 193; RV32IFD-NEXT: sw a3, 0(sp) 194; RV32IFD-NEXT: sw a1, 4(sp) 195; RV32IFD-NEXT: sw a3, 8(sp) 196; RV32IFD-NEXT: sw a5, 12(sp) 197; RV32IFD-NEXT: li a1, 0 198; RV32IFD-NEXT: li a3, 0 199; RV32IFD-NEXT: li a5, 0 200; RV32IFD-NEXT: li a7, 0 201; RV32IFD-NEXT: call callee_double_stack 202; RV32IFD-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 203; RV32IFD-NEXT: addi sp, sp, 32 204; RV32IFD-NEXT: ret 205; 206; RV32IZFINXZDINX-LABEL: caller_double_stack: 207; RV32IZFINXZDINX: # %bb.0: 208; RV32IZFINXZDINX-NEXT: addi sp, sp, -32 209; RV32IZFINXZDINX-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 210; RV32IZFINXZDINX-NEXT: lui a1, 262510 211; RV32IZFINXZDINX-NEXT: lui a3, 713032 212; RV32IZFINXZDINX-NEXT: lui a5, 262574 213; RV32IZFINXZDINX-NEXT: li a0, 1 214; RV32IZFINXZDINX-NEXT: li a2, 2 215; RV32IZFINXZDINX-NEXT: li a4, 3 216; RV32IZFINXZDINX-NEXT: li a6, 4 217; RV32IZFINXZDINX-NEXT: addi a1, a1, 327 218; RV32IZFINXZDINX-NEXT: addi a3, a3, -1311 219; RV32IZFINXZDINX-NEXT: addi a5, a5, 327 220; RV32IZFINXZDINX-NEXT: sw a3, 0(sp) 221; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) 222; RV32IZFINXZDINX-NEXT: sw a3, 8(sp) 223; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) 224; RV32IZFINXZDINX-NEXT: li a1, 0 225; RV32IZFINXZDINX-NEXT: li a3, 0 226; RV32IZFINXZDINX-NEXT: li a5, 0 227; RV32IZFINXZDINX-NEXT: li a7, 0 228; RV32IZFINXZDINX-NEXT: call callee_double_stack 229; RV32IZFINXZDINX-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 230; RV32IZFINXZDINX-NEXT: addi sp, sp, 32 231; RV32IZFINXZDINX-NEXT: ret 232 %1 = call double @callee_double_stack(i64 1, i64 2, i64 3, i64 4, double 5.72, double 6.72) 233 ret double %1 234} 235 236define double @func_return_double_undef() nounwind { 237; RV32IFD-LABEL: func_return_double_undef: 238; RV32IFD: # %bb.0: 239; RV32IFD-NEXT: ret 240; 241; RV32IZFINXZDINX-LABEL: func_return_double_undef: 242; RV32IZFINXZDINX: # %bb.0: 243; RV32IZFINXZDINX-NEXT: ret 244 ret double undef 245} 246