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