1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \ 3; RUN: | FileCheck -check-prefix=RV32IFD %s 4; RUN: llc -mtriple=riscv64 -mattr=+d -verify-machineinstrs < %s \ 5; RUN: | FileCheck -check-prefix=RV64IFD %s 6 7define float @fcvt_s_d(double %a) nounwind { 8; RV32IFD-LABEL: fcvt_s_d: 9; RV32IFD: # %bb.0: 10; RV32IFD-NEXT: addi sp, sp, -16 11; RV32IFD-NEXT: sw a0, 8(sp) 12; RV32IFD-NEXT: sw a1, 12(sp) 13; RV32IFD-NEXT: fld ft0, 8(sp) 14; RV32IFD-NEXT: fcvt.s.d ft0, ft0 15; RV32IFD-NEXT: fmv.x.w a0, ft0 16; RV32IFD-NEXT: addi sp, sp, 16 17; RV32IFD-NEXT: ret 18; 19; RV64IFD-LABEL: fcvt_s_d: 20; RV64IFD: # %bb.0: 21; RV64IFD-NEXT: fmv.d.x ft0, a0 22; RV64IFD-NEXT: fcvt.s.d ft0, ft0 23; RV64IFD-NEXT: fmv.x.w a0, ft0 24; RV64IFD-NEXT: ret 25 %1 = fptrunc double %a to float 26 ret float %1 27} 28 29define double @fcvt_d_s(float %a) nounwind { 30; RV32IFD-LABEL: fcvt_d_s: 31; RV32IFD: # %bb.0: 32; RV32IFD-NEXT: addi sp, sp, -16 33; RV32IFD-NEXT: fmv.w.x ft0, a0 34; RV32IFD-NEXT: fcvt.d.s ft0, ft0 35; RV32IFD-NEXT: fsd ft0, 8(sp) 36; RV32IFD-NEXT: lw a0, 8(sp) 37; RV32IFD-NEXT: lw a1, 12(sp) 38; RV32IFD-NEXT: addi sp, sp, 16 39; RV32IFD-NEXT: ret 40; 41; RV64IFD-LABEL: fcvt_d_s: 42; RV64IFD: # %bb.0: 43; RV64IFD-NEXT: fmv.w.x ft0, a0 44; RV64IFD-NEXT: fcvt.d.s ft0, ft0 45; RV64IFD-NEXT: fmv.x.d a0, ft0 46; RV64IFD-NEXT: ret 47 %1 = fpext float %a to double 48 ret double %1 49} 50 51; For RV64D, fcvt.l.d is semantically equivalent to fcvt.w.d in this case 52; because fptosi will produce poison if the result doesn't fit into an i32. 53define i32 @fcvt_w_d(double %a) nounwind { 54; RV32IFD-LABEL: fcvt_w_d: 55; RV32IFD: # %bb.0: 56; RV32IFD-NEXT: addi sp, sp, -16 57; RV32IFD-NEXT: sw a0, 8(sp) 58; RV32IFD-NEXT: sw a1, 12(sp) 59; RV32IFD-NEXT: fld ft0, 8(sp) 60; RV32IFD-NEXT: fcvt.w.d a0, ft0, rtz 61; RV32IFD-NEXT: addi sp, sp, 16 62; RV32IFD-NEXT: ret 63; 64; RV64IFD-LABEL: fcvt_w_d: 65; RV64IFD: # %bb.0: 66; RV64IFD-NEXT: fmv.d.x ft0, a0 67; RV64IFD-NEXT: fcvt.w.d a0, ft0, rtz 68; RV64IFD-NEXT: ret 69 %1 = fptosi double %a to i32 70 ret i32 %1 71} 72 73define i32 @fcvt_w_d_sat(double %a) nounwind { 74; RV32IFD-LABEL: fcvt_w_d_sat: 75; RV32IFD: # %bb.0: # %start 76; RV32IFD-NEXT: addi sp, sp, -16 77; RV32IFD-NEXT: sw a0, 8(sp) 78; RV32IFD-NEXT: sw a1, 12(sp) 79; RV32IFD-NEXT: fld ft0, 8(sp) 80; RV32IFD-NEXT: feq.d a0, ft0, ft0 81; RV32IFD-NEXT: bnez a0, .LBB3_2 82; RV32IFD-NEXT: # %bb.1: # %start 83; RV32IFD-NEXT: mv a0, zero 84; RV32IFD-NEXT: addi sp, sp, 16 85; RV32IFD-NEXT: ret 86; RV32IFD-NEXT: .LBB3_2: 87; RV32IFD-NEXT: fcvt.w.d a0, ft0, rtz 88; RV32IFD-NEXT: addi sp, sp, 16 89; RV32IFD-NEXT: ret 90; 91; RV64IFD-LABEL: fcvt_w_d_sat: 92; RV64IFD: # %bb.0: # %start 93; RV64IFD-NEXT: fmv.d.x ft0, a0 94; RV64IFD-NEXT: feq.d a0, ft0, ft0 95; RV64IFD-NEXT: bnez a0, .LBB3_2 96; RV64IFD-NEXT: # %bb.1: # %start 97; RV64IFD-NEXT: mv a0, zero 98; RV64IFD-NEXT: ret 99; RV64IFD-NEXT: .LBB3_2: 100; RV64IFD-NEXT: fcvt.w.d a0, ft0, rtz 101; RV64IFD-NEXT: ret 102start: 103 %0 = tail call i32 @llvm.fptosi.sat.i32.f64(double %a) 104 ret i32 %0 105} 106declare i32 @llvm.fptosi.sat.i32.f64(double) 107 108; For RV64D, fcvt.lu.d is semantically equivalent to fcvt.wu.d in this case 109; because fptosi will produce poison if the result doesn't fit into an i32. 110define i32 @fcvt_wu_d(double %a) nounwind { 111; RV32IFD-LABEL: fcvt_wu_d: 112; RV32IFD: # %bb.0: 113; RV32IFD-NEXT: addi sp, sp, -16 114; RV32IFD-NEXT: sw a0, 8(sp) 115; RV32IFD-NEXT: sw a1, 12(sp) 116; RV32IFD-NEXT: fld ft0, 8(sp) 117; RV32IFD-NEXT: fcvt.wu.d a0, ft0, rtz 118; RV32IFD-NEXT: addi sp, sp, 16 119; RV32IFD-NEXT: ret 120; 121; RV64IFD-LABEL: fcvt_wu_d: 122; RV64IFD: # %bb.0: 123; RV64IFD-NEXT: fmv.d.x ft0, a0 124; RV64IFD-NEXT: fcvt.wu.d a0, ft0, rtz 125; RV64IFD-NEXT: ret 126 %1 = fptoui double %a to i32 127 ret i32 %1 128} 129 130; Test where the fptoui has multiple uses, one of which causes a sext to be 131; inserted on RV64. 132define i32 @fcvt_wu_d_multiple_use(double %x, i32* %y) { 133; RV32IFD-LABEL: fcvt_wu_d_multiple_use: 134; RV32IFD: # %bb.0: 135; RV32IFD-NEXT: addi sp, sp, -16 136; RV32IFD-NEXT: .cfi_def_cfa_offset 16 137; RV32IFD-NEXT: sw a0, 8(sp) 138; RV32IFD-NEXT: sw a1, 12(sp) 139; RV32IFD-NEXT: fld ft0, 8(sp) 140; RV32IFD-NEXT: fcvt.wu.d a1, ft0, rtz 141; RV32IFD-NEXT: addi a0, zero, 1 142; RV32IFD-NEXT: beqz a1, .LBB5_2 143; RV32IFD-NEXT: # %bb.1: 144; RV32IFD-NEXT: mv a0, a1 145; RV32IFD-NEXT: .LBB5_2: 146; RV32IFD-NEXT: addi sp, sp, 16 147; RV32IFD-NEXT: ret 148; 149; RV64IFD-LABEL: fcvt_wu_d_multiple_use: 150; RV64IFD: # %bb.0: 151; RV64IFD-NEXT: fmv.d.x ft0, a0 152; RV64IFD-NEXT: fcvt.wu.d a1, ft0, rtz 153; RV64IFD-NEXT: addi a0, zero, 1 154; RV64IFD-NEXT: beqz a1, .LBB5_2 155; RV64IFD-NEXT: # %bb.1: 156; RV64IFD-NEXT: mv a0, a1 157; RV64IFD-NEXT: .LBB5_2: 158; RV64IFD-NEXT: ret 159 %a = fptoui double %x to i32 160 %b = icmp eq i32 %a, 0 161 %c = select i1 %b, i32 1, i32 %a 162 ret i32 %c 163} 164 165define i32 @fcvt_wu_d_sat(double %a) nounwind { 166; RV32IFD-LABEL: fcvt_wu_d_sat: 167; RV32IFD: # %bb.0: # %start 168; RV32IFD-NEXT: addi sp, sp, -16 169; RV32IFD-NEXT: sw a0, 8(sp) 170; RV32IFD-NEXT: sw a1, 12(sp) 171; RV32IFD-NEXT: fld ft0, 8(sp) 172; RV32IFD-NEXT: feq.d a0, ft0, ft0 173; RV32IFD-NEXT: bnez a0, .LBB6_2 174; RV32IFD-NEXT: # %bb.1: # %start 175; RV32IFD-NEXT: mv a0, zero 176; RV32IFD-NEXT: addi sp, sp, 16 177; RV32IFD-NEXT: ret 178; RV32IFD-NEXT: .LBB6_2: 179; RV32IFD-NEXT: fcvt.wu.d a0, ft0, rtz 180; RV32IFD-NEXT: addi sp, sp, 16 181; RV32IFD-NEXT: ret 182; 183; RV64IFD-LABEL: fcvt_wu_d_sat: 184; RV64IFD: # %bb.0: # %start 185; RV64IFD-NEXT: fmv.d.x ft0, a0 186; RV64IFD-NEXT: feq.d a0, ft0, ft0 187; RV64IFD-NEXT: bnez a0, .LBB6_2 188; RV64IFD-NEXT: # %bb.1: # %start 189; RV64IFD-NEXT: mv a0, zero 190; RV64IFD-NEXT: ret 191; RV64IFD-NEXT: .LBB6_2: 192; RV64IFD-NEXT: fcvt.wu.d a0, ft0, rtz 193; RV64IFD-NEXT: ret 194start: 195 %0 = tail call i32 @llvm.fptoui.sat.i32.f64(double %a) 196 ret i32 %0 197} 198declare i32 @llvm.fptoui.sat.i32.f64(double) 199 200define double @fcvt_d_w(i32 %a) nounwind { 201; RV32IFD-LABEL: fcvt_d_w: 202; RV32IFD: # %bb.0: 203; RV32IFD-NEXT: addi sp, sp, -16 204; RV32IFD-NEXT: fcvt.d.w ft0, a0 205; RV32IFD-NEXT: fsd ft0, 8(sp) 206; RV32IFD-NEXT: lw a0, 8(sp) 207; RV32IFD-NEXT: lw a1, 12(sp) 208; RV32IFD-NEXT: addi sp, sp, 16 209; RV32IFD-NEXT: ret 210; 211; RV64IFD-LABEL: fcvt_d_w: 212; RV64IFD: # %bb.0: 213; RV64IFD-NEXT: fcvt.d.w ft0, a0 214; RV64IFD-NEXT: fmv.x.d a0, ft0 215; RV64IFD-NEXT: ret 216 %1 = sitofp i32 %a to double 217 ret double %1 218} 219 220define double @fcvt_d_w_load(i32* %p) nounwind { 221; RV32IFD-LABEL: fcvt_d_w_load: 222; RV32IFD: # %bb.0: 223; RV32IFD-NEXT: addi sp, sp, -16 224; RV32IFD-NEXT: lw a0, 0(a0) 225; RV32IFD-NEXT: fcvt.d.w ft0, a0 226; RV32IFD-NEXT: fsd ft0, 8(sp) 227; RV32IFD-NEXT: lw a0, 8(sp) 228; RV32IFD-NEXT: lw a1, 12(sp) 229; RV32IFD-NEXT: addi sp, sp, 16 230; RV32IFD-NEXT: ret 231; 232; RV64IFD-LABEL: fcvt_d_w_load: 233; RV64IFD: # %bb.0: 234; RV64IFD-NEXT: lw a0, 0(a0) 235; RV64IFD-NEXT: fcvt.d.w ft0, a0 236; RV64IFD-NEXT: fmv.x.d a0, ft0 237; RV64IFD-NEXT: ret 238 %a = load i32, i32* %p 239 %1 = sitofp i32 %a to double 240 ret double %1 241} 242 243define double @fcvt_d_wu(i32 %a) nounwind { 244; RV32IFD-LABEL: fcvt_d_wu: 245; RV32IFD: # %bb.0: 246; RV32IFD-NEXT: addi sp, sp, -16 247; RV32IFD-NEXT: fcvt.d.wu ft0, a0 248; RV32IFD-NEXT: fsd ft0, 8(sp) 249; RV32IFD-NEXT: lw a0, 8(sp) 250; RV32IFD-NEXT: lw a1, 12(sp) 251; RV32IFD-NEXT: addi sp, sp, 16 252; RV32IFD-NEXT: ret 253; 254; RV64IFD-LABEL: fcvt_d_wu: 255; RV64IFD: # %bb.0: 256; RV64IFD-NEXT: fcvt.d.wu ft0, a0 257; RV64IFD-NEXT: fmv.x.d a0, ft0 258; RV64IFD-NEXT: ret 259 %1 = uitofp i32 %a to double 260 ret double %1 261} 262 263define double @fcvt_d_wu_load(i32* %p) nounwind { 264; RV32IFD-LABEL: fcvt_d_wu_load: 265; RV32IFD: # %bb.0: 266; RV32IFD-NEXT: addi sp, sp, -16 267; RV32IFD-NEXT: lw a0, 0(a0) 268; RV32IFD-NEXT: fcvt.d.wu ft0, a0 269; RV32IFD-NEXT: fsd ft0, 8(sp) 270; RV32IFD-NEXT: lw a0, 8(sp) 271; RV32IFD-NEXT: lw a1, 12(sp) 272; RV32IFD-NEXT: addi sp, sp, 16 273; RV32IFD-NEXT: ret 274; 275; RV64IFD-LABEL: fcvt_d_wu_load: 276; RV64IFD: # %bb.0: 277; RV64IFD-NEXT: lwu a0, 0(a0) 278; RV64IFD-NEXT: fcvt.d.wu ft0, a0 279; RV64IFD-NEXT: fmv.x.d a0, ft0 280; RV64IFD-NEXT: ret 281 %a = load i32, i32* %p 282 %1 = uitofp i32 %a to double 283 ret double %1 284} 285 286define i64 @fcvt_l_d(double %a) nounwind { 287; RV32IFD-LABEL: fcvt_l_d: 288; RV32IFD: # %bb.0: 289; RV32IFD-NEXT: addi sp, sp, -16 290; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 291; RV32IFD-NEXT: call __fixdfdi@plt 292; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 293; RV32IFD-NEXT: addi sp, sp, 16 294; RV32IFD-NEXT: ret 295; 296; RV64IFD-LABEL: fcvt_l_d: 297; RV64IFD: # %bb.0: 298; RV64IFD-NEXT: fmv.d.x ft0, a0 299; RV64IFD-NEXT: fcvt.l.d a0, ft0, rtz 300; RV64IFD-NEXT: ret 301 %1 = fptosi double %a to i64 302 ret i64 %1 303} 304 305define i64 @fcvt_l_d_sat(double %a) nounwind { 306; RV32IFD-LABEL: fcvt_l_d_sat: 307; RV32IFD: # %bb.0: # %start 308; RV32IFD-NEXT: addi sp, sp, -32 309; RV32IFD-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 310; RV32IFD-NEXT: sw a0, 16(sp) 311; RV32IFD-NEXT: sw a1, 20(sp) 312; RV32IFD-NEXT: fld ft0, 16(sp) 313; RV32IFD-NEXT: fsd ft0, 8(sp) # 8-byte Folded Spill 314; RV32IFD-NEXT: call __fixdfdi@plt 315; RV32IFD-NEXT: fld ft1, 8(sp) # 8-byte Folded Reload 316; RV32IFD-NEXT: lui a2, %hi(.LCPI12_0) 317; RV32IFD-NEXT: fld ft0, %lo(.LCPI12_0)(a2) 318; RV32IFD-NEXT: fle.d a3, ft0, ft1 319; RV32IFD-NEXT: mv a2, a0 320; RV32IFD-NEXT: bnez a3, .LBB12_2 321; RV32IFD-NEXT: # %bb.1: # %start 322; RV32IFD-NEXT: mv a2, zero 323; RV32IFD-NEXT: .LBB12_2: # %start 324; RV32IFD-NEXT: lui a0, %hi(.LCPI12_1) 325; RV32IFD-NEXT: fld ft0, %lo(.LCPI12_1)(a0) 326; RV32IFD-NEXT: flt.d a4, ft0, ft1 327; RV32IFD-NEXT: addi a0, zero, -1 328; RV32IFD-NEXT: beqz a4, .LBB12_9 329; RV32IFD-NEXT: # %bb.3: # %start 330; RV32IFD-NEXT: feq.d a2, ft1, ft1 331; RV32IFD-NEXT: beqz a2, .LBB12_10 332; RV32IFD-NEXT: .LBB12_4: # %start 333; RV32IFD-NEXT: lui a5, 524288 334; RV32IFD-NEXT: beqz a3, .LBB12_11 335; RV32IFD-NEXT: .LBB12_5: # %start 336; RV32IFD-NEXT: bnez a4, .LBB12_12 337; RV32IFD-NEXT: .LBB12_6: # %start 338; RV32IFD-NEXT: bnez a2, .LBB12_8 339; RV32IFD-NEXT: .LBB12_7: # %start 340; RV32IFD-NEXT: mv a1, zero 341; RV32IFD-NEXT: .LBB12_8: # %start 342; RV32IFD-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 343; RV32IFD-NEXT: addi sp, sp, 32 344; RV32IFD-NEXT: ret 345; RV32IFD-NEXT: .LBB12_9: # %start 346; RV32IFD-NEXT: mv a0, a2 347; RV32IFD-NEXT: feq.d a2, ft1, ft1 348; RV32IFD-NEXT: bnez a2, .LBB12_4 349; RV32IFD-NEXT: .LBB12_10: # %start 350; RV32IFD-NEXT: mv a0, zero 351; RV32IFD-NEXT: lui a5, 524288 352; RV32IFD-NEXT: bnez a3, .LBB12_5 353; RV32IFD-NEXT: .LBB12_11: # %start 354; RV32IFD-NEXT: lui a1, 524288 355; RV32IFD-NEXT: beqz a4, .LBB12_6 356; RV32IFD-NEXT: .LBB12_12: 357; RV32IFD-NEXT: addi a1, a5, -1 358; RV32IFD-NEXT: beqz a2, .LBB12_7 359; RV32IFD-NEXT: j .LBB12_8 360; 361; RV64IFD-LABEL: fcvt_l_d_sat: 362; RV64IFD: # %bb.0: # %start 363; RV64IFD-NEXT: fmv.d.x ft0, a0 364; RV64IFD-NEXT: feq.d a0, ft0, ft0 365; RV64IFD-NEXT: bnez a0, .LBB12_2 366; RV64IFD-NEXT: # %bb.1: # %start 367; RV64IFD-NEXT: mv a0, zero 368; RV64IFD-NEXT: ret 369; RV64IFD-NEXT: .LBB12_2: 370; RV64IFD-NEXT: fcvt.l.d a0, ft0, rtz 371; RV64IFD-NEXT: ret 372start: 373 %0 = tail call i64 @llvm.fptosi.sat.i64.f64(double %a) 374 ret i64 %0 375} 376declare i64 @llvm.fptosi.sat.i64.f64(double) 377 378define i64 @fcvt_lu_d(double %a) nounwind { 379; RV32IFD-LABEL: fcvt_lu_d: 380; RV32IFD: # %bb.0: 381; RV32IFD-NEXT: addi sp, sp, -16 382; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 383; RV32IFD-NEXT: call __fixunsdfdi@plt 384; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 385; RV32IFD-NEXT: addi sp, sp, 16 386; RV32IFD-NEXT: ret 387; 388; RV64IFD-LABEL: fcvt_lu_d: 389; RV64IFD: # %bb.0: 390; RV64IFD-NEXT: fmv.d.x ft0, a0 391; RV64IFD-NEXT: fcvt.lu.d a0, ft0, rtz 392; RV64IFD-NEXT: ret 393 %1 = fptoui double %a to i64 394 ret i64 %1 395} 396 397define i64 @fcvt_lu_d_sat(double %a) nounwind { 398; RV32IFD-LABEL: fcvt_lu_d_sat: 399; RV32IFD: # %bb.0: # %start 400; RV32IFD-NEXT: addi sp, sp, -32 401; RV32IFD-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 402; RV32IFD-NEXT: sw a0, 16(sp) 403; RV32IFD-NEXT: sw a1, 20(sp) 404; RV32IFD-NEXT: fld ft0, 16(sp) 405; RV32IFD-NEXT: fsd ft0, 8(sp) # 8-byte Folded Spill 406; RV32IFD-NEXT: call __fixunsdfdi@plt 407; RV32IFD-NEXT: fld ft1, 8(sp) # 8-byte Folded Reload 408; RV32IFD-NEXT: fcvt.d.w ft0, zero 409; RV32IFD-NEXT: fle.d a4, ft0, ft1 410; RV32IFD-NEXT: mv a3, a0 411; RV32IFD-NEXT: bnez a4, .LBB14_2 412; RV32IFD-NEXT: # %bb.1: # %start 413; RV32IFD-NEXT: mv a3, zero 414; RV32IFD-NEXT: .LBB14_2: # %start 415; RV32IFD-NEXT: lui a0, %hi(.LCPI14_0) 416; RV32IFD-NEXT: fld ft0, %lo(.LCPI14_0)(a0) 417; RV32IFD-NEXT: flt.d a5, ft0, ft1 418; RV32IFD-NEXT: addi a2, zero, -1 419; RV32IFD-NEXT: addi a0, zero, -1 420; RV32IFD-NEXT: beqz a5, .LBB14_7 421; RV32IFD-NEXT: # %bb.3: # %start 422; RV32IFD-NEXT: beqz a4, .LBB14_8 423; RV32IFD-NEXT: .LBB14_4: # %start 424; RV32IFD-NEXT: bnez a5, .LBB14_6 425; RV32IFD-NEXT: .LBB14_5: # %start 426; RV32IFD-NEXT: mv a2, a1 427; RV32IFD-NEXT: .LBB14_6: # %start 428; RV32IFD-NEXT: mv a1, a2 429; RV32IFD-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 430; RV32IFD-NEXT: addi sp, sp, 32 431; RV32IFD-NEXT: ret 432; RV32IFD-NEXT: .LBB14_7: # %start 433; RV32IFD-NEXT: mv a0, a3 434; RV32IFD-NEXT: bnez a4, .LBB14_4 435; RV32IFD-NEXT: .LBB14_8: # %start 436; RV32IFD-NEXT: mv a1, zero 437; RV32IFD-NEXT: beqz a5, .LBB14_5 438; RV32IFD-NEXT: j .LBB14_6 439; 440; RV64IFD-LABEL: fcvt_lu_d_sat: 441; RV64IFD: # %bb.0: # %start 442; RV64IFD-NEXT: fmv.d.x ft0, a0 443; RV64IFD-NEXT: feq.d a0, ft0, ft0 444; RV64IFD-NEXT: bnez a0, .LBB14_2 445; RV64IFD-NEXT: # %bb.1: # %start 446; RV64IFD-NEXT: mv a0, zero 447; RV64IFD-NEXT: ret 448; RV64IFD-NEXT: .LBB14_2: 449; RV64IFD-NEXT: fcvt.lu.d a0, ft0, rtz 450; RV64IFD-NEXT: ret 451start: 452 %0 = tail call i64 @llvm.fptoui.sat.i64.f64(double %a) 453 ret i64 %0 454} 455declare i64 @llvm.fptoui.sat.i64.f64(double) 456 457define i64 @fmv_x_d(double %a, double %b) nounwind { 458; RV32IFD-LABEL: fmv_x_d: 459; RV32IFD: # %bb.0: 460; RV32IFD-NEXT: addi sp, sp, -16 461; RV32IFD-NEXT: sw a2, 0(sp) 462; RV32IFD-NEXT: sw a3, 4(sp) 463; RV32IFD-NEXT: fld ft0, 0(sp) 464; RV32IFD-NEXT: sw a0, 0(sp) 465; RV32IFD-NEXT: sw a1, 4(sp) 466; RV32IFD-NEXT: fld ft1, 0(sp) 467; RV32IFD-NEXT: fadd.d ft0, ft1, ft0 468; RV32IFD-NEXT: fsd ft0, 8(sp) 469; RV32IFD-NEXT: lw a0, 8(sp) 470; RV32IFD-NEXT: lw a1, 12(sp) 471; RV32IFD-NEXT: addi sp, sp, 16 472; RV32IFD-NEXT: ret 473; 474; RV64IFD-LABEL: fmv_x_d: 475; RV64IFD: # %bb.0: 476; RV64IFD-NEXT: fmv.d.x ft0, a1 477; RV64IFD-NEXT: fmv.d.x ft1, a0 478; RV64IFD-NEXT: fadd.d ft0, ft1, ft0 479; RV64IFD-NEXT: fmv.x.d a0, ft0 480; RV64IFD-NEXT: ret 481 %1 = fadd double %a, %b 482 %2 = bitcast double %1 to i64 483 ret i64 %2 484} 485 486define double @fcvt_d_l(i64 %a) nounwind { 487; RV32IFD-LABEL: fcvt_d_l: 488; RV32IFD: # %bb.0: 489; RV32IFD-NEXT: addi sp, sp, -16 490; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 491; RV32IFD-NEXT: call __floatdidf@plt 492; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 493; RV32IFD-NEXT: addi sp, sp, 16 494; RV32IFD-NEXT: ret 495; 496; RV64IFD-LABEL: fcvt_d_l: 497; RV64IFD: # %bb.0: 498; RV64IFD-NEXT: fcvt.d.l ft0, a0 499; RV64IFD-NEXT: fmv.x.d a0, ft0 500; RV64IFD-NEXT: ret 501 %1 = sitofp i64 %a to double 502 ret double %1 503} 504 505define double @fcvt_d_lu(i64 %a) nounwind { 506; RV32IFD-LABEL: fcvt_d_lu: 507; RV32IFD: # %bb.0: 508; RV32IFD-NEXT: addi sp, sp, -16 509; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 510; RV32IFD-NEXT: call __floatundidf@plt 511; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 512; RV32IFD-NEXT: addi sp, sp, 16 513; RV32IFD-NEXT: ret 514; 515; RV64IFD-LABEL: fcvt_d_lu: 516; RV64IFD: # %bb.0: 517; RV64IFD-NEXT: fcvt.d.lu ft0, a0 518; RV64IFD-NEXT: fmv.x.d a0, ft0 519; RV64IFD-NEXT: ret 520 %1 = uitofp i64 %a to double 521 ret double %1 522} 523 524define double @fmv_d_x(i64 %a, i64 %b) nounwind { 525; Ensure fmv.w.x is generated even for a soft double calling convention 526; RV32IFD-LABEL: fmv_d_x: 527; RV32IFD: # %bb.0: 528; RV32IFD-NEXT: addi sp, sp, -32 529; RV32IFD-NEXT: sw a3, 20(sp) 530; RV32IFD-NEXT: sw a2, 16(sp) 531; RV32IFD-NEXT: sw a1, 28(sp) 532; RV32IFD-NEXT: sw a0, 24(sp) 533; RV32IFD-NEXT: fld ft0, 16(sp) 534; RV32IFD-NEXT: fld ft1, 24(sp) 535; RV32IFD-NEXT: fadd.d ft0, ft1, ft0 536; RV32IFD-NEXT: fsd ft0, 8(sp) 537; RV32IFD-NEXT: lw a0, 8(sp) 538; RV32IFD-NEXT: lw a1, 12(sp) 539; RV32IFD-NEXT: addi sp, sp, 32 540; RV32IFD-NEXT: ret 541; 542; RV64IFD-LABEL: fmv_d_x: 543; RV64IFD: # %bb.0: 544; RV64IFD-NEXT: fmv.d.x ft0, a0 545; RV64IFD-NEXT: fmv.d.x ft1, a1 546; RV64IFD-NEXT: fadd.d ft0, ft0, ft1 547; RV64IFD-NEXT: fmv.x.d a0, ft0 548; RV64IFD-NEXT: ret 549 %1 = bitcast i64 %a to double 550 %2 = bitcast i64 %b to double 551 %3 = fadd double %1, %2 552 ret double %3 553} 554 555define double @fcvt_d_w_i8(i8 signext %a) nounwind { 556; RV32IFD-LABEL: fcvt_d_w_i8: 557; RV32IFD: # %bb.0: 558; RV32IFD-NEXT: addi sp, sp, -16 559; RV32IFD-NEXT: fcvt.d.w ft0, a0 560; RV32IFD-NEXT: fsd ft0, 8(sp) 561; RV32IFD-NEXT: lw a0, 8(sp) 562; RV32IFD-NEXT: lw a1, 12(sp) 563; RV32IFD-NEXT: addi sp, sp, 16 564; RV32IFD-NEXT: ret 565; 566; RV64IFD-LABEL: fcvt_d_w_i8: 567; RV64IFD: # %bb.0: 568; RV64IFD-NEXT: fcvt.d.w ft0, a0 569; RV64IFD-NEXT: fmv.x.d a0, ft0 570; RV64IFD-NEXT: ret 571 %1 = sitofp i8 %a to double 572 ret double %1 573} 574 575define double @fcvt_d_wu_i8(i8 zeroext %a) nounwind { 576; RV32IFD-LABEL: fcvt_d_wu_i8: 577; RV32IFD: # %bb.0: 578; RV32IFD-NEXT: addi sp, sp, -16 579; RV32IFD-NEXT: fcvt.d.wu ft0, a0 580; RV32IFD-NEXT: fsd ft0, 8(sp) 581; RV32IFD-NEXT: lw a0, 8(sp) 582; RV32IFD-NEXT: lw a1, 12(sp) 583; RV32IFD-NEXT: addi sp, sp, 16 584; RV32IFD-NEXT: ret 585; 586; RV64IFD-LABEL: fcvt_d_wu_i8: 587; RV64IFD: # %bb.0: 588; RV64IFD-NEXT: fcvt.d.wu ft0, a0 589; RV64IFD-NEXT: fmv.x.d a0, ft0 590; RV64IFD-NEXT: ret 591 %1 = uitofp i8 %a to double 592 ret double %1 593} 594 595define double @fcvt_d_w_i16(i16 signext %a) nounwind { 596; RV32IFD-LABEL: fcvt_d_w_i16: 597; RV32IFD: # %bb.0: 598; RV32IFD-NEXT: addi sp, sp, -16 599; RV32IFD-NEXT: fcvt.d.w ft0, a0 600; RV32IFD-NEXT: fsd ft0, 8(sp) 601; RV32IFD-NEXT: lw a0, 8(sp) 602; RV32IFD-NEXT: lw a1, 12(sp) 603; RV32IFD-NEXT: addi sp, sp, 16 604; RV32IFD-NEXT: ret 605; 606; RV64IFD-LABEL: fcvt_d_w_i16: 607; RV64IFD: # %bb.0: 608; RV64IFD-NEXT: fcvt.d.w ft0, a0 609; RV64IFD-NEXT: fmv.x.d a0, ft0 610; RV64IFD-NEXT: ret 611 %1 = sitofp i16 %a to double 612 ret double %1 613} 614 615define double @fcvt_d_wu_i16(i16 zeroext %a) nounwind { 616; RV32IFD-LABEL: fcvt_d_wu_i16: 617; RV32IFD: # %bb.0: 618; RV32IFD-NEXT: addi sp, sp, -16 619; RV32IFD-NEXT: fcvt.d.wu ft0, a0 620; RV32IFD-NEXT: fsd ft0, 8(sp) 621; RV32IFD-NEXT: lw a0, 8(sp) 622; RV32IFD-NEXT: lw a1, 12(sp) 623; RV32IFD-NEXT: addi sp, sp, 16 624; RV32IFD-NEXT: ret 625; 626; RV64IFD-LABEL: fcvt_d_wu_i16: 627; RV64IFD: # %bb.0: 628; RV64IFD-NEXT: fcvt.d.wu ft0, a0 629; RV64IFD-NEXT: fmv.x.d a0, ft0 630; RV64IFD-NEXT: ret 631 %1 = uitofp i16 %a to double 632 ret double %1 633} 634 635; Make sure we select W version of addi on RV64. 636define signext i32 @fcvt_d_w_demanded_bits(i32 signext %0, double* %1) { 637; RV32IFD-LABEL: fcvt_d_w_demanded_bits: 638; RV32IFD: # %bb.0: 639; RV32IFD-NEXT: addi a0, a0, 1 640; RV32IFD-NEXT: fcvt.d.w ft0, a0 641; RV32IFD-NEXT: fsd ft0, 0(a1) 642; RV32IFD-NEXT: ret 643; 644; RV64IFD-LABEL: fcvt_d_w_demanded_bits: 645; RV64IFD: # %bb.0: 646; RV64IFD-NEXT: addiw a0, a0, 1 647; RV64IFD-NEXT: fcvt.d.w ft0, a0 648; RV64IFD-NEXT: fsd ft0, 0(a1) 649; RV64IFD-NEXT: ret 650 %3 = add i32 %0, 1 651 %4 = sitofp i32 %3 to double 652 store double %4, double* %1, align 8 653 ret i32 %3 654} 655 656; Make sure we select W version of addi on RV64. 657define signext i32 @fcvt_d_wu_demanded_bits(i32 signext %0, double* %1) { 658; RV32IFD-LABEL: fcvt_d_wu_demanded_bits: 659; RV32IFD: # %bb.0: 660; RV32IFD-NEXT: addi a0, a0, 1 661; RV32IFD-NEXT: fcvt.d.wu ft0, a0 662; RV32IFD-NEXT: fsd ft0, 0(a1) 663; RV32IFD-NEXT: ret 664; 665; RV64IFD-LABEL: fcvt_d_wu_demanded_bits: 666; RV64IFD: # %bb.0: 667; RV64IFD-NEXT: addiw a0, a0, 1 668; RV64IFD-NEXT: fcvt.d.wu ft0, a0 669; RV64IFD-NEXT: fsd ft0, 0(a1) 670; RV64IFD-NEXT: ret 671 %3 = add i32 %0, 1 672 %4 = uitofp i32 %3 to double 673 store double %4, double* %1, align 8 674 ret i32 %3 675} 676