1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -mattr=+zfh -verify-machineinstrs \ 3; RUN: -target-abi ilp32f -disable-strictnode-mutation < %s \ 4; RUN: | FileCheck -check-prefix=RV32IZFH %s 5; RUN: llc -mtriple=riscv64 -mattr=+zfh -verify-machineinstrs \ 6; RUN: -target-abi lp64f -disable-strictnode-mutation < %s \ 7; RUN: | FileCheck -check-prefix=RV64IZFH %s 8; RUN: llc -mtriple=riscv32 -mattr=+d,+zfh -verify-machineinstrs \ 9; RUN: -target-abi ilp32d -disable-strictnode-mutation < %s \ 10; RUN: | FileCheck -check-prefix=RV32IDZFH %s 11; RUN: llc -mtriple=riscv64 -mattr=+d,+zfh -verify-machineinstrs \ 12; RUN: -target-abi lp64d -disable-strictnode-mutation < %s \ 13; RUN: | FileCheck -check-prefix=RV64IDZFH %s 14 15; NOTE: The rounding mode metadata does not effect which instruction is 16; selected. Dynamic rounding mode is always used for operations that 17; support rounding mode. 18 19define i16 @fcvt_si_h(half %a) nounwind strictfp { 20; RV32IZFH-LABEL: fcvt_si_h: 21; RV32IZFH: # %bb.0: 22; RV32IZFH-NEXT: fcvt.w.h a0, fa0, rtz 23; RV32IZFH-NEXT: ret 24; 25; RV64IZFH-LABEL: fcvt_si_h: 26; RV64IZFH: # %bb.0: 27; RV64IZFH-NEXT: fcvt.l.h a0, fa0, rtz 28; RV64IZFH-NEXT: ret 29; 30; RV32IDZFH-LABEL: fcvt_si_h: 31; RV32IDZFH: # %bb.0: 32; RV32IDZFH-NEXT: fcvt.w.h a0, fa0, rtz 33; RV32IDZFH-NEXT: ret 34; 35; RV64IDZFH-LABEL: fcvt_si_h: 36; RV64IDZFH: # %bb.0: 37; RV64IDZFH-NEXT: fcvt.l.h a0, fa0, rtz 38; RV64IDZFH-NEXT: ret 39 %1 = call i16 @llvm.experimental.constrained.fptosi.i16.f16(half %a, metadata !"fpexcept.strict") strictfp 40 ret i16 %1 41} 42declare i16 @llvm.experimental.constrained.fptosi.i16.f16(half, metadata) 43 44define i16 @fcvt_ui_h(half %a) nounwind strictfp { 45; RV32IZFH-LABEL: fcvt_ui_h: 46; RV32IZFH: # %bb.0: 47; RV32IZFH-NEXT: fcvt.wu.h a0, fa0, rtz 48; RV32IZFH-NEXT: ret 49; 50; RV64IZFH-LABEL: fcvt_ui_h: 51; RV64IZFH: # %bb.0: 52; RV64IZFH-NEXT: fcvt.lu.h a0, fa0, rtz 53; RV64IZFH-NEXT: ret 54; 55; RV32IDZFH-LABEL: fcvt_ui_h: 56; RV32IDZFH: # %bb.0: 57; RV32IDZFH-NEXT: fcvt.wu.h a0, fa0, rtz 58; RV32IDZFH-NEXT: ret 59; 60; RV64IDZFH-LABEL: fcvt_ui_h: 61; RV64IDZFH: # %bb.0: 62; RV64IDZFH-NEXT: fcvt.lu.h a0, fa0, rtz 63; RV64IDZFH-NEXT: ret 64 %1 = call i16 @llvm.experimental.constrained.fptoui.i16.f16(half %a, metadata !"fpexcept.strict") strictfp 65 ret i16 %1 66} 67declare i16 @llvm.experimental.constrained.fptoui.i16.f16(half, metadata) 68 69define i32 @fcvt_w_h(half %a) nounwind strictfp { 70; RV32IZFH-LABEL: fcvt_w_h: 71; RV32IZFH: # %bb.0: 72; RV32IZFH-NEXT: fcvt.w.h a0, fa0, rtz 73; RV32IZFH-NEXT: ret 74; 75; RV64IZFH-LABEL: fcvt_w_h: 76; RV64IZFH: # %bb.0: 77; RV64IZFH-NEXT: fcvt.w.h a0, fa0, rtz 78; RV64IZFH-NEXT: ret 79; 80; RV32IDZFH-LABEL: fcvt_w_h: 81; RV32IDZFH: # %bb.0: 82; RV32IDZFH-NEXT: fcvt.w.h a0, fa0, rtz 83; RV32IDZFH-NEXT: ret 84; 85; RV64IDZFH-LABEL: fcvt_w_h: 86; RV64IDZFH: # %bb.0: 87; RV64IDZFH-NEXT: fcvt.w.h a0, fa0, rtz 88; RV64IDZFH-NEXT: ret 89 %1 = call i32 @llvm.experimental.constrained.fptosi.i32.f16(half %a, metadata !"fpexcept.strict") strictfp 90 ret i32 %1 91} 92declare i32 @llvm.experimental.constrained.fptosi.i32.f16(half, metadata) 93 94define i32 @fcvt_wu_h(half %a) nounwind strictfp { 95; RV32IZFH-LABEL: fcvt_wu_h: 96; RV32IZFH: # %bb.0: 97; RV32IZFH-NEXT: fcvt.wu.h a0, fa0, rtz 98; RV32IZFH-NEXT: ret 99; 100; RV64IZFH-LABEL: fcvt_wu_h: 101; RV64IZFH: # %bb.0: 102; RV64IZFH-NEXT: fcvt.wu.h a0, fa0, rtz 103; RV64IZFH-NEXT: ret 104; 105; RV32IDZFH-LABEL: fcvt_wu_h: 106; RV32IDZFH: # %bb.0: 107; RV32IDZFH-NEXT: fcvt.wu.h a0, fa0, rtz 108; RV32IDZFH-NEXT: ret 109; 110; RV64IDZFH-LABEL: fcvt_wu_h: 111; RV64IDZFH: # %bb.0: 112; RV64IDZFH-NEXT: fcvt.wu.h a0, fa0, rtz 113; RV64IDZFH-NEXT: ret 114 %1 = call i32 @llvm.experimental.constrained.fptoui.i32.f16(half %a, metadata !"fpexcept.strict") strictfp 115 ret i32 %1 116} 117declare i32 @llvm.experimental.constrained.fptoui.i32.f16(half, metadata) 118 119; Test where the fptoui has multiple uses, one of which causes a sext to be 120; inserted on RV64. 121; FIXME: We should not have an fcvt.wu.h and an fcvt.lu.h. 122define i32 @fcvt_wu_h_multiple_use(half %x, i32* %y) { 123; RV32IZFH-LABEL: fcvt_wu_h_multiple_use: 124; RV32IZFH: # %bb.0: 125; RV32IZFH-NEXT: fcvt.wu.h a1, fa0, rtz 126; RV32IZFH-NEXT: li a0, 1 127; RV32IZFH-NEXT: beqz a1, .LBB4_2 128; RV32IZFH-NEXT: # %bb.1: 129; RV32IZFH-NEXT: mv a0, a1 130; RV32IZFH-NEXT: .LBB4_2: 131; RV32IZFH-NEXT: ret 132; 133; RV64IZFH-LABEL: fcvt_wu_h_multiple_use: 134; RV64IZFH: # %bb.0: 135; RV64IZFH-NEXT: fcvt.wu.h a1, fa0, rtz 136; RV64IZFH-NEXT: li a0, 1 137; RV64IZFH-NEXT: beqz a1, .LBB4_2 138; RV64IZFH-NEXT: # %bb.1: 139; RV64IZFH-NEXT: mv a0, a1 140; RV64IZFH-NEXT: .LBB4_2: 141; RV64IZFH-NEXT: ret 142; 143; RV32IDZFH-LABEL: fcvt_wu_h_multiple_use: 144; RV32IDZFH: # %bb.0: 145; RV32IDZFH-NEXT: fcvt.wu.h a1, fa0, rtz 146; RV32IDZFH-NEXT: li a0, 1 147; RV32IDZFH-NEXT: beqz a1, .LBB4_2 148; RV32IDZFH-NEXT: # %bb.1: 149; RV32IDZFH-NEXT: mv a0, a1 150; RV32IDZFH-NEXT: .LBB4_2: 151; RV32IDZFH-NEXT: ret 152; 153; RV64IDZFH-LABEL: fcvt_wu_h_multiple_use: 154; RV64IDZFH: # %bb.0: 155; RV64IDZFH-NEXT: fcvt.wu.h a1, fa0, rtz 156; RV64IDZFH-NEXT: li a0, 1 157; RV64IDZFH-NEXT: beqz a1, .LBB4_2 158; RV64IDZFH-NEXT: # %bb.1: 159; RV64IDZFH-NEXT: mv a0, a1 160; RV64IDZFH-NEXT: .LBB4_2: 161; RV64IDZFH-NEXT: ret 162 %a = call i32 @llvm.experimental.constrained.fptoui.i32.f16(half %x, metadata !"fpexcept.strict") strictfp 163 %b = icmp eq i32 %a, 0 164 %c = select i1 %b, i32 1, i32 %a 165 ret i32 %c 166} 167 168define i64 @fcvt_l_h(half %a) nounwind strictfp { 169; RV32IZFH-LABEL: fcvt_l_h: 170; RV32IZFH: # %bb.0: 171; RV32IZFH-NEXT: addi sp, sp, -16 172; RV32IZFH-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 173; RV32IZFH-NEXT: call __fixhfdi@plt 174; RV32IZFH-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 175; RV32IZFH-NEXT: addi sp, sp, 16 176; RV32IZFH-NEXT: ret 177; 178; RV64IZFH-LABEL: fcvt_l_h: 179; RV64IZFH: # %bb.0: 180; RV64IZFH-NEXT: fcvt.l.h a0, fa0, rtz 181; RV64IZFH-NEXT: ret 182; 183; RV32IDZFH-LABEL: fcvt_l_h: 184; RV32IDZFH: # %bb.0: 185; RV32IDZFH-NEXT: addi sp, sp, -16 186; RV32IDZFH-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 187; RV32IDZFH-NEXT: call __fixhfdi@plt 188; RV32IDZFH-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 189; RV32IDZFH-NEXT: addi sp, sp, 16 190; RV32IDZFH-NEXT: ret 191; 192; RV64IDZFH-LABEL: fcvt_l_h: 193; RV64IDZFH: # %bb.0: 194; RV64IDZFH-NEXT: fcvt.l.h a0, fa0, rtz 195; RV64IDZFH-NEXT: ret 196 %1 = call i64 @llvm.experimental.constrained.fptosi.i64.f16(half %a, metadata !"fpexcept.strict") strictfp 197 ret i64 %1 198} 199declare i64 @llvm.experimental.constrained.fptosi.i64.f16(half, metadata) 200 201define i64 @fcvt_lu_h(half %a) nounwind strictfp { 202; RV32IZFH-LABEL: fcvt_lu_h: 203; RV32IZFH: # %bb.0: 204; RV32IZFH-NEXT: addi sp, sp, -16 205; RV32IZFH-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 206; RV32IZFH-NEXT: call __fixunshfdi@plt 207; RV32IZFH-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 208; RV32IZFH-NEXT: addi sp, sp, 16 209; RV32IZFH-NEXT: ret 210; 211; RV64IZFH-LABEL: fcvt_lu_h: 212; RV64IZFH: # %bb.0: 213; RV64IZFH-NEXT: fcvt.lu.h a0, fa0, rtz 214; RV64IZFH-NEXT: ret 215; 216; RV32IDZFH-LABEL: fcvt_lu_h: 217; RV32IDZFH: # %bb.0: 218; RV32IDZFH-NEXT: addi sp, sp, -16 219; RV32IDZFH-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 220; RV32IDZFH-NEXT: call __fixunshfdi@plt 221; RV32IDZFH-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 222; RV32IDZFH-NEXT: addi sp, sp, 16 223; RV32IDZFH-NEXT: ret 224; 225; RV64IDZFH-LABEL: fcvt_lu_h: 226; RV64IDZFH: # %bb.0: 227; RV64IDZFH-NEXT: fcvt.lu.h a0, fa0, rtz 228; RV64IDZFH-NEXT: ret 229 %1 = call i64 @llvm.experimental.constrained.fptoui.i64.f16(half %a, metadata !"fpexcept.strict") strictfp 230 ret i64 %1 231} 232declare i64 @llvm.experimental.constrained.fptoui.i64.f16(half, metadata) 233 234define half @fcvt_h_si(i16 %a) nounwind strictfp { 235; RV32IZFH-LABEL: fcvt_h_si: 236; RV32IZFH: # %bb.0: 237; RV32IZFH-NEXT: slli a0, a0, 16 238; RV32IZFH-NEXT: srai a0, a0, 16 239; RV32IZFH-NEXT: fcvt.h.w fa0, a0 240; RV32IZFH-NEXT: ret 241; 242; RV64IZFH-LABEL: fcvt_h_si: 243; RV64IZFH: # %bb.0: 244; RV64IZFH-NEXT: slli a0, a0, 48 245; RV64IZFH-NEXT: srai a0, a0, 48 246; RV64IZFH-NEXT: fcvt.h.w fa0, a0 247; RV64IZFH-NEXT: ret 248; 249; RV32IDZFH-LABEL: fcvt_h_si: 250; RV32IDZFH: # %bb.0: 251; RV32IDZFH-NEXT: slli a0, a0, 16 252; RV32IDZFH-NEXT: srai a0, a0, 16 253; RV32IDZFH-NEXT: fcvt.h.w fa0, a0 254; RV32IDZFH-NEXT: ret 255; 256; RV64IDZFH-LABEL: fcvt_h_si: 257; RV64IDZFH: # %bb.0: 258; RV64IDZFH-NEXT: slli a0, a0, 48 259; RV64IDZFH-NEXT: srai a0, a0, 48 260; RV64IDZFH-NEXT: fcvt.h.w fa0, a0 261; RV64IDZFH-NEXT: ret 262 %1 = call half @llvm.experimental.constrained.sitofp.f16.i16(i16 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 263 ret half %1 264} 265declare half @llvm.experimental.constrained.sitofp.f16.i16(i16, metadata, metadata) 266 267define half @fcvt_h_si_signext(i16 signext %a) nounwind strictfp { 268; RV32IZFH-LABEL: fcvt_h_si_signext: 269; RV32IZFH: # %bb.0: 270; RV32IZFH-NEXT: fcvt.h.w fa0, a0 271; RV32IZFH-NEXT: ret 272; 273; RV64IZFH-LABEL: fcvt_h_si_signext: 274; RV64IZFH: # %bb.0: 275; RV64IZFH-NEXT: fcvt.h.w fa0, a0 276; RV64IZFH-NEXT: ret 277; 278; RV32IDZFH-LABEL: fcvt_h_si_signext: 279; RV32IDZFH: # %bb.0: 280; RV32IDZFH-NEXT: fcvt.h.w fa0, a0 281; RV32IDZFH-NEXT: ret 282; 283; RV64IDZFH-LABEL: fcvt_h_si_signext: 284; RV64IDZFH: # %bb.0: 285; RV64IDZFH-NEXT: fcvt.h.w fa0, a0 286; RV64IDZFH-NEXT: ret 287 %1 = call half @llvm.experimental.constrained.sitofp.f16.i16(i16 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 288 ret half %1 289} 290 291define half @fcvt_h_ui(i16 %a) nounwind strictfp { 292; RV32IZFH-LABEL: fcvt_h_ui: 293; RV32IZFH: # %bb.0: 294; RV32IZFH-NEXT: slli a0, a0, 16 295; RV32IZFH-NEXT: srli a0, a0, 16 296; RV32IZFH-NEXT: fcvt.h.wu fa0, a0 297; RV32IZFH-NEXT: ret 298; 299; RV64IZFH-LABEL: fcvt_h_ui: 300; RV64IZFH: # %bb.0: 301; RV64IZFH-NEXT: slli a0, a0, 48 302; RV64IZFH-NEXT: srli a0, a0, 48 303; RV64IZFH-NEXT: fcvt.h.wu fa0, a0 304; RV64IZFH-NEXT: ret 305; 306; RV32IDZFH-LABEL: fcvt_h_ui: 307; RV32IDZFH: # %bb.0: 308; RV32IDZFH-NEXT: slli a0, a0, 16 309; RV32IDZFH-NEXT: srli a0, a0, 16 310; RV32IDZFH-NEXT: fcvt.h.wu fa0, a0 311; RV32IDZFH-NEXT: ret 312; 313; RV64IDZFH-LABEL: fcvt_h_ui: 314; RV64IDZFH: # %bb.0: 315; RV64IDZFH-NEXT: slli a0, a0, 48 316; RV64IDZFH-NEXT: srli a0, a0, 48 317; RV64IDZFH-NEXT: fcvt.h.wu fa0, a0 318; RV64IDZFH-NEXT: ret 319 %1 = call half @llvm.experimental.constrained.uitofp.f16.i16(i16 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 320 ret half %1 321} 322declare half @llvm.experimental.constrained.uitofp.f16.i16(i16, metadata, metadata) 323 324define half @fcvt_h_ui_zeroext(i16 zeroext %a) nounwind strictfp { 325; RV32IZFH-LABEL: fcvt_h_ui_zeroext: 326; RV32IZFH: # %bb.0: 327; RV32IZFH-NEXT: fcvt.h.wu fa0, a0 328; RV32IZFH-NEXT: ret 329; 330; RV64IZFH-LABEL: fcvt_h_ui_zeroext: 331; RV64IZFH: # %bb.0: 332; RV64IZFH-NEXT: fcvt.h.wu fa0, a0 333; RV64IZFH-NEXT: ret 334; 335; RV32IDZFH-LABEL: fcvt_h_ui_zeroext: 336; RV32IDZFH: # %bb.0: 337; RV32IDZFH-NEXT: fcvt.h.wu fa0, a0 338; RV32IDZFH-NEXT: ret 339; 340; RV64IDZFH-LABEL: fcvt_h_ui_zeroext: 341; RV64IDZFH: # %bb.0: 342; RV64IDZFH-NEXT: fcvt.h.wu fa0, a0 343; RV64IDZFH-NEXT: ret 344 %1 = call half @llvm.experimental.constrained.uitofp.f16.i16(i16 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 345 ret half %1 346} 347 348define half @fcvt_h_w(i32 %a) nounwind strictfp { 349; RV32IZFH-LABEL: fcvt_h_w: 350; RV32IZFH: # %bb.0: 351; RV32IZFH-NEXT: fcvt.h.w fa0, a0 352; RV32IZFH-NEXT: ret 353; 354; RV64IZFH-LABEL: fcvt_h_w: 355; RV64IZFH: # %bb.0: 356; RV64IZFH-NEXT: fcvt.h.w fa0, a0 357; RV64IZFH-NEXT: ret 358; 359; RV32IDZFH-LABEL: fcvt_h_w: 360; RV32IDZFH: # %bb.0: 361; RV32IDZFH-NEXT: fcvt.h.w fa0, a0 362; RV32IDZFH-NEXT: ret 363; 364; RV64IDZFH-LABEL: fcvt_h_w: 365; RV64IDZFH: # %bb.0: 366; RV64IDZFH-NEXT: fcvt.h.w fa0, a0 367; RV64IDZFH-NEXT: ret 368 %1 = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 369 ret half %1 370} 371declare half @llvm.experimental.constrained.sitofp.f16.i32(i32, metadata, metadata) 372 373define half @fcvt_h_w_load(i32* %p) nounwind strictfp { 374; RV32IZFH-LABEL: fcvt_h_w_load: 375; RV32IZFH: # %bb.0: 376; RV32IZFH-NEXT: lw a0, 0(a0) 377; RV32IZFH-NEXT: fcvt.h.w fa0, a0 378; RV32IZFH-NEXT: ret 379; 380; RV64IZFH-LABEL: fcvt_h_w_load: 381; RV64IZFH: # %bb.0: 382; RV64IZFH-NEXT: lw a0, 0(a0) 383; RV64IZFH-NEXT: fcvt.h.w fa0, a0 384; RV64IZFH-NEXT: ret 385; 386; RV32IDZFH-LABEL: fcvt_h_w_load: 387; RV32IDZFH: # %bb.0: 388; RV32IDZFH-NEXT: lw a0, 0(a0) 389; RV32IDZFH-NEXT: fcvt.h.w fa0, a0 390; RV32IDZFH-NEXT: ret 391; 392; RV64IDZFH-LABEL: fcvt_h_w_load: 393; RV64IDZFH: # %bb.0: 394; RV64IDZFH-NEXT: lw a0, 0(a0) 395; RV64IDZFH-NEXT: fcvt.h.w fa0, a0 396; RV64IDZFH-NEXT: ret 397 %a = load i32, i32* %p 398 %1 = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 399 ret half %1 400} 401 402define half @fcvt_h_wu(i32 %a) nounwind strictfp { 403; RV32IZFH-LABEL: fcvt_h_wu: 404; RV32IZFH: # %bb.0: 405; RV32IZFH-NEXT: fcvt.h.wu fa0, a0 406; RV32IZFH-NEXT: ret 407; 408; RV64IZFH-LABEL: fcvt_h_wu: 409; RV64IZFH: # %bb.0: 410; RV64IZFH-NEXT: fcvt.h.wu fa0, a0 411; RV64IZFH-NEXT: ret 412; 413; RV32IDZFH-LABEL: fcvt_h_wu: 414; RV32IDZFH: # %bb.0: 415; RV32IDZFH-NEXT: fcvt.h.wu fa0, a0 416; RV32IDZFH-NEXT: ret 417; 418; RV64IDZFH-LABEL: fcvt_h_wu: 419; RV64IDZFH: # %bb.0: 420; RV64IDZFH-NEXT: fcvt.h.wu fa0, a0 421; RV64IDZFH-NEXT: ret 422 %1 = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 423 ret half %1 424} 425declare half @llvm.experimental.constrained.uitofp.f16.i32(i32, metadata, metadata) 426 427define half @fcvt_h_wu_load(i32* %p) nounwind strictfp { 428; RV32IZFH-LABEL: fcvt_h_wu_load: 429; RV32IZFH: # %bb.0: 430; RV32IZFH-NEXT: lw a0, 0(a0) 431; RV32IZFH-NEXT: fcvt.h.wu fa0, a0 432; RV32IZFH-NEXT: ret 433; 434; RV64IZFH-LABEL: fcvt_h_wu_load: 435; RV64IZFH: # %bb.0: 436; RV64IZFH-NEXT: lwu a0, 0(a0) 437; RV64IZFH-NEXT: fcvt.h.wu fa0, a0 438; RV64IZFH-NEXT: ret 439; 440; RV32IDZFH-LABEL: fcvt_h_wu_load: 441; RV32IDZFH: # %bb.0: 442; RV32IDZFH-NEXT: lw a0, 0(a0) 443; RV32IDZFH-NEXT: fcvt.h.wu fa0, a0 444; RV32IDZFH-NEXT: ret 445; 446; RV64IDZFH-LABEL: fcvt_h_wu_load: 447; RV64IDZFH: # %bb.0: 448; RV64IDZFH-NEXT: lwu a0, 0(a0) 449; RV64IDZFH-NEXT: fcvt.h.wu fa0, a0 450; RV64IDZFH-NEXT: ret 451 %a = load i32, i32* %p 452 %1 = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 453 ret half %1 454} 455 456define half @fcvt_h_l(i64 %a) nounwind strictfp { 457; RV32IZFH-LABEL: fcvt_h_l: 458; RV32IZFH: # %bb.0: 459; RV32IZFH-NEXT: addi sp, sp, -16 460; RV32IZFH-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 461; RV32IZFH-NEXT: call __floatdihf@plt 462; RV32IZFH-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 463; RV32IZFH-NEXT: addi sp, sp, 16 464; RV32IZFH-NEXT: ret 465; 466; RV64IZFH-LABEL: fcvt_h_l: 467; RV64IZFH: # %bb.0: 468; RV64IZFH-NEXT: fcvt.h.l fa0, a0 469; RV64IZFH-NEXT: ret 470; 471; RV32IDZFH-LABEL: fcvt_h_l: 472; RV32IDZFH: # %bb.0: 473; RV32IDZFH-NEXT: addi sp, sp, -16 474; RV32IDZFH-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 475; RV32IDZFH-NEXT: call __floatdihf@plt 476; RV32IDZFH-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 477; RV32IDZFH-NEXT: addi sp, sp, 16 478; RV32IDZFH-NEXT: ret 479; 480; RV64IDZFH-LABEL: fcvt_h_l: 481; RV64IDZFH: # %bb.0: 482; RV64IDZFH-NEXT: fcvt.h.l fa0, a0 483; RV64IDZFH-NEXT: ret 484 %1 = call half @llvm.experimental.constrained.sitofp.f16.i64(i64 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 485 ret half %1 486} 487declare half @llvm.experimental.constrained.sitofp.f16.i64(i64, metadata, metadata) 488 489define half @fcvt_h_lu(i64 %a) nounwind strictfp { 490; RV32IZFH-LABEL: fcvt_h_lu: 491; RV32IZFH: # %bb.0: 492; RV32IZFH-NEXT: addi sp, sp, -16 493; RV32IZFH-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 494; RV32IZFH-NEXT: call __floatundihf@plt 495; RV32IZFH-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 496; RV32IZFH-NEXT: addi sp, sp, 16 497; RV32IZFH-NEXT: ret 498; 499; RV64IZFH-LABEL: fcvt_h_lu: 500; RV64IZFH: # %bb.0: 501; RV64IZFH-NEXT: fcvt.h.lu fa0, a0 502; RV64IZFH-NEXT: ret 503; 504; RV32IDZFH-LABEL: fcvt_h_lu: 505; RV32IDZFH: # %bb.0: 506; RV32IDZFH-NEXT: addi sp, sp, -16 507; RV32IDZFH-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 508; RV32IDZFH-NEXT: call __floatundihf@plt 509; RV32IDZFH-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 510; RV32IDZFH-NEXT: addi sp, sp, 16 511; RV32IDZFH-NEXT: ret 512; 513; RV64IDZFH-LABEL: fcvt_h_lu: 514; RV64IDZFH: # %bb.0: 515; RV64IDZFH-NEXT: fcvt.h.lu fa0, a0 516; RV64IDZFH-NEXT: ret 517 %1 = call half @llvm.experimental.constrained.uitofp.f16.i64(i64 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 518 ret half %1 519} 520declare half @llvm.experimental.constrained.uitofp.f16.i64(i64, metadata, metadata) 521 522define half @fcvt_h_s(float %a) nounwind strictfp { 523; RV32IZFH-LABEL: fcvt_h_s: 524; RV32IZFH: # %bb.0: 525; RV32IZFH-NEXT: fcvt.h.s fa0, fa0 526; RV32IZFH-NEXT: ret 527; 528; RV64IZFH-LABEL: fcvt_h_s: 529; RV64IZFH: # %bb.0: 530; RV64IZFH-NEXT: fcvt.h.s fa0, fa0 531; RV64IZFH-NEXT: ret 532; 533; RV32IDZFH-LABEL: fcvt_h_s: 534; RV32IDZFH: # %bb.0: 535; RV32IDZFH-NEXT: fcvt.h.s fa0, fa0 536; RV32IDZFH-NEXT: ret 537; 538; RV64IDZFH-LABEL: fcvt_h_s: 539; RV64IDZFH: # %bb.0: 540; RV64IDZFH-NEXT: fcvt.h.s fa0, fa0 541; RV64IDZFH-NEXT: ret 542 %1 = call half @llvm.experimental.constrained.fptrunc.f16.f32(float %a, metadata !"round.dynamic", metadata !"fpexcept.strict") 543 ret half %1 544} 545declare half @llvm.experimental.constrained.fptrunc.f16.f32(float, metadata, metadata) 546 547define float @fcvt_s_h(half %a) nounwind strictfp { 548; RV32IZFH-LABEL: fcvt_s_h: 549; RV32IZFH: # %bb.0: 550; RV32IZFH-NEXT: fcvt.s.h fa0, fa0 551; RV32IZFH-NEXT: ret 552; 553; RV64IZFH-LABEL: fcvt_s_h: 554; RV64IZFH: # %bb.0: 555; RV64IZFH-NEXT: fcvt.s.h fa0, fa0 556; RV64IZFH-NEXT: ret 557; 558; RV32IDZFH-LABEL: fcvt_s_h: 559; RV32IDZFH: # %bb.0: 560; RV32IDZFH-NEXT: fcvt.s.h fa0, fa0 561; RV32IDZFH-NEXT: ret 562; 563; RV64IDZFH-LABEL: fcvt_s_h: 564; RV64IDZFH: # %bb.0: 565; RV64IDZFH-NEXT: fcvt.s.h fa0, fa0 566; RV64IDZFH-NEXT: ret 567 %1 = call float @llvm.experimental.constrained.fpext.f32.f16(half %a, metadata !"fpexcept.strict") 568 ret float %1 569} 570declare float @llvm.experimental.constrained.fpext.f32.f16(half, metadata) 571 572define half @fcvt_h_d(double %a) nounwind strictfp { 573; RV32IZFH-LABEL: fcvt_h_d: 574; RV32IZFH: # %bb.0: 575; RV32IZFH-NEXT: addi sp, sp, -16 576; RV32IZFH-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 577; RV32IZFH-NEXT: call __truncdfhf2@plt 578; RV32IZFH-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 579; RV32IZFH-NEXT: addi sp, sp, 16 580; RV32IZFH-NEXT: ret 581; 582; RV64IZFH-LABEL: fcvt_h_d: 583; RV64IZFH: # %bb.0: 584; RV64IZFH-NEXT: addi sp, sp, -16 585; RV64IZFH-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 586; RV64IZFH-NEXT: call __truncdfhf2@plt 587; RV64IZFH-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 588; RV64IZFH-NEXT: addi sp, sp, 16 589; RV64IZFH-NEXT: ret 590; 591; RV32IDZFH-LABEL: fcvt_h_d: 592; RV32IDZFH: # %bb.0: 593; RV32IDZFH-NEXT: fcvt.h.d fa0, fa0 594; RV32IDZFH-NEXT: ret 595; 596; RV64IDZFH-LABEL: fcvt_h_d: 597; RV64IDZFH: # %bb.0: 598; RV64IDZFH-NEXT: fcvt.h.d fa0, fa0 599; RV64IDZFH-NEXT: ret 600 %1 = call half @llvm.experimental.constrained.fptrunc.f16.f64(double %a, metadata !"round.dynamic", metadata !"fpexcept.strict") 601 ret half %1 602} 603declare half @llvm.experimental.constrained.fptrunc.f16.f64(double, metadata, metadata) 604 605define double @fcvt_d_h(half %a) nounwind strictfp { 606; RV32IZFH-LABEL: fcvt_d_h: 607; RV32IZFH: # %bb.0: 608; RV32IZFH-NEXT: addi sp, sp, -16 609; RV32IZFH-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 610; RV32IZFH-NEXT: fcvt.s.h fa0, fa0 611; RV32IZFH-NEXT: call __extendsfdf2@plt 612; RV32IZFH-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 613; RV32IZFH-NEXT: addi sp, sp, 16 614; RV32IZFH-NEXT: ret 615; 616; RV64IZFH-LABEL: fcvt_d_h: 617; RV64IZFH: # %bb.0: 618; RV64IZFH-NEXT: addi sp, sp, -16 619; RV64IZFH-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 620; RV64IZFH-NEXT: fcvt.s.h fa0, fa0 621; RV64IZFH-NEXT: call __extendsfdf2@plt 622; RV64IZFH-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 623; RV64IZFH-NEXT: addi sp, sp, 16 624; RV64IZFH-NEXT: ret 625; 626; RV32IDZFH-LABEL: fcvt_d_h: 627; RV32IDZFH: # %bb.0: 628; RV32IDZFH-NEXT: fcvt.d.h fa0, fa0 629; RV32IDZFH-NEXT: ret 630; 631; RV64IDZFH-LABEL: fcvt_d_h: 632; RV64IDZFH: # %bb.0: 633; RV64IDZFH-NEXT: fcvt.d.h fa0, fa0 634; RV64IDZFH-NEXT: ret 635 %1 = call double @llvm.experimental.constrained.fpext.f64.f16(half %a, metadata !"fpexcept.strict") 636 ret double %1 637} 638declare double @llvm.experimental.constrained.fpext.f64.f16(half, metadata) 639 640; Make sure we select W version of addi on RV64. 641define signext i32 @fcvt_h_w_demanded_bits(i32 signext %0, half* %1) { 642; RV32IZFH-LABEL: fcvt_h_w_demanded_bits: 643; RV32IZFH: # %bb.0: 644; RV32IZFH-NEXT: addi a0, a0, 1 645; RV32IZFH-NEXT: fcvt.h.w ft0, a0 646; RV32IZFH-NEXT: fsh ft0, 0(a1) 647; RV32IZFH-NEXT: ret 648; 649; RV64IZFH-LABEL: fcvt_h_w_demanded_bits: 650; RV64IZFH: # %bb.0: 651; RV64IZFH-NEXT: addiw a0, a0, 1 652; RV64IZFH-NEXT: fcvt.h.w ft0, a0 653; RV64IZFH-NEXT: fsh ft0, 0(a1) 654; RV64IZFH-NEXT: ret 655; 656; RV32IDZFH-LABEL: fcvt_h_w_demanded_bits: 657; RV32IDZFH: # %bb.0: 658; RV32IDZFH-NEXT: addi a0, a0, 1 659; RV32IDZFH-NEXT: fcvt.h.w ft0, a0 660; RV32IDZFH-NEXT: fsh ft0, 0(a1) 661; RV32IDZFH-NEXT: ret 662; 663; RV64IDZFH-LABEL: fcvt_h_w_demanded_bits: 664; RV64IDZFH: # %bb.0: 665; RV64IDZFH-NEXT: addiw a0, a0, 1 666; RV64IDZFH-NEXT: fcvt.h.w ft0, a0 667; RV64IDZFH-NEXT: fsh ft0, 0(a1) 668; RV64IDZFH-NEXT: ret 669 %3 = add i32 %0, 1 670 %4 = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %3, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 671 store half %4, half* %1, align 2 672 ret i32 %3 673} 674 675; Make sure we select W version of addi on RV64. 676define signext i32 @fcvt_h_wu_demanded_bits(i32 signext %0, half* %1) { 677; RV32IZFH-LABEL: fcvt_h_wu_demanded_bits: 678; RV32IZFH: # %bb.0: 679; RV32IZFH-NEXT: addi a0, a0, 1 680; RV32IZFH-NEXT: fcvt.h.wu ft0, a0 681; RV32IZFH-NEXT: fsh ft0, 0(a1) 682; RV32IZFH-NEXT: ret 683; 684; RV64IZFH-LABEL: fcvt_h_wu_demanded_bits: 685; RV64IZFH: # %bb.0: 686; RV64IZFH-NEXT: addiw a0, a0, 1 687; RV64IZFH-NEXT: fcvt.h.wu ft0, a0 688; RV64IZFH-NEXT: fsh ft0, 0(a1) 689; RV64IZFH-NEXT: ret 690; 691; RV32IDZFH-LABEL: fcvt_h_wu_demanded_bits: 692; RV32IDZFH: # %bb.0: 693; RV32IDZFH-NEXT: addi a0, a0, 1 694; RV32IDZFH-NEXT: fcvt.h.wu ft0, a0 695; RV32IDZFH-NEXT: fsh ft0, 0(a1) 696; RV32IDZFH-NEXT: ret 697; 698; RV64IDZFH-LABEL: fcvt_h_wu_demanded_bits: 699; RV64IDZFH: # %bb.0: 700; RV64IDZFH-NEXT: addiw a0, a0, 1 701; RV64IDZFH-NEXT: fcvt.h.wu ft0, a0 702; RV64IDZFH-NEXT: fsh ft0, 0(a1) 703; RV64IDZFH-NEXT: ret 704 %3 = add i32 %0, 1 705 %4 = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %3, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 706 store half %4, half* %1, align 2 707 ret i32 %3 708} 709