1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -mattr=+zfh -verify-machineinstrs \ 3; RUN: -disable-strictnode-mutation -target-abi ilp32f < %s | FileCheck %s 4; RUN: llc -mtriple=riscv64 -mattr=+zfh -verify-machineinstrs \ 5; RUN: -disable-strictnode-mutation -target-abi lp64f < %s | FileCheck %s 6; RUN: llc -mtriple=riscv32 -mattr=+zhinx -verify-machineinstrs \ 7; RUN: -disable-strictnode-mutation -target-abi ilp32 < %s \ 8; RUN: | FileCheck -check-prefix=CHECK-ZHINX %s 9; RUN: llc -mtriple=riscv64 -mattr=+zhinx -verify-machineinstrs \ 10; RUN: -disable-strictnode-mutation -target-abi lp64 < %s \ 11; RUN: | FileCheck -check-prefix=CHECK-ZHINX %s 12; RUN: llc -mtriple=riscv32 -mattr=+zfhmin -verify-machineinstrs \ 13; RUN: -disable-strictnode-mutation -target-abi ilp32f < %s \ 14; RUN: | FileCheck -check-prefixes=CHECK-ZFHMIN,CHECK-ZFHMIN-RV32 %s 15; RUN: llc -mtriple=riscv64 -mattr=+zfhmin -verify-machineinstrs \ 16; RUN: -disable-strictnode-mutation -target-abi lp64f < %s \ 17; RUN: | FileCheck -check-prefixes=CHECK-ZFHMIN,CHECK-ZFHMIN-RV64 %s 18; RUN: llc -mtriple=riscv32 -mattr=+zhinxmin -verify-machineinstrs \ 19; RUN: -disable-strictnode-mutation -target-abi ilp32 < %s \ 20; RUN: | FileCheck -check-prefixes=CHECK-ZHINXMIN,CHECK-ZHINXMIN-RV32 %s 21; RUN: llc -mtriple=riscv64 -mattr=+zhinxmin -verify-machineinstrs \ 22; RUN: -disable-strictnode-mutation -target-abi lp64 < %s \ 23; RUN: | FileCheck -check-prefixes=CHECK-ZHINXMIN,CHECK-ZHINXMIN-RV64 %s 24 25; FIXME: We can't test without Zfh because soft promote legalization isn't 26; implemented in SelectionDAG for STRICT nodes. 27 28define half @fadd_h(half %a, half %b) nounwind strictfp { 29; CHECK-LABEL: fadd_h: 30; CHECK: # %bb.0: 31; CHECK-NEXT: fadd.h fa0, fa0, fa1 32; CHECK-NEXT: ret 33; 34; CHECK-ZHINX-LABEL: fadd_h: 35; CHECK-ZHINX: # %bb.0: 36; CHECK-ZHINX-NEXT: fadd.h a0, a0, a1 37; CHECK-ZHINX-NEXT: ret 38; 39; CHECK-ZFHMIN-LABEL: fadd_h: 40; CHECK-ZFHMIN: # %bb.0: 41; CHECK-ZFHMIN-NEXT: fcvt.s.h fa5, fa1 42; CHECK-ZFHMIN-NEXT: fcvt.s.h fa4, fa0 43; CHECK-ZFHMIN-NEXT: fadd.s fa5, fa4, fa5 44; CHECK-ZFHMIN-NEXT: fcvt.h.s fa0, fa5 45; CHECK-ZFHMIN-NEXT: ret 46; 47; CHECK-ZHINXMIN-LABEL: fadd_h: 48; CHECK-ZHINXMIN: # %bb.0: 49; CHECK-ZHINXMIN-NEXT: fcvt.s.h a1, a1 50; CHECK-ZHINXMIN-NEXT: fcvt.s.h a0, a0 51; CHECK-ZHINXMIN-NEXT: fadd.s a0, a0, a1 52; CHECK-ZHINXMIN-NEXT: fcvt.h.s a0, a0 53; CHECK-ZHINXMIN-NEXT: ret 54 %1 = call half @llvm.experimental.constrained.fadd.f16(half %a, half %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 55 ret half %1 56} 57declare half @llvm.experimental.constrained.fadd.f16(half, half, metadata, metadata) 58 59define half @fsub_h(half %a, half %b) nounwind strictfp { 60; CHECK-LABEL: fsub_h: 61; CHECK: # %bb.0: 62; CHECK-NEXT: fsub.h fa0, fa0, fa1 63; CHECK-NEXT: ret 64; 65; CHECK-ZHINX-LABEL: fsub_h: 66; CHECK-ZHINX: # %bb.0: 67; CHECK-ZHINX-NEXT: fsub.h a0, a0, a1 68; CHECK-ZHINX-NEXT: ret 69; 70; CHECK-ZFHMIN-LABEL: fsub_h: 71; CHECK-ZFHMIN: # %bb.0: 72; CHECK-ZFHMIN-NEXT: fcvt.s.h fa5, fa1 73; CHECK-ZFHMIN-NEXT: fcvt.s.h fa4, fa0 74; CHECK-ZFHMIN-NEXT: fsub.s fa5, fa4, fa5 75; CHECK-ZFHMIN-NEXT: fcvt.h.s fa0, fa5 76; CHECK-ZFHMIN-NEXT: ret 77; 78; CHECK-ZHINXMIN-LABEL: fsub_h: 79; CHECK-ZHINXMIN: # %bb.0: 80; CHECK-ZHINXMIN-NEXT: fcvt.s.h a1, a1 81; CHECK-ZHINXMIN-NEXT: fcvt.s.h a0, a0 82; CHECK-ZHINXMIN-NEXT: fsub.s a0, a0, a1 83; CHECK-ZHINXMIN-NEXT: fcvt.h.s a0, a0 84; CHECK-ZHINXMIN-NEXT: ret 85 %1 = call half @llvm.experimental.constrained.fsub.f16(half %a, half %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 86 ret half %1 87} 88declare half @llvm.experimental.constrained.fsub.f16(half, half, metadata, metadata) 89 90define half @fmul_h(half %a, half %b) nounwind strictfp { 91; CHECK-LABEL: fmul_h: 92; CHECK: # %bb.0: 93; CHECK-NEXT: fmul.h fa0, fa0, fa1 94; CHECK-NEXT: ret 95; 96; CHECK-ZHINX-LABEL: fmul_h: 97; CHECK-ZHINX: # %bb.0: 98; CHECK-ZHINX-NEXT: fmul.h a0, a0, a1 99; CHECK-ZHINX-NEXT: ret 100; 101; CHECK-ZFHMIN-LABEL: fmul_h: 102; CHECK-ZFHMIN: # %bb.0: 103; CHECK-ZFHMIN-NEXT: fcvt.s.h fa5, fa1 104; CHECK-ZFHMIN-NEXT: fcvt.s.h fa4, fa0 105; CHECK-ZFHMIN-NEXT: fmul.s fa5, fa4, fa5 106; CHECK-ZFHMIN-NEXT: fcvt.h.s fa0, fa5 107; CHECK-ZFHMIN-NEXT: ret 108; 109; CHECK-ZHINXMIN-LABEL: fmul_h: 110; CHECK-ZHINXMIN: # %bb.0: 111; CHECK-ZHINXMIN-NEXT: fcvt.s.h a1, a1 112; CHECK-ZHINXMIN-NEXT: fcvt.s.h a0, a0 113; CHECK-ZHINXMIN-NEXT: fmul.s a0, a0, a1 114; CHECK-ZHINXMIN-NEXT: fcvt.h.s a0, a0 115; CHECK-ZHINXMIN-NEXT: ret 116 %1 = call half @llvm.experimental.constrained.fmul.f16(half %a, half %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 117 ret half %1 118} 119declare half @llvm.experimental.constrained.fmul.f16(half, half, metadata, metadata) 120 121define half @fdiv_h(half %a, half %b) nounwind strictfp { 122; CHECK-LABEL: fdiv_h: 123; CHECK: # %bb.0: 124; CHECK-NEXT: fdiv.h fa0, fa0, fa1 125; CHECK-NEXT: ret 126; 127; CHECK-ZHINX-LABEL: fdiv_h: 128; CHECK-ZHINX: # %bb.0: 129; CHECK-ZHINX-NEXT: fdiv.h a0, a0, a1 130; CHECK-ZHINX-NEXT: ret 131; 132; CHECK-ZFHMIN-LABEL: fdiv_h: 133; CHECK-ZFHMIN: # %bb.0: 134; CHECK-ZFHMIN-NEXT: fcvt.s.h fa5, fa1 135; CHECK-ZFHMIN-NEXT: fcvt.s.h fa4, fa0 136; CHECK-ZFHMIN-NEXT: fdiv.s fa5, fa4, fa5 137; CHECK-ZFHMIN-NEXT: fcvt.h.s fa0, fa5 138; CHECK-ZFHMIN-NEXT: ret 139; 140; CHECK-ZHINXMIN-LABEL: fdiv_h: 141; CHECK-ZHINXMIN: # %bb.0: 142; CHECK-ZHINXMIN-NEXT: fcvt.s.h a1, a1 143; CHECK-ZHINXMIN-NEXT: fcvt.s.h a0, a0 144; CHECK-ZHINXMIN-NEXT: fdiv.s a0, a0, a1 145; CHECK-ZHINXMIN-NEXT: fcvt.h.s a0, a0 146; CHECK-ZHINXMIN-NEXT: ret 147 %1 = call half @llvm.experimental.constrained.fdiv.f16(half %a, half %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 148 ret half %1 149} 150declare half @llvm.experimental.constrained.fdiv.f16(half, half, metadata, metadata) 151 152define half @fsqrt_h(half %a) nounwind strictfp { 153; CHECK-LABEL: fsqrt_h: 154; CHECK: # %bb.0: 155; CHECK-NEXT: fsqrt.h fa0, fa0 156; CHECK-NEXT: ret 157; 158; CHECK-ZHINX-LABEL: fsqrt_h: 159; CHECK-ZHINX: # %bb.0: 160; CHECK-ZHINX-NEXT: fsqrt.h a0, a0 161; CHECK-ZHINX-NEXT: ret 162; 163; CHECK-ZFHMIN-LABEL: fsqrt_h: 164; CHECK-ZFHMIN: # %bb.0: 165; CHECK-ZFHMIN-NEXT: fcvt.s.h fa5, fa0 166; CHECK-ZFHMIN-NEXT: fsqrt.s fa5, fa5 167; CHECK-ZFHMIN-NEXT: fcvt.h.s fa0, fa5 168; CHECK-ZFHMIN-NEXT: ret 169; 170; CHECK-ZHINXMIN-LABEL: fsqrt_h: 171; CHECK-ZHINXMIN: # %bb.0: 172; CHECK-ZHINXMIN-NEXT: fcvt.s.h a0, a0 173; CHECK-ZHINXMIN-NEXT: fsqrt.s a0, a0 174; CHECK-ZHINXMIN-NEXT: fcvt.h.s a0, a0 175; CHECK-ZHINXMIN-NEXT: ret 176 %1 = call half @llvm.experimental.constrained.sqrt.f16(half %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 177 ret half %1 178} 179declare half @llvm.experimental.constrained.sqrt.f16(half, metadata, metadata) 180 181; FIXME: fminnum/fmaxnum need libcalls to handle SNaN, but we don't have f16 182; libcalls and don't support promotion yet. 183;define half @fmin_h(half %a, half %b) nounwind strictfp { 184; %1 = call half @llvm.experimental.constrained.minnum.f16(half %a, half %b, metadata !"fpexcept.strict") strictfp 185; ret half %1 186;} 187;declare half @llvm.experimental.constrained.minnum.f16(half, half, metadata) strictfp 188; 189;define half @fmax_h(half %a, half %b) nounwind strictfp { 190; %1 = call half @llvm.experimental.constrained.maxnum.f16(half %a, half %b, metadata !"fpexcept.strict") strictfp 191; ret half %1 192;} 193;declare half @llvm.experimental.constrained.maxnum.f16(half, half, metadata) strictfp 194 195define half @fmadd_h(half %a, half %b, half %c) nounwind strictfp { 196; CHECK-LABEL: fmadd_h: 197; CHECK: # %bb.0: 198; CHECK-NEXT: fmadd.h fa0, fa0, fa1, fa2 199; CHECK-NEXT: ret 200; 201; CHECK-ZHINX-LABEL: fmadd_h: 202; CHECK-ZHINX: # %bb.0: 203; CHECK-ZHINX-NEXT: fmadd.h a0, a0, a1, a2 204; CHECK-ZHINX-NEXT: ret 205; 206; CHECK-ZFHMIN-LABEL: fmadd_h: 207; CHECK-ZFHMIN: # %bb.0: 208; CHECK-ZFHMIN-NEXT: fcvt.s.h fa5, fa2 209; CHECK-ZFHMIN-NEXT: fcvt.s.h fa4, fa1 210; CHECK-ZFHMIN-NEXT: fcvt.s.h fa3, fa0 211; CHECK-ZFHMIN-NEXT: fmadd.s fa5, fa3, fa4, fa5 212; CHECK-ZFHMIN-NEXT: fcvt.h.s fa0, fa5 213; CHECK-ZFHMIN-NEXT: ret 214; 215; CHECK-ZHINXMIN-LABEL: fmadd_h: 216; CHECK-ZHINXMIN: # %bb.0: 217; CHECK-ZHINXMIN-NEXT: fcvt.s.h a2, a2 218; CHECK-ZHINXMIN-NEXT: fcvt.s.h a1, a1 219; CHECK-ZHINXMIN-NEXT: fcvt.s.h a0, a0 220; CHECK-ZHINXMIN-NEXT: fmadd.s a0, a0, a1, a2 221; CHECK-ZHINXMIN-NEXT: fcvt.h.s a0, a0 222; CHECK-ZHINXMIN-NEXT: ret 223 %1 = call half @llvm.experimental.constrained.fma.f16(half %a, half %b, half %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 224 ret half %1 225} 226declare half @llvm.experimental.constrained.fma.f16(half, half, half, metadata, metadata) strictfp 227 228define half @fmsub_h(half %a, half %b, half %c) nounwind strictfp { 229; CHECK-LABEL: fmsub_h: 230; CHECK: # %bb.0: 231; CHECK-NEXT: fmv.h.x fa5, zero 232; CHECK-NEXT: fadd.h fa5, fa2, fa5 233; CHECK-NEXT: fmsub.h fa0, fa0, fa1, fa5 234; CHECK-NEXT: ret 235; 236; CHECK-ZHINX-LABEL: fmsub_h: 237; CHECK-ZHINX: # %bb.0: 238; CHECK-ZHINX-NEXT: fadd.h a2, a2, zero 239; CHECK-ZHINX-NEXT: fmsub.h a0, a0, a1, a2 240; CHECK-ZHINX-NEXT: ret 241; 242; CHECK-ZFHMIN-LABEL: fmsub_h: 243; CHECK-ZFHMIN: # %bb.0: 244; CHECK-ZFHMIN-NEXT: fcvt.s.h fa5, fa2 245; CHECK-ZFHMIN-NEXT: fmv.w.x fa4, zero 246; CHECK-ZFHMIN-NEXT: lui a0, 1048568 247; CHECK-ZFHMIN-NEXT: fcvt.s.h fa3, fa1 248; CHECK-ZFHMIN-NEXT: fadd.s fa5, fa5, fa4 249; CHECK-ZFHMIN-NEXT: fcvt.h.s fa5, fa5 250; CHECK-ZFHMIN-NEXT: fmv.x.h a1, fa5 251; CHECK-ZFHMIN-NEXT: xor a0, a1, a0 252; CHECK-ZFHMIN-NEXT: fmv.h.x fa5, a0 253; CHECK-ZFHMIN-NEXT: fcvt.s.h fa5, fa5 254; CHECK-ZFHMIN-NEXT: fcvt.s.h fa4, fa0 255; CHECK-ZFHMIN-NEXT: fmadd.s fa5, fa4, fa3, fa5 256; CHECK-ZFHMIN-NEXT: fcvt.h.s fa0, fa5 257; CHECK-ZFHMIN-NEXT: ret 258; 259; CHECK-ZHINXMIN-LABEL: fmsub_h: 260; CHECK-ZHINXMIN: # %bb.0: 261; CHECK-ZHINXMIN-NEXT: fcvt.s.h a2, a2 262; CHECK-ZHINXMIN-NEXT: lui a3, 1048568 263; CHECK-ZHINXMIN-NEXT: fcvt.s.h a1, a1 264; CHECK-ZHINXMIN-NEXT: fadd.s a2, a2, zero 265; CHECK-ZHINXMIN-NEXT: fcvt.h.s a2, a2 266; CHECK-ZHINXMIN-NEXT: xor a2, a2, a3 267; CHECK-ZHINXMIN-NEXT: fcvt.s.h a2, a2 268; CHECK-ZHINXMIN-NEXT: fcvt.s.h a0, a0 269; CHECK-ZHINXMIN-NEXT: fmadd.s a0, a0, a1, a2 270; CHECK-ZHINXMIN-NEXT: fcvt.h.s a0, a0 271; CHECK-ZHINXMIN-NEXT: ret 272 %c_ = fadd half 0.0, %c ; avoid negation using xor 273 %negc = fneg half %c_ 274 %1 = call half @llvm.experimental.constrained.fma.f16(half %a, half %b, half %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 275 ret half %1 276} 277 278define half @fnmadd_h(half %a, half %b, half %c) nounwind strictfp { 279; CHECK-LABEL: fnmadd_h: 280; CHECK: # %bb.0: 281; CHECK-NEXT: fmv.h.x fa5, zero 282; CHECK-NEXT: fadd.h fa4, fa0, fa5 283; CHECK-NEXT: fadd.h fa5, fa2, fa5 284; CHECK-NEXT: fnmadd.h fa0, fa4, fa1, fa5 285; CHECK-NEXT: ret 286; 287; CHECK-ZHINX-LABEL: fnmadd_h: 288; CHECK-ZHINX: # %bb.0: 289; CHECK-ZHINX-NEXT: fadd.h a0, a0, zero 290; CHECK-ZHINX-NEXT: fadd.h a2, a2, zero 291; CHECK-ZHINX-NEXT: fnmadd.h a0, a0, a1, a2 292; CHECK-ZHINX-NEXT: ret 293; 294; CHECK-ZFHMIN-LABEL: fnmadd_h: 295; CHECK-ZFHMIN: # %bb.0: 296; CHECK-ZFHMIN-NEXT: fcvt.s.h fa5, fa0 297; CHECK-ZFHMIN-NEXT: fmv.w.x fa4, zero 298; CHECK-ZFHMIN-NEXT: fcvt.s.h fa3, fa2 299; CHECK-ZFHMIN-NEXT: lui a0, 1048568 300; CHECK-ZFHMIN-NEXT: fadd.s fa5, fa5, fa4 301; CHECK-ZFHMIN-NEXT: fadd.s fa4, fa3, fa4 302; CHECK-ZFHMIN-NEXT: fcvt.h.s fa5, fa5 303; CHECK-ZFHMIN-NEXT: fcvt.h.s fa4, fa4 304; CHECK-ZFHMIN-NEXT: fmv.x.h a1, fa5 305; CHECK-ZFHMIN-NEXT: fmv.x.h a2, fa4 306; CHECK-ZFHMIN-NEXT: xor a1, a1, a0 307; CHECK-ZFHMIN-NEXT: xor a0, a2, a0 308; CHECK-ZFHMIN-NEXT: fmv.h.x fa5, a1 309; CHECK-ZFHMIN-NEXT: fmv.h.x fa4, a0 310; CHECK-ZFHMIN-NEXT: fcvt.s.h fa4, fa4 311; CHECK-ZFHMIN-NEXT: fcvt.s.h fa5, fa5 312; CHECK-ZFHMIN-NEXT: fcvt.s.h fa3, fa1 313; CHECK-ZFHMIN-NEXT: fmadd.s fa5, fa5, fa3, fa4 314; CHECK-ZFHMIN-NEXT: fcvt.h.s fa0, fa5 315; CHECK-ZFHMIN-NEXT: ret 316; 317; CHECK-ZHINXMIN-LABEL: fnmadd_h: 318; CHECK-ZHINXMIN: # %bb.0: 319; CHECK-ZHINXMIN-NEXT: fcvt.s.h a0, a0 320; CHECK-ZHINXMIN-NEXT: fcvt.s.h a2, a2 321; CHECK-ZHINXMIN-NEXT: lui a3, 1048568 322; CHECK-ZHINXMIN-NEXT: fadd.s a0, a0, zero 323; CHECK-ZHINXMIN-NEXT: fadd.s a2, a2, zero 324; CHECK-ZHINXMIN-NEXT: fcvt.h.s a0, a0 325; CHECK-ZHINXMIN-NEXT: fcvt.h.s a2, a2 326; CHECK-ZHINXMIN-NEXT: xor a0, a0, a3 327; CHECK-ZHINXMIN-NEXT: xor a2, a2, a3 328; CHECK-ZHINXMIN-NEXT: fcvt.s.h a2, a2 329; CHECK-ZHINXMIN-NEXT: fcvt.s.h a0, a0 330; CHECK-ZHINXMIN-NEXT: fcvt.s.h a1, a1 331; CHECK-ZHINXMIN-NEXT: fmadd.s a0, a0, a1, a2 332; CHECK-ZHINXMIN-NEXT: fcvt.h.s a0, a0 333; CHECK-ZHINXMIN-NEXT: ret 334 %a_ = fadd half 0.0, %a 335 %c_ = fadd half 0.0, %c 336 %nega = fneg half %a_ 337 %negc = fneg half %c_ 338 %1 = call half @llvm.experimental.constrained.fma.f16(half %nega, half %b, half %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 339 ret half %1 340} 341 342define half @fnmadd_h_2(half %a, half %b, half %c) nounwind strictfp { 343; CHECK-LABEL: fnmadd_h_2: 344; CHECK: # %bb.0: 345; CHECK-NEXT: fmv.h.x fa5, zero 346; CHECK-NEXT: fadd.h fa4, fa1, fa5 347; CHECK-NEXT: fadd.h fa5, fa2, fa5 348; CHECK-NEXT: fnmadd.h fa0, fa4, fa0, fa5 349; CHECK-NEXT: ret 350; 351; CHECK-ZHINX-LABEL: fnmadd_h_2: 352; CHECK-ZHINX: # %bb.0: 353; CHECK-ZHINX-NEXT: fadd.h a1, a1, zero 354; CHECK-ZHINX-NEXT: fadd.h a2, a2, zero 355; CHECK-ZHINX-NEXT: fnmadd.h a0, a1, a0, a2 356; CHECK-ZHINX-NEXT: ret 357; 358; CHECK-ZFHMIN-LABEL: fnmadd_h_2: 359; CHECK-ZFHMIN: # %bb.0: 360; CHECK-ZFHMIN-NEXT: fcvt.s.h fa5, fa1 361; CHECK-ZFHMIN-NEXT: fmv.w.x fa4, zero 362; CHECK-ZFHMIN-NEXT: fcvt.s.h fa3, fa2 363; CHECK-ZFHMIN-NEXT: lui a0, 1048568 364; CHECK-ZFHMIN-NEXT: fadd.s fa5, fa5, fa4 365; CHECK-ZFHMIN-NEXT: fadd.s fa4, fa3, fa4 366; CHECK-ZFHMIN-NEXT: fcvt.h.s fa5, fa5 367; CHECK-ZFHMIN-NEXT: fcvt.h.s fa4, fa4 368; CHECK-ZFHMIN-NEXT: fmv.x.h a1, fa5 369; CHECK-ZFHMIN-NEXT: fmv.x.h a2, fa4 370; CHECK-ZFHMIN-NEXT: xor a1, a1, a0 371; CHECK-ZFHMIN-NEXT: xor a0, a2, a0 372; CHECK-ZFHMIN-NEXT: fmv.h.x fa5, a1 373; CHECK-ZFHMIN-NEXT: fmv.h.x fa4, a0 374; CHECK-ZFHMIN-NEXT: fcvt.s.h fa4, fa4 375; CHECK-ZFHMIN-NEXT: fcvt.s.h fa5, fa5 376; CHECK-ZFHMIN-NEXT: fcvt.s.h fa3, fa0 377; CHECK-ZFHMIN-NEXT: fmadd.s fa5, fa3, fa5, fa4 378; CHECK-ZFHMIN-NEXT: fcvt.h.s fa0, fa5 379; CHECK-ZFHMIN-NEXT: ret 380; 381; CHECK-ZHINXMIN-LABEL: fnmadd_h_2: 382; CHECK-ZHINXMIN: # %bb.0: 383; CHECK-ZHINXMIN-NEXT: fcvt.s.h a1, a1 384; CHECK-ZHINXMIN-NEXT: fcvt.s.h a2, a2 385; CHECK-ZHINXMIN-NEXT: lui a3, 1048568 386; CHECK-ZHINXMIN-NEXT: fadd.s a1, a1, zero 387; CHECK-ZHINXMIN-NEXT: fadd.s a2, a2, zero 388; CHECK-ZHINXMIN-NEXT: fcvt.h.s a1, a1 389; CHECK-ZHINXMIN-NEXT: fcvt.h.s a2, a2 390; CHECK-ZHINXMIN-NEXT: xor a1, a1, a3 391; CHECK-ZHINXMIN-NEXT: xor a2, a2, a3 392; CHECK-ZHINXMIN-NEXT: fcvt.s.h a2, a2 393; CHECK-ZHINXMIN-NEXT: fcvt.s.h a1, a1 394; CHECK-ZHINXMIN-NEXT: fcvt.s.h a0, a0 395; CHECK-ZHINXMIN-NEXT: fmadd.s a0, a0, a1, a2 396; CHECK-ZHINXMIN-NEXT: fcvt.h.s a0, a0 397; CHECK-ZHINXMIN-NEXT: ret 398 %b_ = fadd half 0.0, %b 399 %c_ = fadd half 0.0, %c 400 %negb = fneg half %b_ 401 %negc = fneg half %c_ 402 %1 = call half @llvm.experimental.constrained.fma.f16(half %a, half %negb, half %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 403 ret half %1 404} 405 406define half @fnmsub_h(half %a, half %b, half %c) nounwind strictfp { 407; CHECK-LABEL: fnmsub_h: 408; CHECK: # %bb.0: 409; CHECK-NEXT: fmv.h.x fa5, zero 410; CHECK-NEXT: fadd.h fa5, fa0, fa5 411; CHECK-NEXT: fnmsub.h fa0, fa5, fa1, fa2 412; CHECK-NEXT: ret 413; 414; CHECK-ZHINX-LABEL: fnmsub_h: 415; CHECK-ZHINX: # %bb.0: 416; CHECK-ZHINX-NEXT: fadd.h a0, a0, zero 417; CHECK-ZHINX-NEXT: fnmsub.h a0, a0, a1, a2 418; CHECK-ZHINX-NEXT: ret 419; 420; CHECK-ZFHMIN-LABEL: fnmsub_h: 421; CHECK-ZFHMIN: # %bb.0: 422; CHECK-ZFHMIN-NEXT: fcvt.s.h fa5, fa0 423; CHECK-ZFHMIN-NEXT: fmv.w.x fa4, zero 424; CHECK-ZFHMIN-NEXT: lui a0, 1048568 425; CHECK-ZFHMIN-NEXT: fcvt.s.h fa3, fa2 426; CHECK-ZFHMIN-NEXT: fadd.s fa5, fa5, fa4 427; CHECK-ZFHMIN-NEXT: fcvt.h.s fa5, fa5 428; CHECK-ZFHMIN-NEXT: fmv.x.h a1, fa5 429; CHECK-ZFHMIN-NEXT: xor a0, a1, a0 430; CHECK-ZFHMIN-NEXT: fmv.h.x fa5, a0 431; CHECK-ZFHMIN-NEXT: fcvt.s.h fa5, fa5 432; CHECK-ZFHMIN-NEXT: fcvt.s.h fa4, fa1 433; CHECK-ZFHMIN-NEXT: fmadd.s fa5, fa5, fa4, fa3 434; CHECK-ZFHMIN-NEXT: fcvt.h.s fa0, fa5 435; CHECK-ZFHMIN-NEXT: ret 436; 437; CHECK-ZHINXMIN-LABEL: fnmsub_h: 438; CHECK-ZHINXMIN: # %bb.0: 439; CHECK-ZHINXMIN-NEXT: fcvt.s.h a0, a0 440; CHECK-ZHINXMIN-NEXT: lui a3, 1048568 441; CHECK-ZHINXMIN-NEXT: fcvt.s.h a2, a2 442; CHECK-ZHINXMIN-NEXT: fadd.s a0, a0, zero 443; CHECK-ZHINXMIN-NEXT: fcvt.h.s a0, a0 444; CHECK-ZHINXMIN-NEXT: xor a0, a0, a3 445; CHECK-ZHINXMIN-NEXT: fcvt.s.h a0, a0 446; CHECK-ZHINXMIN-NEXT: fcvt.s.h a1, a1 447; CHECK-ZHINXMIN-NEXT: fmadd.s a0, a0, a1, a2 448; CHECK-ZHINXMIN-NEXT: fcvt.h.s a0, a0 449; CHECK-ZHINXMIN-NEXT: ret 450 %a_ = fadd half 0.0, %a 451 %nega = fneg half %a_ 452 %1 = call half @llvm.experimental.constrained.fma.f16(half %nega, half %b, half %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 453 ret half %1 454} 455 456define half @fnmsub_h_2(half %a, half %b, half %c) nounwind strictfp { 457; CHECK-LABEL: fnmsub_h_2: 458; CHECK: # %bb.0: 459; CHECK-NEXT: fmv.h.x fa5, zero 460; CHECK-NEXT: fadd.h fa5, fa1, fa5 461; CHECK-NEXT: fnmsub.h fa0, fa5, fa0, fa2 462; CHECK-NEXT: ret 463; 464; CHECK-ZHINX-LABEL: fnmsub_h_2: 465; CHECK-ZHINX: # %bb.0: 466; CHECK-ZHINX-NEXT: fadd.h a1, a1, zero 467; CHECK-ZHINX-NEXT: fnmsub.h a0, a1, a0, a2 468; CHECK-ZHINX-NEXT: ret 469; 470; CHECK-ZFHMIN-LABEL: fnmsub_h_2: 471; CHECK-ZFHMIN: # %bb.0: 472; CHECK-ZFHMIN-NEXT: fcvt.s.h fa5, fa1 473; CHECK-ZFHMIN-NEXT: fmv.w.x fa4, zero 474; CHECK-ZFHMIN-NEXT: lui a0, 1048568 475; CHECK-ZFHMIN-NEXT: fcvt.s.h fa3, fa2 476; CHECK-ZFHMIN-NEXT: fadd.s fa5, fa5, fa4 477; CHECK-ZFHMIN-NEXT: fcvt.h.s fa5, fa5 478; CHECK-ZFHMIN-NEXT: fmv.x.h a1, fa5 479; CHECK-ZFHMIN-NEXT: xor a0, a1, a0 480; CHECK-ZFHMIN-NEXT: fmv.h.x fa5, a0 481; CHECK-ZFHMIN-NEXT: fcvt.s.h fa5, fa5 482; CHECK-ZFHMIN-NEXT: fcvt.s.h fa4, fa0 483; CHECK-ZFHMIN-NEXT: fmadd.s fa5, fa4, fa5, fa3 484; CHECK-ZFHMIN-NEXT: fcvt.h.s fa0, fa5 485; CHECK-ZFHMIN-NEXT: ret 486; 487; CHECK-ZHINXMIN-LABEL: fnmsub_h_2: 488; CHECK-ZHINXMIN: # %bb.0: 489; CHECK-ZHINXMIN-NEXT: fcvt.s.h a1, a1 490; CHECK-ZHINXMIN-NEXT: lui a3, 1048568 491; CHECK-ZHINXMIN-NEXT: fcvt.s.h a2, a2 492; CHECK-ZHINXMIN-NEXT: fadd.s a1, a1, zero 493; CHECK-ZHINXMIN-NEXT: fcvt.h.s a1, a1 494; CHECK-ZHINXMIN-NEXT: xor a1, a1, a3 495; CHECK-ZHINXMIN-NEXT: fcvt.s.h a1, a1 496; CHECK-ZHINXMIN-NEXT: fcvt.s.h a0, a0 497; CHECK-ZHINXMIN-NEXT: fmadd.s a0, a0, a1, a2 498; CHECK-ZHINXMIN-NEXT: fcvt.h.s a0, a0 499; CHECK-ZHINXMIN-NEXT: ret 500 %b_ = fadd half 0.0, %b 501 %negb = fneg half %b_ 502 %1 = call half @llvm.experimental.constrained.fma.f16(half %a, half %negb, half %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 503 ret half %1 504} 505;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: 506; CHECK-ZFHMIN-RV32: {{.*}} 507; CHECK-ZFHMIN-RV64: {{.*}} 508; CHECK-ZHINXMIN-RV32: {{.*}} 509; CHECK-ZHINXMIN-RV64: {{.*}} 510