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 < %s | FileCheck -check-prefix=CHECKIZFH %s 4; RUN: llc -mtriple=riscv64 -mattr=+zfh -verify-machineinstrs \ 5; RUN: -target-abi lp64f < %s | FileCheck -check-prefix=CHECKIZFH %s 6; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ 7; RUN: | FileCheck -check-prefix=RV32I %s 8; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ 9; RUN: | FileCheck -check-prefix=RV64I %s 10 11; These tests are each targeted at a particular RISC-V FPU instruction. 12; Compares and conversions can be found in half-fcmp.ll and half-convert.ll 13; respectively. Some other half-*.ll files in this folder exercise LLVM IR 14; instructions that don't directly match a RISC-V instruction. 15 16define half @fadd_s(half %a, half %b) nounwind { 17; CHECKIZFH-LABEL: fadd_s: 18; CHECKIZFH: # %bb.0: 19; CHECKIZFH-NEXT: fadd.h fa0, fa0, fa1 20; CHECKIZFH-NEXT: ret 21; 22; RV32I-LABEL: fadd_s: 23; RV32I: # %bb.0: 24; RV32I-NEXT: addi sp, sp, -16 25; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 26; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 27; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 28; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 29; RV32I-NEXT: mv s0, a1 30; RV32I-NEXT: lui a1, 16 31; RV32I-NEXT: addi s2, a1, -1 32; RV32I-NEXT: and a0, a0, s2 33; RV32I-NEXT: call __extendhfsf2@plt 34; RV32I-NEXT: mv s1, a0 35; RV32I-NEXT: and a0, s0, s2 36; RV32I-NEXT: call __extendhfsf2@plt 37; RV32I-NEXT: mv a1, a0 38; RV32I-NEXT: mv a0, s1 39; RV32I-NEXT: call __addsf3@plt 40; RV32I-NEXT: call __truncsfhf2@plt 41; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 42; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 43; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 44; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 45; RV32I-NEXT: addi sp, sp, 16 46; RV32I-NEXT: ret 47; 48; RV64I-LABEL: fadd_s: 49; RV64I: # %bb.0: 50; RV64I-NEXT: addi sp, sp, -32 51; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 52; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 53; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 54; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 55; RV64I-NEXT: mv s0, a1 56; RV64I-NEXT: lui a1, 16 57; RV64I-NEXT: addiw s2, a1, -1 58; RV64I-NEXT: and a0, a0, s2 59; RV64I-NEXT: call __extendhfsf2@plt 60; RV64I-NEXT: mv s1, a0 61; RV64I-NEXT: and a0, s0, s2 62; RV64I-NEXT: call __extendhfsf2@plt 63; RV64I-NEXT: mv a1, a0 64; RV64I-NEXT: mv a0, s1 65; RV64I-NEXT: call __addsf3@plt 66; RV64I-NEXT: call __truncsfhf2@plt 67; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 68; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 69; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 70; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 71; RV64I-NEXT: addi sp, sp, 32 72; RV64I-NEXT: ret 73 %1 = fadd half %a, %b 74 ret half %1 75} 76 77define half @fsub_s(half %a, half %b) nounwind { 78; CHECKIZFH-LABEL: fsub_s: 79; CHECKIZFH: # %bb.0: 80; CHECKIZFH-NEXT: fsub.h fa0, fa0, fa1 81; CHECKIZFH-NEXT: ret 82; 83; RV32I-LABEL: fsub_s: 84; RV32I: # %bb.0: 85; RV32I-NEXT: addi sp, sp, -16 86; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 87; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 88; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 89; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 90; RV32I-NEXT: mv s0, a1 91; RV32I-NEXT: lui a1, 16 92; RV32I-NEXT: addi s2, a1, -1 93; RV32I-NEXT: and a0, a0, s2 94; RV32I-NEXT: call __extendhfsf2@plt 95; RV32I-NEXT: mv s1, a0 96; RV32I-NEXT: and a0, s0, s2 97; RV32I-NEXT: call __extendhfsf2@plt 98; RV32I-NEXT: mv a1, a0 99; RV32I-NEXT: mv a0, s1 100; RV32I-NEXT: call __subsf3@plt 101; RV32I-NEXT: call __truncsfhf2@plt 102; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 103; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 104; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 105; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 106; RV32I-NEXT: addi sp, sp, 16 107; RV32I-NEXT: ret 108; 109; RV64I-LABEL: fsub_s: 110; RV64I: # %bb.0: 111; RV64I-NEXT: addi sp, sp, -32 112; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 113; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 114; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 115; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 116; RV64I-NEXT: mv s0, a1 117; RV64I-NEXT: lui a1, 16 118; RV64I-NEXT: addiw s2, a1, -1 119; RV64I-NEXT: and a0, a0, s2 120; RV64I-NEXT: call __extendhfsf2@plt 121; RV64I-NEXT: mv s1, a0 122; RV64I-NEXT: and a0, s0, s2 123; RV64I-NEXT: call __extendhfsf2@plt 124; RV64I-NEXT: mv a1, a0 125; RV64I-NEXT: mv a0, s1 126; RV64I-NEXT: call __subsf3@plt 127; RV64I-NEXT: call __truncsfhf2@plt 128; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 129; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 130; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 131; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 132; RV64I-NEXT: addi sp, sp, 32 133; RV64I-NEXT: ret 134 %1 = fsub half %a, %b 135 ret half %1 136} 137 138define half @fmul_s(half %a, half %b) nounwind { 139; CHECKIZFH-LABEL: fmul_s: 140; CHECKIZFH: # %bb.0: 141; CHECKIZFH-NEXT: fmul.h fa0, fa0, fa1 142; CHECKIZFH-NEXT: ret 143; 144; RV32I-LABEL: fmul_s: 145; RV32I: # %bb.0: 146; RV32I-NEXT: addi sp, sp, -16 147; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 148; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 149; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 150; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 151; RV32I-NEXT: mv s0, a1 152; RV32I-NEXT: lui a1, 16 153; RV32I-NEXT: addi s2, a1, -1 154; RV32I-NEXT: and a0, a0, s2 155; RV32I-NEXT: call __extendhfsf2@plt 156; RV32I-NEXT: mv s1, a0 157; RV32I-NEXT: and a0, s0, s2 158; RV32I-NEXT: call __extendhfsf2@plt 159; RV32I-NEXT: mv a1, a0 160; RV32I-NEXT: mv a0, s1 161; RV32I-NEXT: call __mulsf3@plt 162; RV32I-NEXT: call __truncsfhf2@plt 163; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 164; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 165; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 166; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 167; RV32I-NEXT: addi sp, sp, 16 168; RV32I-NEXT: ret 169; 170; RV64I-LABEL: fmul_s: 171; RV64I: # %bb.0: 172; RV64I-NEXT: addi sp, sp, -32 173; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 174; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 175; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 176; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 177; RV64I-NEXT: mv s0, a1 178; RV64I-NEXT: lui a1, 16 179; RV64I-NEXT: addiw s2, a1, -1 180; RV64I-NEXT: and a0, a0, s2 181; RV64I-NEXT: call __extendhfsf2@plt 182; RV64I-NEXT: mv s1, a0 183; RV64I-NEXT: and a0, s0, s2 184; RV64I-NEXT: call __extendhfsf2@plt 185; RV64I-NEXT: mv a1, a0 186; RV64I-NEXT: mv a0, s1 187; RV64I-NEXT: call __mulsf3@plt 188; RV64I-NEXT: call __truncsfhf2@plt 189; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 190; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 191; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 192; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 193; RV64I-NEXT: addi sp, sp, 32 194; RV64I-NEXT: ret 195 %1 = fmul half %a, %b 196 ret half %1 197} 198 199define half @fdiv_s(half %a, half %b) nounwind { 200; CHECKIZFH-LABEL: fdiv_s: 201; CHECKIZFH: # %bb.0: 202; CHECKIZFH-NEXT: fdiv.h fa0, fa0, fa1 203; CHECKIZFH-NEXT: ret 204; 205; RV32I-LABEL: fdiv_s: 206; RV32I: # %bb.0: 207; RV32I-NEXT: addi sp, sp, -16 208; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 209; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 210; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 211; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 212; RV32I-NEXT: mv s0, a1 213; RV32I-NEXT: lui a1, 16 214; RV32I-NEXT: addi s2, a1, -1 215; RV32I-NEXT: and a0, a0, s2 216; RV32I-NEXT: call __extendhfsf2@plt 217; RV32I-NEXT: mv s1, a0 218; RV32I-NEXT: and a0, s0, s2 219; RV32I-NEXT: call __extendhfsf2@plt 220; RV32I-NEXT: mv a1, a0 221; RV32I-NEXT: mv a0, s1 222; RV32I-NEXT: call __divsf3@plt 223; RV32I-NEXT: call __truncsfhf2@plt 224; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 225; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 226; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 227; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 228; RV32I-NEXT: addi sp, sp, 16 229; RV32I-NEXT: ret 230; 231; RV64I-LABEL: fdiv_s: 232; RV64I: # %bb.0: 233; RV64I-NEXT: addi sp, sp, -32 234; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 235; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 236; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 237; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 238; RV64I-NEXT: mv s0, a1 239; RV64I-NEXT: lui a1, 16 240; RV64I-NEXT: addiw s2, a1, -1 241; RV64I-NEXT: and a0, a0, s2 242; RV64I-NEXT: call __extendhfsf2@plt 243; RV64I-NEXT: mv s1, a0 244; RV64I-NEXT: and a0, s0, s2 245; RV64I-NEXT: call __extendhfsf2@plt 246; RV64I-NEXT: mv a1, a0 247; RV64I-NEXT: mv a0, s1 248; RV64I-NEXT: call __divsf3@plt 249; RV64I-NEXT: call __truncsfhf2@plt 250; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 251; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 252; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 253; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 254; RV64I-NEXT: addi sp, sp, 32 255; RV64I-NEXT: ret 256 %1 = fdiv half %a, %b 257 ret half %1 258} 259 260declare half @llvm.sqrt.f16(half) 261 262define half @fsqrt_s(half %a) nounwind { 263; CHECKIZFH-LABEL: fsqrt_s: 264; CHECKIZFH: # %bb.0: 265; CHECKIZFH-NEXT: fsqrt.h fa0, fa0 266; CHECKIZFH-NEXT: ret 267; 268; RV32I-LABEL: fsqrt_s: 269; RV32I: # %bb.0: 270; RV32I-NEXT: addi sp, sp, -16 271; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 272; RV32I-NEXT: slli a0, a0, 16 273; RV32I-NEXT: srli a0, a0, 16 274; RV32I-NEXT: call __extendhfsf2@plt 275; RV32I-NEXT: call sqrtf@plt 276; RV32I-NEXT: call __truncsfhf2@plt 277; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 278; RV32I-NEXT: addi sp, sp, 16 279; RV32I-NEXT: ret 280; 281; RV64I-LABEL: fsqrt_s: 282; RV64I: # %bb.0: 283; RV64I-NEXT: addi sp, sp, -16 284; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 285; RV64I-NEXT: slli a0, a0, 48 286; RV64I-NEXT: srli a0, a0, 48 287; RV64I-NEXT: call __extendhfsf2@plt 288; RV64I-NEXT: call sqrtf@plt 289; RV64I-NEXT: call __truncsfhf2@plt 290; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 291; RV64I-NEXT: addi sp, sp, 16 292; RV64I-NEXT: ret 293 %1 = call half @llvm.sqrt.f16(half %a) 294 ret half %1 295} 296 297declare half @llvm.copysign.f16(half, half) 298 299define half @fsgnj_s(half %a, half %b) nounwind { 300; CHECKIZFH-LABEL: fsgnj_s: 301; CHECKIZFH: # %bb.0: 302; CHECKIZFH-NEXT: fsgnj.h fa0, fa0, fa1 303; CHECKIZFH-NEXT: ret 304; 305; RV32I-LABEL: fsgnj_s: 306; RV32I: # %bb.0: 307; RV32I-NEXT: lui a2, 1048568 308; RV32I-NEXT: and a1, a1, a2 309; RV32I-NEXT: slli a0, a0, 17 310; RV32I-NEXT: srli a0, a0, 17 311; RV32I-NEXT: or a0, a0, a1 312; RV32I-NEXT: ret 313; 314; RV64I-LABEL: fsgnj_s: 315; RV64I: # %bb.0: 316; RV64I-NEXT: lui a2, 1048568 317; RV64I-NEXT: and a1, a1, a2 318; RV64I-NEXT: slli a0, a0, 49 319; RV64I-NEXT: srli a0, a0, 49 320; RV64I-NEXT: or a0, a0, a1 321; RV64I-NEXT: ret 322 %1 = call half @llvm.copysign.f16(half %a, half %b) 323 ret half %1 324} 325 326; This function performs extra work to ensure that 327; DAGCombiner::visitBITCAST doesn't replace the fneg with an xor. 328define i32 @fneg_s(half %a, half %b) nounwind { 329; CHECKIZFH-LABEL: fneg_s: 330; CHECKIZFH: # %bb.0: 331; CHECKIZFH-NEXT: fadd.h ft0, fa0, fa0 332; CHECKIZFH-NEXT: fneg.h ft1, ft0 333; CHECKIZFH-NEXT: feq.h a0, ft0, ft1 334; CHECKIZFH-NEXT: ret 335; 336; RV32I-LABEL: fneg_s: 337; RV32I: # %bb.0: 338; RV32I-NEXT: addi sp, sp, -16 339; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 340; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 341; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 342; RV32I-NEXT: lui a1, 16 343; RV32I-NEXT: addi s1, a1, -1 344; RV32I-NEXT: and a0, a0, s1 345; RV32I-NEXT: call __extendhfsf2@plt 346; RV32I-NEXT: mv a1, a0 347; RV32I-NEXT: call __addsf3@plt 348; RV32I-NEXT: call __truncsfhf2@plt 349; RV32I-NEXT: and a0, a0, s1 350; RV32I-NEXT: call __extendhfsf2@plt 351; RV32I-NEXT: mv s0, a0 352; RV32I-NEXT: lui a0, 524288 353; RV32I-NEXT: xor a0, s0, a0 354; RV32I-NEXT: call __truncsfhf2@plt 355; RV32I-NEXT: and a0, a0, s1 356; RV32I-NEXT: call __extendhfsf2@plt 357; RV32I-NEXT: mv a1, a0 358; RV32I-NEXT: mv a0, s0 359; RV32I-NEXT: call __eqsf2@plt 360; RV32I-NEXT: seqz a0, a0 361; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 362; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 363; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 364; RV32I-NEXT: addi sp, sp, 16 365; RV32I-NEXT: ret 366; 367; RV64I-LABEL: fneg_s: 368; RV64I: # %bb.0: 369; RV64I-NEXT: addi sp, sp, -32 370; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 371; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 372; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 373; RV64I-NEXT: lui a1, 16 374; RV64I-NEXT: addiw s1, a1, -1 375; RV64I-NEXT: and a0, a0, s1 376; RV64I-NEXT: call __extendhfsf2@plt 377; RV64I-NEXT: mv a1, a0 378; RV64I-NEXT: call __addsf3@plt 379; RV64I-NEXT: call __truncsfhf2@plt 380; RV64I-NEXT: and a0, a0, s1 381; RV64I-NEXT: call __extendhfsf2@plt 382; RV64I-NEXT: mv s0, a0 383; RV64I-NEXT: lui a0, 524288 384; RV64I-NEXT: xor a0, s0, a0 385; RV64I-NEXT: call __truncsfhf2@plt 386; RV64I-NEXT: and a0, a0, s1 387; RV64I-NEXT: call __extendhfsf2@plt 388; RV64I-NEXT: mv a1, a0 389; RV64I-NEXT: mv a0, s0 390; RV64I-NEXT: call __eqsf2@plt 391; RV64I-NEXT: seqz a0, a0 392; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 393; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 394; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 395; RV64I-NEXT: addi sp, sp, 32 396; RV64I-NEXT: ret 397 %1 = fadd half %a, %a 398 %2 = fneg half %1 399 %3 = fcmp oeq half %1, %2 400 %4 = zext i1 %3 to i32 401 ret i32 %4 402} 403 404; This function performs extra work to ensure that 405; DAGCombiner::visitBITCAST doesn't replace the fneg with an xor. 406define half @fsgnjn_s(half %a, half %b) nounwind { 407; CHECKIZFH-LABEL: fsgnjn_s: 408; CHECKIZFH: # %bb.0: 409; CHECKIZFH-NEXT: fadd.h ft0, fa0, fa1 410; CHECKIZFH-NEXT: fsgnjn.h fa0, fa0, ft0 411; CHECKIZFH-NEXT: ret 412; 413; RV32I-LABEL: fsgnjn_s: 414; RV32I: # %bb.0: 415; RV32I-NEXT: addi sp, sp, -32 416; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 417; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 418; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 419; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 420; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 421; RV32I-NEXT: mv s0, a1 422; RV32I-NEXT: mv s1, a0 423; RV32I-NEXT: lui a0, 16 424; RV32I-NEXT: addi s3, a0, -1 425; RV32I-NEXT: and a0, s1, s3 426; RV32I-NEXT: call __extendhfsf2@plt 427; RV32I-NEXT: mv s2, a0 428; RV32I-NEXT: and a0, s0, s3 429; RV32I-NEXT: call __extendhfsf2@plt 430; RV32I-NEXT: mv a1, a0 431; RV32I-NEXT: mv a0, s2 432; RV32I-NEXT: call __addsf3@plt 433; RV32I-NEXT: call __truncsfhf2@plt 434; RV32I-NEXT: and a0, a0, s3 435; RV32I-NEXT: call __extendhfsf2@plt 436; RV32I-NEXT: lui a1, 524288 437; RV32I-NEXT: xor a0, a0, a1 438; RV32I-NEXT: call __truncsfhf2@plt 439; RV32I-NEXT: lui a1, 1048568 440; RV32I-NEXT: and a0, a0, a1 441; RV32I-NEXT: slli a1, s1, 17 442; RV32I-NEXT: srli a1, a1, 17 443; RV32I-NEXT: or a0, a1, a0 444; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 445; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 446; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 447; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 448; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 449; RV32I-NEXT: addi sp, sp, 32 450; RV32I-NEXT: ret 451; 452; RV64I-LABEL: fsgnjn_s: 453; RV64I: # %bb.0: 454; RV64I-NEXT: addi sp, sp, -48 455; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 456; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill 457; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill 458; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill 459; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill 460; RV64I-NEXT: mv s0, a1 461; RV64I-NEXT: mv s1, a0 462; RV64I-NEXT: lui a0, 16 463; RV64I-NEXT: addiw s3, a0, -1 464; RV64I-NEXT: and a0, s1, s3 465; RV64I-NEXT: call __extendhfsf2@plt 466; RV64I-NEXT: mv s2, a0 467; RV64I-NEXT: and a0, s0, s3 468; RV64I-NEXT: call __extendhfsf2@plt 469; RV64I-NEXT: mv a1, a0 470; RV64I-NEXT: mv a0, s2 471; RV64I-NEXT: call __addsf3@plt 472; RV64I-NEXT: call __truncsfhf2@plt 473; RV64I-NEXT: and a0, a0, s3 474; RV64I-NEXT: call __extendhfsf2@plt 475; RV64I-NEXT: lui a1, 524288 476; RV64I-NEXT: xor a0, a0, a1 477; RV64I-NEXT: call __truncsfhf2@plt 478; RV64I-NEXT: lui a1, 1048568 479; RV64I-NEXT: and a0, a0, a1 480; RV64I-NEXT: slli a1, s1, 49 481; RV64I-NEXT: srli a1, a1, 49 482; RV64I-NEXT: or a0, a1, a0 483; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 484; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload 485; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload 486; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload 487; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload 488; RV64I-NEXT: addi sp, sp, 48 489; RV64I-NEXT: ret 490 %1 = fadd half %a, %b 491 %2 = fneg half %1 492 %3 = call half @llvm.copysign.f16(half %a, half %2) 493 ret half %3 494} 495 496declare half @llvm.fabs.f16(half) 497 498; This function performs extra work to ensure that 499; DAGCombiner::visitBITCAST doesn't replace the fabs with an and. 500define half @fabs_s(half %a, half %b) nounwind { 501; CHECKIZFH-LABEL: fabs_s: 502; CHECKIZFH: # %bb.0: 503; CHECKIZFH-NEXT: fadd.h ft0, fa0, fa1 504; CHECKIZFH-NEXT: fabs.h ft1, ft0 505; CHECKIZFH-NEXT: fadd.h fa0, ft1, ft0 506; CHECKIZFH-NEXT: ret 507; 508; RV32I-LABEL: fabs_s: 509; RV32I: # %bb.0: 510; RV32I-NEXT: addi sp, sp, -16 511; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 512; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 513; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 514; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 515; RV32I-NEXT: mv s0, a1 516; RV32I-NEXT: lui a1, 16 517; RV32I-NEXT: addi s2, a1, -1 518; RV32I-NEXT: and a0, a0, s2 519; RV32I-NEXT: call __extendhfsf2@plt 520; RV32I-NEXT: mv s1, a0 521; RV32I-NEXT: and a0, s0, s2 522; RV32I-NEXT: call __extendhfsf2@plt 523; RV32I-NEXT: mv a1, a0 524; RV32I-NEXT: mv a0, s1 525; RV32I-NEXT: call __addsf3@plt 526; RV32I-NEXT: call __truncsfhf2@plt 527; RV32I-NEXT: and a0, a0, s2 528; RV32I-NEXT: call __extendhfsf2@plt 529; RV32I-NEXT: mv s0, a0 530; RV32I-NEXT: slli a0, a0, 1 531; RV32I-NEXT: srli a0, a0, 1 532; RV32I-NEXT: call __truncsfhf2@plt 533; RV32I-NEXT: and a0, a0, s2 534; RV32I-NEXT: call __extendhfsf2@plt 535; RV32I-NEXT: mv a1, s0 536; RV32I-NEXT: call __addsf3@plt 537; RV32I-NEXT: call __truncsfhf2@plt 538; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 539; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 540; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 541; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 542; RV32I-NEXT: addi sp, sp, 16 543; RV32I-NEXT: ret 544; 545; RV64I-LABEL: fabs_s: 546; RV64I: # %bb.0: 547; RV64I-NEXT: addi sp, sp, -32 548; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 549; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 550; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 551; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 552; RV64I-NEXT: mv s0, a1 553; RV64I-NEXT: lui a1, 16 554; RV64I-NEXT: addiw s2, a1, -1 555; RV64I-NEXT: and a0, a0, s2 556; RV64I-NEXT: call __extendhfsf2@plt 557; RV64I-NEXT: mv s1, a0 558; RV64I-NEXT: and a0, s0, s2 559; RV64I-NEXT: call __extendhfsf2@plt 560; RV64I-NEXT: mv a1, a0 561; RV64I-NEXT: mv a0, s1 562; RV64I-NEXT: call __addsf3@plt 563; RV64I-NEXT: call __truncsfhf2@plt 564; RV64I-NEXT: and a0, a0, s2 565; RV64I-NEXT: call __extendhfsf2@plt 566; RV64I-NEXT: mv s0, a0 567; RV64I-NEXT: slli a0, a0, 33 568; RV64I-NEXT: srli a0, a0, 33 569; RV64I-NEXT: call __truncsfhf2@plt 570; RV64I-NEXT: and a0, a0, s2 571; RV64I-NEXT: call __extendhfsf2@plt 572; RV64I-NEXT: mv a1, s0 573; RV64I-NEXT: call __addsf3@plt 574; RV64I-NEXT: call __truncsfhf2@plt 575; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 576; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 577; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 578; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 579; RV64I-NEXT: addi sp, sp, 32 580; RV64I-NEXT: ret 581 %1 = fadd half %a, %b 582 %2 = call half @llvm.fabs.f16(half %1) 583 %3 = fadd half %2, %1 584 ret half %3 585} 586 587declare half @llvm.minnum.f16(half, half) 588 589define half @fmin_s(half %a, half %b) nounwind { 590; CHECKIZFH-LABEL: fmin_s: 591; CHECKIZFH: # %bb.0: 592; CHECKIZFH-NEXT: fmin.h fa0, fa0, fa1 593; CHECKIZFH-NEXT: ret 594; 595; RV32I-LABEL: fmin_s: 596; RV32I: # %bb.0: 597; RV32I-NEXT: addi sp, sp, -16 598; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 599; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 600; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 601; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 602; RV32I-NEXT: mv s0, a1 603; RV32I-NEXT: lui a1, 16 604; RV32I-NEXT: addi s2, a1, -1 605; RV32I-NEXT: and a0, a0, s2 606; RV32I-NEXT: call __extendhfsf2@plt 607; RV32I-NEXT: mv s1, a0 608; RV32I-NEXT: and a0, s0, s2 609; RV32I-NEXT: call __extendhfsf2@plt 610; RV32I-NEXT: mv a1, a0 611; RV32I-NEXT: mv a0, s1 612; RV32I-NEXT: call fminf@plt 613; RV32I-NEXT: call __truncsfhf2@plt 614; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 615; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 616; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 617; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 618; RV32I-NEXT: addi sp, sp, 16 619; RV32I-NEXT: ret 620; 621; RV64I-LABEL: fmin_s: 622; RV64I: # %bb.0: 623; RV64I-NEXT: addi sp, sp, -32 624; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 625; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 626; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 627; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 628; RV64I-NEXT: mv s0, a1 629; RV64I-NEXT: lui a1, 16 630; RV64I-NEXT: addiw s2, a1, -1 631; RV64I-NEXT: and a0, a0, s2 632; RV64I-NEXT: call __extendhfsf2@plt 633; RV64I-NEXT: mv s1, a0 634; RV64I-NEXT: and a0, s0, s2 635; RV64I-NEXT: call __extendhfsf2@plt 636; RV64I-NEXT: mv a1, a0 637; RV64I-NEXT: mv a0, s1 638; RV64I-NEXT: call fminf@plt 639; RV64I-NEXT: call __truncsfhf2@plt 640; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 641; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 642; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 643; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 644; RV64I-NEXT: addi sp, sp, 32 645; RV64I-NEXT: ret 646 %1 = call half @llvm.minnum.f16(half %a, half %b) 647 ret half %1 648} 649 650declare half @llvm.maxnum.f16(half, half) 651 652define half @fmax_s(half %a, half %b) nounwind { 653; CHECKIZFH-LABEL: fmax_s: 654; CHECKIZFH: # %bb.0: 655; CHECKIZFH-NEXT: fmax.h fa0, fa0, fa1 656; CHECKIZFH-NEXT: ret 657; 658; RV32I-LABEL: fmax_s: 659; RV32I: # %bb.0: 660; RV32I-NEXT: addi sp, sp, -16 661; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 662; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 663; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 664; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 665; RV32I-NEXT: mv s0, a1 666; RV32I-NEXT: lui a1, 16 667; RV32I-NEXT: addi s2, a1, -1 668; RV32I-NEXT: and a0, a0, s2 669; RV32I-NEXT: call __extendhfsf2@plt 670; RV32I-NEXT: mv s1, a0 671; RV32I-NEXT: and a0, s0, s2 672; RV32I-NEXT: call __extendhfsf2@plt 673; RV32I-NEXT: mv a1, a0 674; RV32I-NEXT: mv a0, s1 675; RV32I-NEXT: call fmaxf@plt 676; RV32I-NEXT: call __truncsfhf2@plt 677; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 678; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 679; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 680; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 681; RV32I-NEXT: addi sp, sp, 16 682; RV32I-NEXT: ret 683; 684; RV64I-LABEL: fmax_s: 685; RV64I: # %bb.0: 686; RV64I-NEXT: addi sp, sp, -32 687; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 688; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 689; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 690; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 691; RV64I-NEXT: mv s0, a1 692; RV64I-NEXT: lui a1, 16 693; RV64I-NEXT: addiw s2, a1, -1 694; RV64I-NEXT: and a0, a0, s2 695; RV64I-NEXT: call __extendhfsf2@plt 696; RV64I-NEXT: mv s1, a0 697; RV64I-NEXT: and a0, s0, s2 698; RV64I-NEXT: call __extendhfsf2@plt 699; RV64I-NEXT: mv a1, a0 700; RV64I-NEXT: mv a0, s1 701; RV64I-NEXT: call fmaxf@plt 702; RV64I-NEXT: call __truncsfhf2@plt 703; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 704; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 705; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 706; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 707; RV64I-NEXT: addi sp, sp, 32 708; RV64I-NEXT: ret 709 %1 = call half @llvm.maxnum.f16(half %a, half %b) 710 ret half %1 711} 712 713declare half @llvm.fma.f16(half, half, half) 714 715define half @fmadd_s(half %a, half %b, half %c) nounwind { 716; CHECKIZFH-LABEL: fmadd_s: 717; CHECKIZFH: # %bb.0: 718; CHECKIZFH-NEXT: fmadd.h fa0, fa0, fa1, fa2 719; CHECKIZFH-NEXT: ret 720; 721; RV32I-LABEL: fmadd_s: 722; RV32I: # %bb.0: 723; RV32I-NEXT: addi sp, sp, -32 724; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 725; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 726; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 727; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 728; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 729; RV32I-NEXT: mv s0, a2 730; RV32I-NEXT: mv s1, a1 731; RV32I-NEXT: lui a1, 16 732; RV32I-NEXT: addi s3, a1, -1 733; RV32I-NEXT: and a0, a0, s3 734; RV32I-NEXT: call __extendhfsf2@plt 735; RV32I-NEXT: mv s2, a0 736; RV32I-NEXT: and a0, s1, s3 737; RV32I-NEXT: call __extendhfsf2@plt 738; RV32I-NEXT: mv s1, a0 739; RV32I-NEXT: and a0, s0, s3 740; RV32I-NEXT: call __extendhfsf2@plt 741; RV32I-NEXT: mv a2, a0 742; RV32I-NEXT: mv a0, s2 743; RV32I-NEXT: mv a1, s1 744; RV32I-NEXT: call fmaf@plt 745; RV32I-NEXT: call __truncsfhf2@plt 746; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 747; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 748; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 749; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 750; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 751; RV32I-NEXT: addi sp, sp, 32 752; RV32I-NEXT: ret 753; 754; RV64I-LABEL: fmadd_s: 755; RV64I: # %bb.0: 756; RV64I-NEXT: addi sp, sp, -48 757; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 758; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill 759; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill 760; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill 761; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill 762; RV64I-NEXT: mv s0, a2 763; RV64I-NEXT: mv s1, a1 764; RV64I-NEXT: lui a1, 16 765; RV64I-NEXT: addiw s3, a1, -1 766; RV64I-NEXT: and a0, a0, s3 767; RV64I-NEXT: call __extendhfsf2@plt 768; RV64I-NEXT: mv s2, a0 769; RV64I-NEXT: and a0, s1, s3 770; RV64I-NEXT: call __extendhfsf2@plt 771; RV64I-NEXT: mv s1, a0 772; RV64I-NEXT: and a0, s0, s3 773; RV64I-NEXT: call __extendhfsf2@plt 774; RV64I-NEXT: mv a2, a0 775; RV64I-NEXT: mv a0, s2 776; RV64I-NEXT: mv a1, s1 777; RV64I-NEXT: call fmaf@plt 778; RV64I-NEXT: call __truncsfhf2@plt 779; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 780; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload 781; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload 782; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload 783; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload 784; RV64I-NEXT: addi sp, sp, 48 785; RV64I-NEXT: ret 786 %1 = call half @llvm.fma.f16(half %a, half %b, half %c) 787 ret half %1 788} 789 790define half @fmsub_s(half %a, half %b, half %c) nounwind { 791; CHECKIZFH-LABEL: fmsub_s: 792; CHECKIZFH: # %bb.0: 793; CHECKIZFH-NEXT: fmv.h.x ft0, zero 794; CHECKIZFH-NEXT: fadd.h ft0, fa2, ft0 795; CHECKIZFH-NEXT: fmsub.h fa0, fa0, fa1, ft0 796; CHECKIZFH-NEXT: ret 797; 798; RV32I-LABEL: fmsub_s: 799; RV32I: # %bb.0: 800; RV32I-NEXT: addi sp, sp, -32 801; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 802; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 803; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 804; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 805; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 806; RV32I-NEXT: mv s0, a1 807; RV32I-NEXT: mv s1, a0 808; RV32I-NEXT: lui a0, 16 809; RV32I-NEXT: addi s3, a0, -1 810; RV32I-NEXT: and a0, a2, s3 811; RV32I-NEXT: call __extendhfsf2@plt 812; RV32I-NEXT: li a1, 0 813; RV32I-NEXT: call __addsf3@plt 814; RV32I-NEXT: call __truncsfhf2@plt 815; RV32I-NEXT: and a0, a0, s3 816; RV32I-NEXT: call __extendhfsf2@plt 817; RV32I-NEXT: lui a1, 524288 818; RV32I-NEXT: xor a0, a0, a1 819; RV32I-NEXT: call __truncsfhf2@plt 820; RV32I-NEXT: mv s2, a0 821; RV32I-NEXT: and a0, s1, s3 822; RV32I-NEXT: call __extendhfsf2@plt 823; RV32I-NEXT: mv s1, a0 824; RV32I-NEXT: and a0, s0, s3 825; RV32I-NEXT: call __extendhfsf2@plt 826; RV32I-NEXT: mv s0, a0 827; RV32I-NEXT: and a0, s2, s3 828; RV32I-NEXT: call __extendhfsf2@plt 829; RV32I-NEXT: mv a2, a0 830; RV32I-NEXT: mv a0, s1 831; RV32I-NEXT: mv a1, s0 832; RV32I-NEXT: call fmaf@plt 833; RV32I-NEXT: call __truncsfhf2@plt 834; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 835; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 836; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 837; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 838; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 839; RV32I-NEXT: addi sp, sp, 32 840; RV32I-NEXT: ret 841; 842; RV64I-LABEL: fmsub_s: 843; RV64I: # %bb.0: 844; RV64I-NEXT: addi sp, sp, -48 845; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 846; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill 847; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill 848; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill 849; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill 850; RV64I-NEXT: mv s0, a1 851; RV64I-NEXT: mv s1, a0 852; RV64I-NEXT: lui a0, 16 853; RV64I-NEXT: addiw s3, a0, -1 854; RV64I-NEXT: and a0, a2, s3 855; RV64I-NEXT: call __extendhfsf2@plt 856; RV64I-NEXT: li a1, 0 857; RV64I-NEXT: call __addsf3@plt 858; RV64I-NEXT: call __truncsfhf2@plt 859; RV64I-NEXT: and a0, a0, s3 860; RV64I-NEXT: call __extendhfsf2@plt 861; RV64I-NEXT: lui a1, 524288 862; RV64I-NEXT: xor a0, a0, a1 863; RV64I-NEXT: call __truncsfhf2@plt 864; RV64I-NEXT: mv s2, a0 865; RV64I-NEXT: and a0, s1, s3 866; RV64I-NEXT: call __extendhfsf2@plt 867; RV64I-NEXT: mv s1, a0 868; RV64I-NEXT: and a0, s0, s3 869; RV64I-NEXT: call __extendhfsf2@plt 870; RV64I-NEXT: mv s0, a0 871; RV64I-NEXT: and a0, s2, s3 872; RV64I-NEXT: call __extendhfsf2@plt 873; RV64I-NEXT: mv a2, a0 874; RV64I-NEXT: mv a0, s1 875; RV64I-NEXT: mv a1, s0 876; RV64I-NEXT: call fmaf@plt 877; RV64I-NEXT: call __truncsfhf2@plt 878; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 879; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload 880; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload 881; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload 882; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload 883; RV64I-NEXT: addi sp, sp, 48 884; RV64I-NEXT: ret 885 %c_ = fadd half 0.0, %c ; avoid negation using xor 886 %negc = fsub half -0.0, %c_ 887 %1 = call half @llvm.fma.f16(half %a, half %b, half %negc) 888 ret half %1 889} 890 891define half @fnmadd_s(half %a, half %b, half %c) nounwind { 892; CHECKIZFH-LABEL: fnmadd_s: 893; CHECKIZFH: # %bb.0: 894; CHECKIZFH-NEXT: fmv.h.x ft0, zero 895; CHECKIZFH-NEXT: fadd.h ft1, fa0, ft0 896; CHECKIZFH-NEXT: fadd.h ft0, fa2, ft0 897; CHECKIZFH-NEXT: fnmadd.h fa0, ft1, fa1, ft0 898; CHECKIZFH-NEXT: ret 899; 900; RV32I-LABEL: fnmadd_s: 901; RV32I: # %bb.0: 902; RV32I-NEXT: addi sp, sp, -32 903; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 904; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 905; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 906; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 907; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 908; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill 909; RV32I-NEXT: mv s1, a2 910; RV32I-NEXT: mv s0, a1 911; RV32I-NEXT: lui a1, 16 912; RV32I-NEXT: addi s3, a1, -1 913; RV32I-NEXT: and a0, a0, s3 914; RV32I-NEXT: call __extendhfsf2@plt 915; RV32I-NEXT: li a1, 0 916; RV32I-NEXT: call __addsf3@plt 917; RV32I-NEXT: call __truncsfhf2@plt 918; RV32I-NEXT: mv s2, a0 919; RV32I-NEXT: and a0, s1, s3 920; RV32I-NEXT: call __extendhfsf2@plt 921; RV32I-NEXT: li a1, 0 922; RV32I-NEXT: call __addsf3@plt 923; RV32I-NEXT: call __truncsfhf2@plt 924; RV32I-NEXT: mv s1, a0 925; RV32I-NEXT: and a0, s2, s3 926; RV32I-NEXT: call __extendhfsf2@plt 927; RV32I-NEXT: lui s4, 524288 928; RV32I-NEXT: xor a0, a0, s4 929; RV32I-NEXT: call __truncsfhf2@plt 930; RV32I-NEXT: mv s2, a0 931; RV32I-NEXT: and a0, s1, s3 932; RV32I-NEXT: call __extendhfsf2@plt 933; RV32I-NEXT: xor a0, a0, s4 934; RV32I-NEXT: call __truncsfhf2@plt 935; RV32I-NEXT: mv s1, a0 936; RV32I-NEXT: and a0, s0, s3 937; RV32I-NEXT: call __extendhfsf2@plt 938; RV32I-NEXT: mv s0, a0 939; RV32I-NEXT: and a0, s2, s3 940; RV32I-NEXT: call __extendhfsf2@plt 941; RV32I-NEXT: mv s2, a0 942; RV32I-NEXT: and a0, s1, s3 943; RV32I-NEXT: call __extendhfsf2@plt 944; RV32I-NEXT: mv a2, a0 945; RV32I-NEXT: mv a0, s2 946; RV32I-NEXT: mv a1, s0 947; RV32I-NEXT: call fmaf@plt 948; RV32I-NEXT: call __truncsfhf2@plt 949; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 950; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 951; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 952; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 953; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 954; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload 955; RV32I-NEXT: addi sp, sp, 32 956; RV32I-NEXT: ret 957; 958; RV64I-LABEL: fnmadd_s: 959; RV64I: # %bb.0: 960; RV64I-NEXT: addi sp, sp, -48 961; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 962; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill 963; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill 964; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill 965; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill 966; RV64I-NEXT: sd s4, 0(sp) # 8-byte Folded Spill 967; RV64I-NEXT: mv s1, a2 968; RV64I-NEXT: mv s0, a1 969; RV64I-NEXT: lui a1, 16 970; RV64I-NEXT: addiw s3, a1, -1 971; RV64I-NEXT: and a0, a0, s3 972; RV64I-NEXT: call __extendhfsf2@plt 973; RV64I-NEXT: li a1, 0 974; RV64I-NEXT: call __addsf3@plt 975; RV64I-NEXT: call __truncsfhf2@plt 976; RV64I-NEXT: mv s2, a0 977; RV64I-NEXT: and a0, s1, s3 978; RV64I-NEXT: call __extendhfsf2@plt 979; RV64I-NEXT: li a1, 0 980; RV64I-NEXT: call __addsf3@plt 981; RV64I-NEXT: call __truncsfhf2@plt 982; RV64I-NEXT: mv s1, a0 983; RV64I-NEXT: and a0, s2, s3 984; RV64I-NEXT: call __extendhfsf2@plt 985; RV64I-NEXT: lui s4, 524288 986; RV64I-NEXT: xor a0, a0, s4 987; RV64I-NEXT: call __truncsfhf2@plt 988; RV64I-NEXT: mv s2, a0 989; RV64I-NEXT: and a0, s1, s3 990; RV64I-NEXT: call __extendhfsf2@plt 991; RV64I-NEXT: xor a0, a0, s4 992; RV64I-NEXT: call __truncsfhf2@plt 993; RV64I-NEXT: mv s1, a0 994; RV64I-NEXT: and a0, s0, s3 995; RV64I-NEXT: call __extendhfsf2@plt 996; RV64I-NEXT: mv s0, a0 997; RV64I-NEXT: and a0, s2, s3 998; RV64I-NEXT: call __extendhfsf2@plt 999; RV64I-NEXT: mv s2, a0 1000; RV64I-NEXT: and a0, s1, s3 1001; RV64I-NEXT: call __extendhfsf2@plt 1002; RV64I-NEXT: mv a2, a0 1003; RV64I-NEXT: mv a0, s2 1004; RV64I-NEXT: mv a1, s0 1005; RV64I-NEXT: call fmaf@plt 1006; RV64I-NEXT: call __truncsfhf2@plt 1007; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 1008; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload 1009; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload 1010; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload 1011; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload 1012; RV64I-NEXT: ld s4, 0(sp) # 8-byte Folded Reload 1013; RV64I-NEXT: addi sp, sp, 48 1014; RV64I-NEXT: ret 1015 %a_ = fadd half 0.0, %a 1016 %c_ = fadd half 0.0, %c 1017 %nega = fsub half -0.0, %a_ 1018 %negc = fsub half -0.0, %c_ 1019 %1 = call half @llvm.fma.f16(half %nega, half %b, half %negc) 1020 ret half %1 1021} 1022 1023define half @fnmadd_s_2(half %a, half %b, half %c) nounwind { 1024; CHECKIZFH-LABEL: fnmadd_s_2: 1025; CHECKIZFH: # %bb.0: 1026; CHECKIZFH-NEXT: fmv.h.x ft0, zero 1027; CHECKIZFH-NEXT: fadd.h ft1, fa1, ft0 1028; CHECKIZFH-NEXT: fadd.h ft0, fa2, ft0 1029; CHECKIZFH-NEXT: fnmadd.h fa0, ft1, fa0, ft0 1030; CHECKIZFH-NEXT: ret 1031; 1032; RV32I-LABEL: fnmadd_s_2: 1033; RV32I: # %bb.0: 1034; RV32I-NEXT: addi sp, sp, -32 1035; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 1036; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 1037; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 1038; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 1039; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 1040; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill 1041; RV32I-NEXT: mv s1, a2 1042; RV32I-NEXT: mv s0, a0 1043; RV32I-NEXT: lui a0, 16 1044; RV32I-NEXT: addi s3, a0, -1 1045; RV32I-NEXT: and a0, a1, s3 1046; RV32I-NEXT: call __extendhfsf2@plt 1047; RV32I-NEXT: li a1, 0 1048; RV32I-NEXT: call __addsf3@plt 1049; RV32I-NEXT: call __truncsfhf2@plt 1050; RV32I-NEXT: mv s2, a0 1051; RV32I-NEXT: and a0, s1, s3 1052; RV32I-NEXT: call __extendhfsf2@plt 1053; RV32I-NEXT: li a1, 0 1054; RV32I-NEXT: call __addsf3@plt 1055; RV32I-NEXT: call __truncsfhf2@plt 1056; RV32I-NEXT: mv s1, a0 1057; RV32I-NEXT: and a0, s2, s3 1058; RV32I-NEXT: call __extendhfsf2@plt 1059; RV32I-NEXT: lui s4, 524288 1060; RV32I-NEXT: xor a0, a0, s4 1061; RV32I-NEXT: call __truncsfhf2@plt 1062; RV32I-NEXT: mv s2, a0 1063; RV32I-NEXT: and a0, s1, s3 1064; RV32I-NEXT: call __extendhfsf2@plt 1065; RV32I-NEXT: xor a0, a0, s4 1066; RV32I-NEXT: call __truncsfhf2@plt 1067; RV32I-NEXT: mv s1, a0 1068; RV32I-NEXT: and a0, s0, s3 1069; RV32I-NEXT: call __extendhfsf2@plt 1070; RV32I-NEXT: mv s0, a0 1071; RV32I-NEXT: and a0, s2, s3 1072; RV32I-NEXT: call __extendhfsf2@plt 1073; RV32I-NEXT: mv s2, a0 1074; RV32I-NEXT: and a0, s1, s3 1075; RV32I-NEXT: call __extendhfsf2@plt 1076; RV32I-NEXT: mv a2, a0 1077; RV32I-NEXT: mv a0, s0 1078; RV32I-NEXT: mv a1, s2 1079; RV32I-NEXT: call fmaf@plt 1080; RV32I-NEXT: call __truncsfhf2@plt 1081; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 1082; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 1083; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 1084; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 1085; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 1086; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload 1087; RV32I-NEXT: addi sp, sp, 32 1088; RV32I-NEXT: ret 1089; 1090; RV64I-LABEL: fnmadd_s_2: 1091; RV64I: # %bb.0: 1092; RV64I-NEXT: addi sp, sp, -48 1093; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 1094; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill 1095; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill 1096; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill 1097; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill 1098; RV64I-NEXT: sd s4, 0(sp) # 8-byte Folded Spill 1099; RV64I-NEXT: mv s1, a2 1100; RV64I-NEXT: mv s0, a0 1101; RV64I-NEXT: lui a0, 16 1102; RV64I-NEXT: addiw s3, a0, -1 1103; RV64I-NEXT: and a0, a1, s3 1104; RV64I-NEXT: call __extendhfsf2@plt 1105; RV64I-NEXT: li a1, 0 1106; RV64I-NEXT: call __addsf3@plt 1107; RV64I-NEXT: call __truncsfhf2@plt 1108; RV64I-NEXT: mv s2, a0 1109; RV64I-NEXT: and a0, s1, s3 1110; RV64I-NEXT: call __extendhfsf2@plt 1111; RV64I-NEXT: li a1, 0 1112; RV64I-NEXT: call __addsf3@plt 1113; RV64I-NEXT: call __truncsfhf2@plt 1114; RV64I-NEXT: mv s1, a0 1115; RV64I-NEXT: and a0, s2, s3 1116; RV64I-NEXT: call __extendhfsf2@plt 1117; RV64I-NEXT: lui s4, 524288 1118; RV64I-NEXT: xor a0, a0, s4 1119; RV64I-NEXT: call __truncsfhf2@plt 1120; RV64I-NEXT: mv s2, a0 1121; RV64I-NEXT: and a0, s1, s3 1122; RV64I-NEXT: call __extendhfsf2@plt 1123; RV64I-NEXT: xor a0, a0, s4 1124; RV64I-NEXT: call __truncsfhf2@plt 1125; RV64I-NEXT: mv s1, a0 1126; RV64I-NEXT: and a0, s0, s3 1127; RV64I-NEXT: call __extendhfsf2@plt 1128; RV64I-NEXT: mv s0, a0 1129; RV64I-NEXT: and a0, s2, s3 1130; RV64I-NEXT: call __extendhfsf2@plt 1131; RV64I-NEXT: mv s2, a0 1132; RV64I-NEXT: and a0, s1, s3 1133; RV64I-NEXT: call __extendhfsf2@plt 1134; RV64I-NEXT: mv a2, a0 1135; RV64I-NEXT: mv a0, s0 1136; RV64I-NEXT: mv a1, s2 1137; RV64I-NEXT: call fmaf@plt 1138; RV64I-NEXT: call __truncsfhf2@plt 1139; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 1140; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload 1141; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload 1142; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload 1143; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload 1144; RV64I-NEXT: ld s4, 0(sp) # 8-byte Folded Reload 1145; RV64I-NEXT: addi sp, sp, 48 1146; RV64I-NEXT: ret 1147 %b_ = fadd half 0.0, %b 1148 %c_ = fadd half 0.0, %c 1149 %negb = fsub half -0.0, %b_ 1150 %negc = fsub half -0.0, %c_ 1151 %1 = call half @llvm.fma.f16(half %a, half %negb, half %negc) 1152 ret half %1 1153} 1154 1155define half @fnmadd_s_3(half %a, half %b, half %c) nounwind { 1156; RV32IZFH-LABEL: fnmadd_s_3: 1157; RV32IZFH: # %bb.0: 1158; RV32IZFH-NEXT: fmadd.h ft0, fa0, fa1, fa2 1159; RV32IZFH-NEXT: fneg.h fa0, ft0 1160; RV32IZFH-NEXT: ret 1161; 1162; RV64IZFH-LABEL: fnmadd_s_3: 1163; RV64IZFH: # %bb.0: 1164; RV64IZFH-NEXT: fmadd.h ft0, fa0, fa1, fa2 1165; RV64IZFH-NEXT: fneg.h fa0, ft0 1166; RV64IZFH-NEXT: ret 1167; 1168; CHECKIZFH-LABEL: fnmadd_s_3: 1169; CHECKIZFH: # %bb.0: 1170; CHECKIZFH-NEXT: fmadd.h ft0, fa0, fa1, fa2 1171; CHECKIZFH-NEXT: fneg.h fa0, ft0 1172; CHECKIZFH-NEXT: ret 1173; 1174; RV32I-LABEL: fnmadd_s_3: 1175; RV32I: # %bb.0: 1176; RV32I-NEXT: addi sp, sp, -32 1177; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 1178; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 1179; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 1180; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 1181; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 1182; RV32I-NEXT: mv s0, a2 1183; RV32I-NEXT: mv s1, a1 1184; RV32I-NEXT: lui a1, 16 1185; RV32I-NEXT: addi s3, a1, -1 1186; RV32I-NEXT: and a0, a0, s3 1187; RV32I-NEXT: call __extendhfsf2@plt 1188; RV32I-NEXT: mv s2, a0 1189; RV32I-NEXT: and a0, s1, s3 1190; RV32I-NEXT: call __extendhfsf2@plt 1191; RV32I-NEXT: mv s1, a0 1192; RV32I-NEXT: and a0, s0, s3 1193; RV32I-NEXT: call __extendhfsf2@plt 1194; RV32I-NEXT: mv a2, a0 1195; RV32I-NEXT: mv a0, s2 1196; RV32I-NEXT: mv a1, s1 1197; RV32I-NEXT: call fmaf@plt 1198; RV32I-NEXT: call __truncsfhf2@plt 1199; RV32I-NEXT: lui a1, 1048568 1200; RV32I-NEXT: xor a0, a0, a1 1201; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 1202; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 1203; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 1204; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 1205; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 1206; RV32I-NEXT: addi sp, sp, 32 1207; RV32I-NEXT: ret 1208; 1209; RV64I-LABEL: fnmadd_s_3: 1210; RV64I: # %bb.0: 1211; RV64I-NEXT: addi sp, sp, -48 1212; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 1213; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill 1214; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill 1215; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill 1216; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill 1217; RV64I-NEXT: mv s0, a2 1218; RV64I-NEXT: mv s1, a1 1219; RV64I-NEXT: lui a1, 16 1220; RV64I-NEXT: addiw s3, a1, -1 1221; RV64I-NEXT: and a0, a0, s3 1222; RV64I-NEXT: call __extendhfsf2@plt 1223; RV64I-NEXT: mv s2, a0 1224; RV64I-NEXT: and a0, s1, s3 1225; RV64I-NEXT: call __extendhfsf2@plt 1226; RV64I-NEXT: mv s1, a0 1227; RV64I-NEXT: and a0, s0, s3 1228; RV64I-NEXT: call __extendhfsf2@plt 1229; RV64I-NEXT: mv a2, a0 1230; RV64I-NEXT: mv a0, s2 1231; RV64I-NEXT: mv a1, s1 1232; RV64I-NEXT: call fmaf@plt 1233; RV64I-NEXT: call __truncsfhf2@plt 1234; RV64I-NEXT: lui a1, 1048568 1235; RV64I-NEXT: xor a0, a0, a1 1236; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 1237; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload 1238; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload 1239; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload 1240; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload 1241; RV64I-NEXT: addi sp, sp, 48 1242; RV64I-NEXT: ret 1243 %1 = call half @llvm.fma.f16(half %a, half %b, half %c) 1244 %neg = fneg half %1 1245 ret half %neg 1246} 1247 1248 1249define half @fnmadd_nsz(half %a, half %b, half %c) nounwind { 1250; RV32IZFH-LABEL: fnmadd_nsz: 1251; RV32IZFH: # %bb.0: 1252; RV32IZFH-NEXT: fnmadd.h fa0, fa0, fa1, fa2 1253; RV32IZFH-NEXT: ret 1254; 1255; RV64IZFH-LABEL: fnmadd_nsz: 1256; RV64IZFH: # %bb.0: 1257; RV64IZFH-NEXT: fnmadd.h fa0, fa0, fa1, fa2 1258; RV64IZFH-NEXT: ret 1259; 1260; CHECKIZFH-LABEL: fnmadd_nsz: 1261; CHECKIZFH: # %bb.0: 1262; CHECKIZFH-NEXT: fnmadd.h fa0, fa0, fa1, fa2 1263; CHECKIZFH-NEXT: ret 1264; 1265; RV32I-LABEL: fnmadd_nsz: 1266; RV32I: # %bb.0: 1267; RV32I-NEXT: addi sp, sp, -32 1268; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 1269; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 1270; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 1271; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 1272; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 1273; RV32I-NEXT: mv s0, a2 1274; RV32I-NEXT: mv s1, a1 1275; RV32I-NEXT: lui a1, 16 1276; RV32I-NEXT: addi s3, a1, -1 1277; RV32I-NEXT: and a0, a0, s3 1278; RV32I-NEXT: call __extendhfsf2@plt 1279; RV32I-NEXT: mv s2, a0 1280; RV32I-NEXT: and a0, s1, s3 1281; RV32I-NEXT: call __extendhfsf2@plt 1282; RV32I-NEXT: mv s1, a0 1283; RV32I-NEXT: and a0, s0, s3 1284; RV32I-NEXT: call __extendhfsf2@plt 1285; RV32I-NEXT: mv a2, a0 1286; RV32I-NEXT: mv a0, s2 1287; RV32I-NEXT: mv a1, s1 1288; RV32I-NEXT: call fmaf@plt 1289; RV32I-NEXT: call __truncsfhf2@plt 1290; RV32I-NEXT: lui a1, 1048568 1291; RV32I-NEXT: xor a0, a0, a1 1292; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 1293; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 1294; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 1295; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 1296; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 1297; RV32I-NEXT: addi sp, sp, 32 1298; RV32I-NEXT: ret 1299; 1300; RV64I-LABEL: fnmadd_nsz: 1301; RV64I: # %bb.0: 1302; RV64I-NEXT: addi sp, sp, -48 1303; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 1304; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill 1305; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill 1306; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill 1307; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill 1308; RV64I-NEXT: mv s0, a2 1309; RV64I-NEXT: mv s1, a1 1310; RV64I-NEXT: lui a1, 16 1311; RV64I-NEXT: addiw s3, a1, -1 1312; RV64I-NEXT: and a0, a0, s3 1313; RV64I-NEXT: call __extendhfsf2@plt 1314; RV64I-NEXT: mv s2, a0 1315; RV64I-NEXT: and a0, s1, s3 1316; RV64I-NEXT: call __extendhfsf2@plt 1317; RV64I-NEXT: mv s1, a0 1318; RV64I-NEXT: and a0, s0, s3 1319; RV64I-NEXT: call __extendhfsf2@plt 1320; RV64I-NEXT: mv a2, a0 1321; RV64I-NEXT: mv a0, s2 1322; RV64I-NEXT: mv a1, s1 1323; RV64I-NEXT: call fmaf@plt 1324; RV64I-NEXT: call __truncsfhf2@plt 1325; RV64I-NEXT: lui a1, 1048568 1326; RV64I-NEXT: xor a0, a0, a1 1327; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 1328; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload 1329; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload 1330; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload 1331; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload 1332; RV64I-NEXT: addi sp, sp, 48 1333; RV64I-NEXT: ret 1334 %1 = call nsz half @llvm.fma.f16(half %a, half %b, half %c) 1335 %neg = fneg nsz half %1 1336 ret half %neg 1337} 1338 1339define half @fnmsub_s(half %a, half %b, half %c) nounwind { 1340; CHECKIZFH-LABEL: fnmsub_s: 1341; CHECKIZFH: # %bb.0: 1342; CHECKIZFH-NEXT: fmv.h.x ft0, zero 1343; CHECKIZFH-NEXT: fadd.h ft0, fa0, ft0 1344; CHECKIZFH-NEXT: fnmsub.h fa0, ft0, fa1, fa2 1345; CHECKIZFH-NEXT: ret 1346; 1347; RV32I-LABEL: fnmsub_s: 1348; RV32I: # %bb.0: 1349; RV32I-NEXT: addi sp, sp, -32 1350; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 1351; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 1352; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 1353; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 1354; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 1355; RV32I-NEXT: mv s0, a2 1356; RV32I-NEXT: mv s1, a1 1357; RV32I-NEXT: lui a1, 16 1358; RV32I-NEXT: addi s3, a1, -1 1359; RV32I-NEXT: and a0, a0, s3 1360; RV32I-NEXT: call __extendhfsf2@plt 1361; RV32I-NEXT: li a1, 0 1362; RV32I-NEXT: call __addsf3@plt 1363; RV32I-NEXT: call __truncsfhf2@plt 1364; RV32I-NEXT: and a0, a0, s3 1365; RV32I-NEXT: call __extendhfsf2@plt 1366; RV32I-NEXT: lui a1, 524288 1367; RV32I-NEXT: xor a0, a0, a1 1368; RV32I-NEXT: call __truncsfhf2@plt 1369; RV32I-NEXT: mv s2, a0 1370; RV32I-NEXT: and a0, s1, s3 1371; RV32I-NEXT: call __extendhfsf2@plt 1372; RV32I-NEXT: mv s1, a0 1373; RV32I-NEXT: and a0, s0, s3 1374; RV32I-NEXT: call __extendhfsf2@plt 1375; RV32I-NEXT: mv s0, a0 1376; RV32I-NEXT: and a0, s2, s3 1377; RV32I-NEXT: call __extendhfsf2@plt 1378; RV32I-NEXT: mv a1, s1 1379; RV32I-NEXT: mv a2, s0 1380; RV32I-NEXT: call fmaf@plt 1381; RV32I-NEXT: call __truncsfhf2@plt 1382; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 1383; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 1384; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 1385; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 1386; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 1387; RV32I-NEXT: addi sp, sp, 32 1388; RV32I-NEXT: ret 1389; 1390; RV64I-LABEL: fnmsub_s: 1391; RV64I: # %bb.0: 1392; RV64I-NEXT: addi sp, sp, -48 1393; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 1394; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill 1395; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill 1396; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill 1397; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill 1398; RV64I-NEXT: mv s0, a2 1399; RV64I-NEXT: mv s1, a1 1400; RV64I-NEXT: lui a1, 16 1401; RV64I-NEXT: addiw s3, a1, -1 1402; RV64I-NEXT: and a0, a0, s3 1403; RV64I-NEXT: call __extendhfsf2@plt 1404; RV64I-NEXT: li a1, 0 1405; RV64I-NEXT: call __addsf3@plt 1406; RV64I-NEXT: call __truncsfhf2@plt 1407; RV64I-NEXT: and a0, a0, s3 1408; RV64I-NEXT: call __extendhfsf2@plt 1409; RV64I-NEXT: lui a1, 524288 1410; RV64I-NEXT: xor a0, a0, a1 1411; RV64I-NEXT: call __truncsfhf2@plt 1412; RV64I-NEXT: mv s2, a0 1413; RV64I-NEXT: and a0, s1, s3 1414; RV64I-NEXT: call __extendhfsf2@plt 1415; RV64I-NEXT: mv s1, a0 1416; RV64I-NEXT: and a0, s0, s3 1417; RV64I-NEXT: call __extendhfsf2@plt 1418; RV64I-NEXT: mv s0, a0 1419; RV64I-NEXT: and a0, s2, s3 1420; RV64I-NEXT: call __extendhfsf2@plt 1421; RV64I-NEXT: mv a1, s1 1422; RV64I-NEXT: mv a2, s0 1423; RV64I-NEXT: call fmaf@plt 1424; RV64I-NEXT: call __truncsfhf2@plt 1425; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 1426; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload 1427; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload 1428; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload 1429; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload 1430; RV64I-NEXT: addi sp, sp, 48 1431; RV64I-NEXT: ret 1432 %a_ = fadd half 0.0, %a 1433 %nega = fsub half -0.0, %a_ 1434 %1 = call half @llvm.fma.f16(half %nega, half %b, half %c) 1435 ret half %1 1436} 1437 1438define half @fnmsub_s_2(half %a, half %b, half %c) nounwind { 1439; CHECKIZFH-LABEL: fnmsub_s_2: 1440; CHECKIZFH: # %bb.0: 1441; CHECKIZFH-NEXT: fmv.h.x ft0, zero 1442; CHECKIZFH-NEXT: fadd.h ft0, fa1, ft0 1443; CHECKIZFH-NEXT: fnmsub.h fa0, ft0, fa0, fa2 1444; CHECKIZFH-NEXT: ret 1445; 1446; RV32I-LABEL: fnmsub_s_2: 1447; RV32I: # %bb.0: 1448; RV32I-NEXT: addi sp, sp, -32 1449; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 1450; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 1451; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 1452; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 1453; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 1454; RV32I-NEXT: mv s0, a2 1455; RV32I-NEXT: mv s1, a0 1456; RV32I-NEXT: lui a0, 16 1457; RV32I-NEXT: addi s3, a0, -1 1458; RV32I-NEXT: and a0, a1, s3 1459; RV32I-NEXT: call __extendhfsf2@plt 1460; RV32I-NEXT: li a1, 0 1461; RV32I-NEXT: call __addsf3@plt 1462; RV32I-NEXT: call __truncsfhf2@plt 1463; RV32I-NEXT: and a0, a0, s3 1464; RV32I-NEXT: call __extendhfsf2@plt 1465; RV32I-NEXT: lui a1, 524288 1466; RV32I-NEXT: xor a0, a0, a1 1467; RV32I-NEXT: call __truncsfhf2@plt 1468; RV32I-NEXT: mv s2, a0 1469; RV32I-NEXT: and a0, s1, s3 1470; RV32I-NEXT: call __extendhfsf2@plt 1471; RV32I-NEXT: mv s1, a0 1472; RV32I-NEXT: and a0, s0, s3 1473; RV32I-NEXT: call __extendhfsf2@plt 1474; RV32I-NEXT: mv s0, a0 1475; RV32I-NEXT: and a0, s2, s3 1476; RV32I-NEXT: call __extendhfsf2@plt 1477; RV32I-NEXT: mv a1, a0 1478; RV32I-NEXT: mv a0, s1 1479; RV32I-NEXT: mv a2, s0 1480; RV32I-NEXT: call fmaf@plt 1481; RV32I-NEXT: call __truncsfhf2@plt 1482; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 1483; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 1484; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 1485; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 1486; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 1487; RV32I-NEXT: addi sp, sp, 32 1488; RV32I-NEXT: ret 1489; 1490; RV64I-LABEL: fnmsub_s_2: 1491; RV64I: # %bb.0: 1492; RV64I-NEXT: addi sp, sp, -48 1493; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 1494; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill 1495; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill 1496; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill 1497; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill 1498; RV64I-NEXT: mv s0, a2 1499; RV64I-NEXT: mv s1, a0 1500; RV64I-NEXT: lui a0, 16 1501; RV64I-NEXT: addiw s3, a0, -1 1502; RV64I-NEXT: and a0, a1, s3 1503; RV64I-NEXT: call __extendhfsf2@plt 1504; RV64I-NEXT: li a1, 0 1505; RV64I-NEXT: call __addsf3@plt 1506; RV64I-NEXT: call __truncsfhf2@plt 1507; RV64I-NEXT: and a0, a0, s3 1508; RV64I-NEXT: call __extendhfsf2@plt 1509; RV64I-NEXT: lui a1, 524288 1510; RV64I-NEXT: xor a0, a0, a1 1511; RV64I-NEXT: call __truncsfhf2@plt 1512; RV64I-NEXT: mv s2, a0 1513; RV64I-NEXT: and a0, s1, s3 1514; RV64I-NEXT: call __extendhfsf2@plt 1515; RV64I-NEXT: mv s1, a0 1516; RV64I-NEXT: and a0, s0, s3 1517; RV64I-NEXT: call __extendhfsf2@plt 1518; RV64I-NEXT: mv s0, a0 1519; RV64I-NEXT: and a0, s2, s3 1520; RV64I-NEXT: call __extendhfsf2@plt 1521; RV64I-NEXT: mv a1, a0 1522; RV64I-NEXT: mv a0, s1 1523; RV64I-NEXT: mv a2, s0 1524; RV64I-NEXT: call fmaf@plt 1525; RV64I-NEXT: call __truncsfhf2@plt 1526; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 1527; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload 1528; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload 1529; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload 1530; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload 1531; RV64I-NEXT: addi sp, sp, 48 1532; RV64I-NEXT: ret 1533 %b_ = fadd half 0.0, %b 1534 %negb = fsub half -0.0, %b_ 1535 %1 = call half @llvm.fma.f16(half %a, half %negb, half %c) 1536 ret half %1 1537} 1538 1539define half @fmadd_s_contract(half %a, half %b, half %c) nounwind { 1540; CHECKIZFH-LABEL: fmadd_s_contract: 1541; CHECKIZFH: # %bb.0: 1542; CHECKIZFH-NEXT: fmadd.h fa0, fa0, fa1, fa2 1543; CHECKIZFH-NEXT: ret 1544; 1545; RV32I-LABEL: fmadd_s_contract: 1546; RV32I: # %bb.0: 1547; RV32I-NEXT: addi sp, sp, -32 1548; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 1549; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 1550; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 1551; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 1552; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 1553; RV32I-NEXT: mv s0, a2 1554; RV32I-NEXT: mv s1, a1 1555; RV32I-NEXT: lui a1, 16 1556; RV32I-NEXT: addi s3, a1, -1 1557; RV32I-NEXT: and a0, a0, s3 1558; RV32I-NEXT: call __extendhfsf2@plt 1559; RV32I-NEXT: mv s2, a0 1560; RV32I-NEXT: and a0, s1, s3 1561; RV32I-NEXT: call __extendhfsf2@plt 1562; RV32I-NEXT: mv a1, a0 1563; RV32I-NEXT: mv a0, s2 1564; RV32I-NEXT: call __mulsf3@plt 1565; RV32I-NEXT: call __truncsfhf2@plt 1566; RV32I-NEXT: mv s1, a0 1567; RV32I-NEXT: and a0, s0, s3 1568; RV32I-NEXT: call __extendhfsf2@plt 1569; RV32I-NEXT: mv s0, a0 1570; RV32I-NEXT: and a0, s1, s3 1571; RV32I-NEXT: call __extendhfsf2@plt 1572; RV32I-NEXT: mv a1, s0 1573; RV32I-NEXT: call __addsf3@plt 1574; RV32I-NEXT: call __truncsfhf2@plt 1575; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 1576; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 1577; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 1578; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 1579; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 1580; RV32I-NEXT: addi sp, sp, 32 1581; RV32I-NEXT: ret 1582; 1583; RV64I-LABEL: fmadd_s_contract: 1584; RV64I: # %bb.0: 1585; RV64I-NEXT: addi sp, sp, -48 1586; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 1587; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill 1588; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill 1589; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill 1590; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill 1591; RV64I-NEXT: mv s0, a2 1592; RV64I-NEXT: mv s1, a1 1593; RV64I-NEXT: lui a1, 16 1594; RV64I-NEXT: addiw s3, a1, -1 1595; RV64I-NEXT: and a0, a0, s3 1596; RV64I-NEXT: call __extendhfsf2@plt 1597; RV64I-NEXT: mv s2, a0 1598; RV64I-NEXT: and a0, s1, s3 1599; RV64I-NEXT: call __extendhfsf2@plt 1600; RV64I-NEXT: mv a1, a0 1601; RV64I-NEXT: mv a0, s2 1602; RV64I-NEXT: call __mulsf3@plt 1603; RV64I-NEXT: call __truncsfhf2@plt 1604; RV64I-NEXT: mv s1, a0 1605; RV64I-NEXT: and a0, s0, s3 1606; RV64I-NEXT: call __extendhfsf2@plt 1607; RV64I-NEXT: mv s0, a0 1608; RV64I-NEXT: and a0, s1, s3 1609; RV64I-NEXT: call __extendhfsf2@plt 1610; RV64I-NEXT: mv a1, s0 1611; RV64I-NEXT: call __addsf3@plt 1612; RV64I-NEXT: call __truncsfhf2@plt 1613; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 1614; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload 1615; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload 1616; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload 1617; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload 1618; RV64I-NEXT: addi sp, sp, 48 1619; RV64I-NEXT: ret 1620 %1 = fmul contract half %a, %b 1621 %2 = fadd contract half %1, %c 1622 ret half %2 1623} 1624 1625define half @fmsub_s_contract(half %a, half %b, half %c) nounwind { 1626; CHECKIZFH-LABEL: fmsub_s_contract: 1627; CHECKIZFH: # %bb.0: 1628; CHECKIZFH-NEXT: fmv.h.x ft0, zero 1629; CHECKIZFH-NEXT: fadd.h ft0, fa2, ft0 1630; CHECKIZFH-NEXT: fmsub.h fa0, fa0, fa1, ft0 1631; CHECKIZFH-NEXT: ret 1632; 1633; RV32I-LABEL: fmsub_s_contract: 1634; RV32I: # %bb.0: 1635; RV32I-NEXT: addi sp, sp, -32 1636; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 1637; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 1638; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 1639; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 1640; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 1641; RV32I-NEXT: mv s0, a1 1642; RV32I-NEXT: mv s1, a0 1643; RV32I-NEXT: lui a0, 16 1644; RV32I-NEXT: addi s3, a0, -1 1645; RV32I-NEXT: and a0, a2, s3 1646; RV32I-NEXT: call __extendhfsf2@plt 1647; RV32I-NEXT: li a1, 0 1648; RV32I-NEXT: call __addsf3@plt 1649; RV32I-NEXT: call __truncsfhf2@plt 1650; RV32I-NEXT: mv s2, a0 1651; RV32I-NEXT: and a0, s1, s3 1652; RV32I-NEXT: call __extendhfsf2@plt 1653; RV32I-NEXT: mv s1, a0 1654; RV32I-NEXT: and a0, s0, s3 1655; RV32I-NEXT: call __extendhfsf2@plt 1656; RV32I-NEXT: mv a1, a0 1657; RV32I-NEXT: mv a0, s1 1658; RV32I-NEXT: call __mulsf3@plt 1659; RV32I-NEXT: call __truncsfhf2@plt 1660; RV32I-NEXT: and a0, a0, s3 1661; RV32I-NEXT: call __extendhfsf2@plt 1662; RV32I-NEXT: mv s0, a0 1663; RV32I-NEXT: and a0, s2, s3 1664; RV32I-NEXT: call __extendhfsf2@plt 1665; RV32I-NEXT: mv a1, a0 1666; RV32I-NEXT: mv a0, s0 1667; RV32I-NEXT: call __subsf3@plt 1668; RV32I-NEXT: call __truncsfhf2@plt 1669; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 1670; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 1671; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 1672; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 1673; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 1674; RV32I-NEXT: addi sp, sp, 32 1675; RV32I-NEXT: ret 1676; 1677; RV64I-LABEL: fmsub_s_contract: 1678; RV64I: # %bb.0: 1679; RV64I-NEXT: addi sp, sp, -48 1680; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 1681; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill 1682; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill 1683; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill 1684; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill 1685; RV64I-NEXT: mv s0, a1 1686; RV64I-NEXT: mv s1, a0 1687; RV64I-NEXT: lui a0, 16 1688; RV64I-NEXT: addiw s3, a0, -1 1689; RV64I-NEXT: and a0, a2, s3 1690; RV64I-NEXT: call __extendhfsf2@plt 1691; RV64I-NEXT: li a1, 0 1692; RV64I-NEXT: call __addsf3@plt 1693; RV64I-NEXT: call __truncsfhf2@plt 1694; RV64I-NEXT: mv s2, a0 1695; RV64I-NEXT: and a0, s1, s3 1696; RV64I-NEXT: call __extendhfsf2@plt 1697; RV64I-NEXT: mv s1, a0 1698; RV64I-NEXT: and a0, s0, s3 1699; RV64I-NEXT: call __extendhfsf2@plt 1700; RV64I-NEXT: mv a1, a0 1701; RV64I-NEXT: mv a0, s1 1702; RV64I-NEXT: call __mulsf3@plt 1703; RV64I-NEXT: call __truncsfhf2@plt 1704; RV64I-NEXT: and a0, a0, s3 1705; RV64I-NEXT: call __extendhfsf2@plt 1706; RV64I-NEXT: mv s0, a0 1707; RV64I-NEXT: and a0, s2, s3 1708; RV64I-NEXT: call __extendhfsf2@plt 1709; RV64I-NEXT: mv a1, a0 1710; RV64I-NEXT: mv a0, s0 1711; RV64I-NEXT: call __subsf3@plt 1712; RV64I-NEXT: call __truncsfhf2@plt 1713; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 1714; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload 1715; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload 1716; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload 1717; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload 1718; RV64I-NEXT: addi sp, sp, 48 1719; RV64I-NEXT: ret 1720 %c_ = fadd half 0.0, %c ; avoid negation using xor 1721 %1 = fmul contract half %a, %b 1722 %2 = fsub contract half %1, %c_ 1723 ret half %2 1724} 1725 1726define half @fnmadd_s_contract(half %a, half %b, half %c) nounwind { 1727; CHECKIZFH-LABEL: fnmadd_s_contract: 1728; CHECKIZFH: # %bb.0: 1729; CHECKIZFH-NEXT: fmv.h.x ft0, zero 1730; CHECKIZFH-NEXT: fadd.h ft1, fa0, ft0 1731; CHECKIZFH-NEXT: fadd.h ft2, fa1, ft0 1732; CHECKIZFH-NEXT: fadd.h ft0, fa2, ft0 1733; CHECKIZFH-NEXT: fnmadd.h fa0, ft1, ft2, ft0 1734; CHECKIZFH-NEXT: ret 1735; 1736; RV32I-LABEL: fnmadd_s_contract: 1737; RV32I: # %bb.0: 1738; RV32I-NEXT: addi sp, sp, -32 1739; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 1740; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 1741; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 1742; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 1743; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 1744; RV32I-NEXT: mv s0, a2 1745; RV32I-NEXT: mv s1, a1 1746; RV32I-NEXT: lui a1, 16 1747; RV32I-NEXT: addi s3, a1, -1 1748; RV32I-NEXT: and a0, a0, s3 1749; RV32I-NEXT: call __extendhfsf2@plt 1750; RV32I-NEXT: li a1, 0 1751; RV32I-NEXT: call __addsf3@plt 1752; RV32I-NEXT: call __truncsfhf2@plt 1753; RV32I-NEXT: mv s2, a0 1754; RV32I-NEXT: and a0, s1, s3 1755; RV32I-NEXT: call __extendhfsf2@plt 1756; RV32I-NEXT: li a1, 0 1757; RV32I-NEXT: call __addsf3@plt 1758; RV32I-NEXT: call __truncsfhf2@plt 1759; RV32I-NEXT: mv s1, a0 1760; RV32I-NEXT: and a0, s0, s3 1761; RV32I-NEXT: call __extendhfsf2@plt 1762; RV32I-NEXT: li a1, 0 1763; RV32I-NEXT: call __addsf3@plt 1764; RV32I-NEXT: call __truncsfhf2@plt 1765; RV32I-NEXT: mv s0, a0 1766; RV32I-NEXT: and a0, s2, s3 1767; RV32I-NEXT: call __extendhfsf2@plt 1768; RV32I-NEXT: mv s2, a0 1769; RV32I-NEXT: and a0, s1, s3 1770; RV32I-NEXT: call __extendhfsf2@plt 1771; RV32I-NEXT: mv a1, a0 1772; RV32I-NEXT: mv a0, s2 1773; RV32I-NEXT: call __mulsf3@plt 1774; RV32I-NEXT: call __truncsfhf2@plt 1775; RV32I-NEXT: and a0, a0, s3 1776; RV32I-NEXT: call __extendhfsf2@plt 1777; RV32I-NEXT: lui a1, 524288 1778; RV32I-NEXT: xor a0, a0, a1 1779; RV32I-NEXT: call __truncsfhf2@plt 1780; RV32I-NEXT: mv s1, a0 1781; RV32I-NEXT: and a0, s0, s3 1782; RV32I-NEXT: call __extendhfsf2@plt 1783; RV32I-NEXT: mv s0, a0 1784; RV32I-NEXT: and a0, s1, s3 1785; RV32I-NEXT: call __extendhfsf2@plt 1786; RV32I-NEXT: mv a1, s0 1787; RV32I-NEXT: call __subsf3@plt 1788; RV32I-NEXT: call __truncsfhf2@plt 1789; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 1790; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 1791; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 1792; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 1793; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 1794; RV32I-NEXT: addi sp, sp, 32 1795; RV32I-NEXT: ret 1796; 1797; RV64I-LABEL: fnmadd_s_contract: 1798; RV64I: # %bb.0: 1799; RV64I-NEXT: addi sp, sp, -48 1800; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 1801; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill 1802; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill 1803; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill 1804; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill 1805; RV64I-NEXT: mv s0, a2 1806; RV64I-NEXT: mv s1, a1 1807; RV64I-NEXT: lui a1, 16 1808; RV64I-NEXT: addiw s3, a1, -1 1809; RV64I-NEXT: and a0, a0, s3 1810; RV64I-NEXT: call __extendhfsf2@plt 1811; RV64I-NEXT: li a1, 0 1812; RV64I-NEXT: call __addsf3@plt 1813; RV64I-NEXT: call __truncsfhf2@plt 1814; RV64I-NEXT: mv s2, a0 1815; RV64I-NEXT: and a0, s1, s3 1816; RV64I-NEXT: call __extendhfsf2@plt 1817; RV64I-NEXT: li a1, 0 1818; RV64I-NEXT: call __addsf3@plt 1819; RV64I-NEXT: call __truncsfhf2@plt 1820; RV64I-NEXT: mv s1, a0 1821; RV64I-NEXT: and a0, s0, s3 1822; RV64I-NEXT: call __extendhfsf2@plt 1823; RV64I-NEXT: li a1, 0 1824; RV64I-NEXT: call __addsf3@plt 1825; RV64I-NEXT: call __truncsfhf2@plt 1826; RV64I-NEXT: mv s0, a0 1827; RV64I-NEXT: and a0, s2, s3 1828; RV64I-NEXT: call __extendhfsf2@plt 1829; RV64I-NEXT: mv s2, a0 1830; RV64I-NEXT: and a0, s1, s3 1831; RV64I-NEXT: call __extendhfsf2@plt 1832; RV64I-NEXT: mv a1, a0 1833; RV64I-NEXT: mv a0, s2 1834; RV64I-NEXT: call __mulsf3@plt 1835; RV64I-NEXT: call __truncsfhf2@plt 1836; RV64I-NEXT: and a0, a0, s3 1837; RV64I-NEXT: call __extendhfsf2@plt 1838; RV64I-NEXT: lui a1, 524288 1839; RV64I-NEXT: xor a0, a0, a1 1840; RV64I-NEXT: call __truncsfhf2@plt 1841; RV64I-NEXT: mv s1, a0 1842; RV64I-NEXT: and a0, s0, s3 1843; RV64I-NEXT: call __extendhfsf2@plt 1844; RV64I-NEXT: mv s0, a0 1845; RV64I-NEXT: and a0, s1, s3 1846; RV64I-NEXT: call __extendhfsf2@plt 1847; RV64I-NEXT: mv a1, s0 1848; RV64I-NEXT: call __subsf3@plt 1849; RV64I-NEXT: call __truncsfhf2@plt 1850; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 1851; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload 1852; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload 1853; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload 1854; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload 1855; RV64I-NEXT: addi sp, sp, 48 1856; RV64I-NEXT: ret 1857 %a_ = fadd half 0.0, %a ; avoid negation using xor 1858 %b_ = fadd half 0.0, %b ; avoid negation using xor 1859 %c_ = fadd half 0.0, %c ; avoid negation using xor 1860 %1 = fmul contract half %a_, %b_ 1861 %2 = fneg half %1 1862 %3 = fsub contract half %2, %c_ 1863 ret half %3 1864} 1865 1866define half @fnmsub_s_contract(half %a, half %b, half %c) nounwind { 1867; CHECKIZFH-LABEL: fnmsub_s_contract: 1868; CHECKIZFH: # %bb.0: 1869; CHECKIZFH-NEXT: fmv.h.x ft0, zero 1870; CHECKIZFH-NEXT: fadd.h ft1, fa0, ft0 1871; CHECKIZFH-NEXT: fadd.h ft0, fa1, ft0 1872; CHECKIZFH-NEXT: fnmsub.h fa0, ft1, ft0, fa2 1873; CHECKIZFH-NEXT: ret 1874; 1875; RV32I-LABEL: fnmsub_s_contract: 1876; RV32I: # %bb.0: 1877; RV32I-NEXT: addi sp, sp, -32 1878; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 1879; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 1880; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 1881; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 1882; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 1883; RV32I-NEXT: mv s0, a2 1884; RV32I-NEXT: mv s1, a1 1885; RV32I-NEXT: lui a1, 16 1886; RV32I-NEXT: addi s3, a1, -1 1887; RV32I-NEXT: and a0, a0, s3 1888; RV32I-NEXT: call __extendhfsf2@plt 1889; RV32I-NEXT: li a1, 0 1890; RV32I-NEXT: call __addsf3@plt 1891; RV32I-NEXT: call __truncsfhf2@plt 1892; RV32I-NEXT: mv s2, a0 1893; RV32I-NEXT: and a0, s1, s3 1894; RV32I-NEXT: call __extendhfsf2@plt 1895; RV32I-NEXT: li a1, 0 1896; RV32I-NEXT: call __addsf3@plt 1897; RV32I-NEXT: call __truncsfhf2@plt 1898; RV32I-NEXT: mv s1, a0 1899; RV32I-NEXT: and a0, s2, s3 1900; RV32I-NEXT: call __extendhfsf2@plt 1901; RV32I-NEXT: mv s2, a0 1902; RV32I-NEXT: and a0, s1, s3 1903; RV32I-NEXT: call __extendhfsf2@plt 1904; RV32I-NEXT: mv a1, a0 1905; RV32I-NEXT: mv a0, s2 1906; RV32I-NEXT: call __mulsf3@plt 1907; RV32I-NEXT: call __truncsfhf2@plt 1908; RV32I-NEXT: mv s1, a0 1909; RV32I-NEXT: and a0, s0, s3 1910; RV32I-NEXT: call __extendhfsf2@plt 1911; RV32I-NEXT: mv s0, a0 1912; RV32I-NEXT: and a0, s1, s3 1913; RV32I-NEXT: call __extendhfsf2@plt 1914; RV32I-NEXT: mv a1, a0 1915; RV32I-NEXT: mv a0, s0 1916; RV32I-NEXT: call __subsf3@plt 1917; RV32I-NEXT: call __truncsfhf2@plt 1918; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 1919; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 1920; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 1921; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 1922; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 1923; RV32I-NEXT: addi sp, sp, 32 1924; RV32I-NEXT: ret 1925; 1926; RV64I-LABEL: fnmsub_s_contract: 1927; RV64I: # %bb.0: 1928; RV64I-NEXT: addi sp, sp, -48 1929; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 1930; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill 1931; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill 1932; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill 1933; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill 1934; RV64I-NEXT: mv s0, a2 1935; RV64I-NEXT: mv s1, a1 1936; RV64I-NEXT: lui a1, 16 1937; RV64I-NEXT: addiw s3, a1, -1 1938; RV64I-NEXT: and a0, a0, s3 1939; RV64I-NEXT: call __extendhfsf2@plt 1940; RV64I-NEXT: li a1, 0 1941; RV64I-NEXT: call __addsf3@plt 1942; RV64I-NEXT: call __truncsfhf2@plt 1943; RV64I-NEXT: mv s2, a0 1944; RV64I-NEXT: and a0, s1, s3 1945; RV64I-NEXT: call __extendhfsf2@plt 1946; RV64I-NEXT: li a1, 0 1947; RV64I-NEXT: call __addsf3@plt 1948; RV64I-NEXT: call __truncsfhf2@plt 1949; RV64I-NEXT: mv s1, a0 1950; RV64I-NEXT: and a0, s2, s3 1951; RV64I-NEXT: call __extendhfsf2@plt 1952; RV64I-NEXT: mv s2, a0 1953; RV64I-NEXT: and a0, s1, s3 1954; RV64I-NEXT: call __extendhfsf2@plt 1955; RV64I-NEXT: mv a1, a0 1956; RV64I-NEXT: mv a0, s2 1957; RV64I-NEXT: call __mulsf3@plt 1958; RV64I-NEXT: call __truncsfhf2@plt 1959; RV64I-NEXT: mv s1, a0 1960; RV64I-NEXT: and a0, s0, s3 1961; RV64I-NEXT: call __extendhfsf2@plt 1962; RV64I-NEXT: mv s0, a0 1963; RV64I-NEXT: and a0, s1, s3 1964; RV64I-NEXT: call __extendhfsf2@plt 1965; RV64I-NEXT: mv a1, a0 1966; RV64I-NEXT: mv a0, s0 1967; RV64I-NEXT: call __subsf3@plt 1968; RV64I-NEXT: call __truncsfhf2@plt 1969; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 1970; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload 1971; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload 1972; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload 1973; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload 1974; RV64I-NEXT: addi sp, sp, 48 1975; RV64I-NEXT: ret 1976 %a_ = fadd half 0.0, %a ; avoid negation using xor 1977 %b_ = fadd half 0.0, %b ; avoid negation using xor 1978 %1 = fmul contract half %a_, %b_ 1979 %2 = fsub contract half %c, %1 1980 ret half %2 1981} 1982