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