1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -mattr=+f -verify-machineinstrs < %s \ 3; RUN: -target-abi=ilp32f | FileCheck -check-prefix=CHECKIF %s 4; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs < %s \ 5; RUN: -target-abi=lp64f | FileCheck -check-prefix=CHECKIF %s 6; RUN: llc -mtriple=riscv32 -mattr=+zfinx -verify-machineinstrs < %s \ 7; RUN: -target-abi=ilp32 | FileCheck -check-prefixes=CHECKIZFINX,RV32IZFINX %s 8; RUN: llc -mtriple=riscv64 -mattr=+zfinx -verify-machineinstrs < %s \ 9; RUN: -target-abi=lp64 | FileCheck -check-prefixes=CHECKIZFINX,RV64IZFINX %s 10; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ 11; RUN: | FileCheck -check-prefix=RV32I %s 12; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ 13; RUN: | FileCheck -check-prefix=RV64I %s 14 15; These tests are each targeted at a particular RISC-V FPU instruction. 16; Compares and conversions can be found in float-fcmp.ll and float-convert.ll 17; respectively. Some other float-*.ll files in this folder exercise LLVM IR 18; instructions that don't directly match a RISC-V instruction. 19 20define float @fadd_s(float %a, float %b) nounwind { 21; CHECKIF-LABEL: fadd_s: 22; CHECKIF: # %bb.0: 23; CHECKIF-NEXT: fadd.s fa0, fa0, fa1 24; CHECKIF-NEXT: ret 25; 26; CHECKIZFINX-LABEL: fadd_s: 27; CHECKIZFINX: # %bb.0: 28; CHECKIZFINX-NEXT: fadd.s a0, a0, a1 29; CHECKIZFINX-NEXT: ret 30; 31; RV32I-LABEL: fadd_s: 32; RV32I: # %bb.0: 33; RV32I-NEXT: addi sp, sp, -16 34; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 35; RV32I-NEXT: call __addsf3 36; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 37; RV32I-NEXT: addi sp, sp, 16 38; RV32I-NEXT: ret 39; 40; RV64I-LABEL: fadd_s: 41; RV64I: # %bb.0: 42; RV64I-NEXT: addi sp, sp, -16 43; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 44; RV64I-NEXT: call __addsf3 45; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 46; RV64I-NEXT: addi sp, sp, 16 47; RV64I-NEXT: ret 48 %1 = fadd float %a, %b 49 ret float %1 50} 51 52define float @fsub_s(float %a, float %b) nounwind { 53; CHECKIF-LABEL: fsub_s: 54; CHECKIF: # %bb.0: 55; CHECKIF-NEXT: fsub.s fa0, fa0, fa1 56; CHECKIF-NEXT: ret 57; 58; CHECKIZFINX-LABEL: fsub_s: 59; CHECKIZFINX: # %bb.0: 60; CHECKIZFINX-NEXT: fsub.s a0, a0, a1 61; CHECKIZFINX-NEXT: ret 62; 63; RV32I-LABEL: fsub_s: 64; RV32I: # %bb.0: 65; RV32I-NEXT: addi sp, sp, -16 66; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 67; RV32I-NEXT: call __subsf3 68; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 69; RV32I-NEXT: addi sp, sp, 16 70; RV32I-NEXT: ret 71; 72; RV64I-LABEL: fsub_s: 73; RV64I: # %bb.0: 74; RV64I-NEXT: addi sp, sp, -16 75; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 76; RV64I-NEXT: call __subsf3 77; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 78; RV64I-NEXT: addi sp, sp, 16 79; RV64I-NEXT: ret 80 %1 = fsub float %a, %b 81 ret float %1 82} 83 84define float @fmul_s(float %a, float %b) nounwind { 85; CHECKIF-LABEL: fmul_s: 86; CHECKIF: # %bb.0: 87; CHECKIF-NEXT: fmul.s fa0, fa0, fa1 88; CHECKIF-NEXT: ret 89; 90; CHECKIZFINX-LABEL: fmul_s: 91; CHECKIZFINX: # %bb.0: 92; CHECKIZFINX-NEXT: fmul.s a0, a0, a1 93; CHECKIZFINX-NEXT: ret 94; 95; RV32I-LABEL: fmul_s: 96; RV32I: # %bb.0: 97; RV32I-NEXT: addi sp, sp, -16 98; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 99; RV32I-NEXT: call __mulsf3 100; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 101; RV32I-NEXT: addi sp, sp, 16 102; RV32I-NEXT: ret 103; 104; RV64I-LABEL: fmul_s: 105; RV64I: # %bb.0: 106; RV64I-NEXT: addi sp, sp, -16 107; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 108; RV64I-NEXT: call __mulsf3 109; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 110; RV64I-NEXT: addi sp, sp, 16 111; RV64I-NEXT: ret 112 %1 = fmul float %a, %b 113 ret float %1 114} 115 116define float @fdiv_s(float %a, float %b) nounwind { 117; CHECKIF-LABEL: fdiv_s: 118; CHECKIF: # %bb.0: 119; CHECKIF-NEXT: fdiv.s fa0, fa0, fa1 120; CHECKIF-NEXT: ret 121; 122; CHECKIZFINX-LABEL: fdiv_s: 123; CHECKIZFINX: # %bb.0: 124; CHECKIZFINX-NEXT: fdiv.s a0, a0, a1 125; CHECKIZFINX-NEXT: ret 126; 127; RV32I-LABEL: fdiv_s: 128; RV32I: # %bb.0: 129; RV32I-NEXT: addi sp, sp, -16 130; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 131; RV32I-NEXT: call __divsf3 132; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 133; RV32I-NEXT: addi sp, sp, 16 134; RV32I-NEXT: ret 135; 136; RV64I-LABEL: fdiv_s: 137; RV64I: # %bb.0: 138; RV64I-NEXT: addi sp, sp, -16 139; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 140; RV64I-NEXT: call __divsf3 141; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 142; RV64I-NEXT: addi sp, sp, 16 143; RV64I-NEXT: ret 144 %1 = fdiv float %a, %b 145 ret float %1 146} 147 148declare float @llvm.sqrt.f32(float) 149 150define float @fsqrt_s(float %a) nounwind { 151; CHECKIF-LABEL: fsqrt_s: 152; CHECKIF: # %bb.0: 153; CHECKIF-NEXT: fsqrt.s fa0, fa0 154; CHECKIF-NEXT: ret 155; 156; CHECKIZFINX-LABEL: fsqrt_s: 157; CHECKIZFINX: # %bb.0: 158; CHECKIZFINX-NEXT: fsqrt.s a0, a0 159; CHECKIZFINX-NEXT: ret 160; 161; RV32I-LABEL: fsqrt_s: 162; RV32I: # %bb.0: 163; RV32I-NEXT: addi sp, sp, -16 164; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 165; RV32I-NEXT: call sqrtf 166; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 167; RV32I-NEXT: addi sp, sp, 16 168; RV32I-NEXT: ret 169; 170; RV64I-LABEL: fsqrt_s: 171; RV64I: # %bb.0: 172; RV64I-NEXT: addi sp, sp, -16 173; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 174; RV64I-NEXT: call sqrtf 175; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 176; RV64I-NEXT: addi sp, sp, 16 177; RV64I-NEXT: ret 178 %1 = call float @llvm.sqrt.f32(float %a) 179 ret float %1 180} 181 182declare float @llvm.copysign.f32(float, float) 183 184define float @fsgnj_s(float %a, float %b) nounwind { 185; CHECKIF-LABEL: fsgnj_s: 186; CHECKIF: # %bb.0: 187; CHECKIF-NEXT: fsgnj.s fa0, fa0, fa1 188; CHECKIF-NEXT: ret 189; 190; CHECKIZFINX-LABEL: fsgnj_s: 191; CHECKIZFINX: # %bb.0: 192; CHECKIZFINX-NEXT: fsgnj.s a0, a0, a1 193; CHECKIZFINX-NEXT: ret 194; 195; RV32I-LABEL: fsgnj_s: 196; RV32I: # %bb.0: 197; RV32I-NEXT: lui a2, 524288 198; RV32I-NEXT: slli a0, a0, 1 199; RV32I-NEXT: and a1, a1, a2 200; RV32I-NEXT: srli a0, a0, 1 201; RV32I-NEXT: or a0, a0, a1 202; RV32I-NEXT: ret 203; 204; RV64I-LABEL: fsgnj_s: 205; RV64I: # %bb.0: 206; RV64I-NEXT: lui a2, 524288 207; RV64I-NEXT: slli a0, a0, 33 208; RV64I-NEXT: and a1, a1, a2 209; RV64I-NEXT: srli a0, a0, 33 210; RV64I-NEXT: or a0, a0, a1 211; RV64I-NEXT: ret 212 %1 = call float @llvm.copysign.f32(float %a, float %b) 213 ret float %1 214} 215 216define i32 @fneg_s(float %a, float %b) nounwind { 217; CHECKIF-LABEL: fneg_s: 218; CHECKIF: # %bb.0: 219; CHECKIF-NEXT: fadd.s fa5, fa0, fa0 220; CHECKIF-NEXT: fneg.s fa4, fa5 221; CHECKIF-NEXT: feq.s a0, fa5, fa4 222; CHECKIF-NEXT: ret 223; 224; CHECKIZFINX-LABEL: fneg_s: 225; CHECKIZFINX: # %bb.0: 226; CHECKIZFINX-NEXT: fadd.s a0, a0, a0 227; CHECKIZFINX-NEXT: fneg.s a1, a0 228; CHECKIZFINX-NEXT: feq.s a0, a0, a1 229; CHECKIZFINX-NEXT: ret 230; 231; RV32I-LABEL: fneg_s: 232; RV32I: # %bb.0: 233; RV32I-NEXT: addi sp, sp, -16 234; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 235; RV32I-NEXT: mv a1, a0 236; RV32I-NEXT: call __addsf3 237; RV32I-NEXT: lui a1, 524288 238; RV32I-NEXT: xor a1, a0, a1 239; RV32I-NEXT: call __eqsf2 240; RV32I-NEXT: seqz a0, a0 241; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 242; RV32I-NEXT: addi sp, sp, 16 243; RV32I-NEXT: ret 244; 245; RV64I-LABEL: fneg_s: 246; RV64I: # %bb.0: 247; RV64I-NEXT: addi sp, sp, -16 248; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 249; RV64I-NEXT: mv a1, a0 250; RV64I-NEXT: call __addsf3 251; RV64I-NEXT: lui a1, 524288 252; RV64I-NEXT: xor a1, a0, a1 253; RV64I-NEXT: call __eqsf2 254; RV64I-NEXT: seqz a0, a0 255; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 256; RV64I-NEXT: addi sp, sp, 16 257; RV64I-NEXT: ret 258 %1 = fadd float %a, %a 259 %2 = fneg float %1 260 %3 = fcmp oeq float %1, %2 261 %4 = zext i1 %3 to i32 262 ret i32 %4 263} 264 265define float @fsgnjn_s(float %a, float %b) nounwind { 266; CHECKIF-LABEL: fsgnjn_s: 267; CHECKIF: # %bb.0: 268; CHECKIF-NEXT: fadd.s fa5, fa0, fa1 269; CHECKIF-NEXT: fsgnjn.s fa0, fa0, fa5 270; CHECKIF-NEXT: ret 271; 272; CHECKIZFINX-LABEL: fsgnjn_s: 273; CHECKIZFINX: # %bb.0: 274; CHECKIZFINX-NEXT: fadd.s a1, a0, a1 275; CHECKIZFINX-NEXT: fsgnjn.s a0, a0, a1 276; CHECKIZFINX-NEXT: ret 277; 278; RV32I-LABEL: fsgnjn_s: 279; RV32I: # %bb.0: 280; RV32I-NEXT: addi sp, sp, -16 281; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 282; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 283; RV32I-NEXT: mv s0, a0 284; RV32I-NEXT: call __addsf3 285; RV32I-NEXT: not a0, a0 286; RV32I-NEXT: lui a1, 524288 287; RV32I-NEXT: slli s0, s0, 1 288; RV32I-NEXT: and a0, a0, a1 289; RV32I-NEXT: srli s0, s0, 1 290; RV32I-NEXT: or a0, s0, a0 291; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 292; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 293; RV32I-NEXT: addi sp, sp, 16 294; RV32I-NEXT: ret 295; 296; RV64I-LABEL: fsgnjn_s: 297; RV64I: # %bb.0: 298; RV64I-NEXT: addi sp, sp, -16 299; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 300; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill 301; RV64I-NEXT: mv s0, a0 302; RV64I-NEXT: call __addsf3 303; RV64I-NEXT: not a0, a0 304; RV64I-NEXT: lui a1, 524288 305; RV64I-NEXT: slli s0, s0, 33 306; RV64I-NEXT: and a0, a0, a1 307; RV64I-NEXT: srli s0, s0, 33 308; RV64I-NEXT: or a0, s0, a0 309; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 310; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload 311; RV64I-NEXT: addi sp, sp, 16 312; RV64I-NEXT: ret 313 %1 = fadd float %a, %b 314 %2 = fneg float %1 315 %3 = call float @llvm.copysign.f32(float %a, float %2) 316 ret float %3 317} 318 319declare float @llvm.fabs.f32(float) 320 321define float @fabs_s(float %a, float %b) nounwind { 322; CHECKIF-LABEL: fabs_s: 323; CHECKIF: # %bb.0: 324; CHECKIF-NEXT: fadd.s fa5, fa0, fa1 325; CHECKIF-NEXT: fabs.s fa4, fa5 326; CHECKIF-NEXT: fadd.s fa0, fa4, fa5 327; CHECKIF-NEXT: ret 328; 329; CHECKIZFINX-LABEL: fabs_s: 330; CHECKIZFINX: # %bb.0: 331; CHECKIZFINX-NEXT: fadd.s a0, a0, a1 332; CHECKIZFINX-NEXT: fabs.s a1, a0 333; CHECKIZFINX-NEXT: fadd.s a0, a1, a0 334; CHECKIZFINX-NEXT: ret 335; 336; RV32I-LABEL: fabs_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: call __addsf3 341; RV32I-NEXT: mv a1, a0 342; RV32I-NEXT: slli a0, a0, 1 343; RV32I-NEXT: srli a0, a0, 1 344; RV32I-NEXT: call __addsf3 345; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 346; RV32I-NEXT: addi sp, sp, 16 347; RV32I-NEXT: ret 348; 349; RV64I-LABEL: fabs_s: 350; RV64I: # %bb.0: 351; RV64I-NEXT: addi sp, sp, -16 352; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 353; RV64I-NEXT: call __addsf3 354; RV64I-NEXT: mv a1, a0 355; RV64I-NEXT: slli a0, a0, 33 356; RV64I-NEXT: srli a0, a0, 33 357; RV64I-NEXT: call __addsf3 358; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 359; RV64I-NEXT: addi sp, sp, 16 360; RV64I-NEXT: ret 361 %1 = fadd float %a, %b 362 %2 = call float @llvm.fabs.f32(float %1) 363 %3 = fadd float %2, %1 364 ret float %3 365} 366 367declare float @llvm.minnum.f32(float, float) 368 369define float @fmin_s(float %a, float %b) nounwind { 370; CHECKIF-LABEL: fmin_s: 371; CHECKIF: # %bb.0: 372; CHECKIF-NEXT: fmin.s fa0, fa0, fa1 373; CHECKIF-NEXT: ret 374; 375; CHECKIZFINX-LABEL: fmin_s: 376; CHECKIZFINX: # %bb.0: 377; CHECKIZFINX-NEXT: fmin.s a0, a0, a1 378; CHECKIZFINX-NEXT: ret 379; 380; RV32I-LABEL: fmin_s: 381; RV32I: # %bb.0: 382; RV32I-NEXT: addi sp, sp, -16 383; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 384; RV32I-NEXT: call fminf 385; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 386; RV32I-NEXT: addi sp, sp, 16 387; RV32I-NEXT: ret 388; 389; RV64I-LABEL: fmin_s: 390; RV64I: # %bb.0: 391; RV64I-NEXT: addi sp, sp, -16 392; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 393; RV64I-NEXT: call fminf 394; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 395; RV64I-NEXT: addi sp, sp, 16 396; RV64I-NEXT: ret 397 %1 = call float @llvm.minnum.f32(float %a, float %b) 398 ret float %1 399} 400 401declare float @llvm.maxnum.f32(float, float) 402 403define float @fmax_s(float %a, float %b) nounwind { 404; CHECKIF-LABEL: fmax_s: 405; CHECKIF: # %bb.0: 406; CHECKIF-NEXT: fmax.s fa0, fa0, fa1 407; CHECKIF-NEXT: ret 408; 409; CHECKIZFINX-LABEL: fmax_s: 410; CHECKIZFINX: # %bb.0: 411; CHECKIZFINX-NEXT: fmax.s a0, a0, a1 412; CHECKIZFINX-NEXT: ret 413; 414; RV32I-LABEL: fmax_s: 415; RV32I: # %bb.0: 416; RV32I-NEXT: addi sp, sp, -16 417; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 418; RV32I-NEXT: call fmaxf 419; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 420; RV32I-NEXT: addi sp, sp, 16 421; RV32I-NEXT: ret 422; 423; RV64I-LABEL: fmax_s: 424; RV64I: # %bb.0: 425; RV64I-NEXT: addi sp, sp, -16 426; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 427; RV64I-NEXT: call fmaxf 428; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 429; RV64I-NEXT: addi sp, sp, 16 430; RV64I-NEXT: ret 431 %1 = call float @llvm.maxnum.f32(float %a, float %b) 432 ret float %1 433} 434 435declare float @llvm.fma.f32(float, float, float) 436 437define float @fmadd_s(float %a, float %b, float %c) nounwind { 438; CHECKIF-LABEL: fmadd_s: 439; CHECKIF: # %bb.0: 440; CHECKIF-NEXT: fmadd.s fa0, fa0, fa1, fa2 441; CHECKIF-NEXT: ret 442; 443; CHECKIZFINX-LABEL: fmadd_s: 444; CHECKIZFINX: # %bb.0: 445; CHECKIZFINX-NEXT: fmadd.s a0, a0, a1, a2 446; CHECKIZFINX-NEXT: ret 447; 448; RV32I-LABEL: fmadd_s: 449; RV32I: # %bb.0: 450; RV32I-NEXT: addi sp, sp, -16 451; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 452; RV32I-NEXT: call fmaf 453; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 454; RV32I-NEXT: addi sp, sp, 16 455; RV32I-NEXT: ret 456; 457; RV64I-LABEL: fmadd_s: 458; RV64I: # %bb.0: 459; RV64I-NEXT: addi sp, sp, -16 460; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 461; RV64I-NEXT: call fmaf 462; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 463; RV64I-NEXT: addi sp, sp, 16 464; RV64I-NEXT: ret 465 %1 = call float @llvm.fma.f32(float %a, float %b, float %c) 466 ret float %1 467} 468 469define float @fmsub_s(float %a, float %b, float %c) nounwind { 470; CHECKIF-LABEL: fmsub_s: 471; CHECKIF: # %bb.0: 472; CHECKIF-NEXT: fmv.w.x fa5, zero 473; CHECKIF-NEXT: fadd.s fa5, fa2, fa5 474; CHECKIF-NEXT: fmsub.s fa0, fa0, fa1, fa5 475; CHECKIF-NEXT: ret 476; 477; CHECKIZFINX-LABEL: fmsub_s: 478; CHECKIZFINX: # %bb.0: 479; CHECKIZFINX-NEXT: fadd.s a2, a2, zero 480; CHECKIZFINX-NEXT: fmsub.s a0, a0, a1, a2 481; CHECKIZFINX-NEXT: ret 482; 483; RV32I-LABEL: fmsub_s: 484; RV32I: # %bb.0: 485; RV32I-NEXT: addi sp, sp, -16 486; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 487; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 488; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 489; RV32I-NEXT: mv s0, a1 490; RV32I-NEXT: mv s1, a0 491; RV32I-NEXT: mv a0, a2 492; RV32I-NEXT: li a1, 0 493; RV32I-NEXT: call __addsf3 494; RV32I-NEXT: lui a2, 524288 495; RV32I-NEXT: xor a2, a0, a2 496; RV32I-NEXT: mv a0, s1 497; RV32I-NEXT: mv a1, s0 498; RV32I-NEXT: call fmaf 499; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 500; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 501; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 502; RV32I-NEXT: addi sp, sp, 16 503; RV32I-NEXT: ret 504; 505; RV64I-LABEL: fmsub_s: 506; RV64I: # %bb.0: 507; RV64I-NEXT: addi sp, sp, -32 508; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 509; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 510; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 511; RV64I-NEXT: mv s0, a1 512; RV64I-NEXT: mv s1, a0 513; RV64I-NEXT: mv a0, a2 514; RV64I-NEXT: li a1, 0 515; RV64I-NEXT: call __addsf3 516; RV64I-NEXT: lui a2, 524288 517; RV64I-NEXT: xor a2, a0, a2 518; RV64I-NEXT: mv a0, s1 519; RV64I-NEXT: mv a1, s0 520; RV64I-NEXT: call fmaf 521; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 522; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 523; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 524; RV64I-NEXT: addi sp, sp, 32 525; RV64I-NEXT: ret 526 %c_ = fadd float 0.0, %c ; avoid negation using xor 527 %negc = fsub float -0.0, %c_ 528 %1 = call float @llvm.fma.f32(float %a, float %b, float %negc) 529 ret float %1 530} 531 532define float @fnmadd_s(float %a, float %b, float %c) nounwind { 533; CHECKIF-LABEL: fnmadd_s: 534; CHECKIF: # %bb.0: 535; CHECKIF-NEXT: fmv.w.x fa5, zero 536; CHECKIF-NEXT: fadd.s fa4, fa0, fa5 537; CHECKIF-NEXT: fadd.s fa5, fa2, fa5 538; CHECKIF-NEXT: fnmadd.s fa0, fa4, fa1, fa5 539; CHECKIF-NEXT: ret 540; 541; CHECKIZFINX-LABEL: fnmadd_s: 542; CHECKIZFINX: # %bb.0: 543; CHECKIZFINX-NEXT: fadd.s a0, a0, zero 544; CHECKIZFINX-NEXT: fadd.s a2, a2, zero 545; CHECKIZFINX-NEXT: fnmadd.s a0, a0, a1, a2 546; CHECKIZFINX-NEXT: ret 547; 548; RV32I-LABEL: fnmadd_s: 549; RV32I: # %bb.0: 550; RV32I-NEXT: addi sp, sp, -16 551; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 552; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 553; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 554; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 555; RV32I-NEXT: mv s0, a2 556; RV32I-NEXT: mv s1, a1 557; RV32I-NEXT: li a1, 0 558; RV32I-NEXT: call __addsf3 559; RV32I-NEXT: mv s2, a0 560; RV32I-NEXT: mv a0, s0 561; RV32I-NEXT: li a1, 0 562; RV32I-NEXT: call __addsf3 563; RV32I-NEXT: lui a2, 524288 564; RV32I-NEXT: xor a1, s2, a2 565; RV32I-NEXT: xor a2, a0, a2 566; RV32I-NEXT: mv a0, a1 567; RV32I-NEXT: mv a1, s1 568; RV32I-NEXT: call fmaf 569; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 570; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 571; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 572; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 573; RV32I-NEXT: addi sp, sp, 16 574; RV32I-NEXT: ret 575; 576; RV64I-LABEL: fnmadd_s: 577; RV64I: # %bb.0: 578; RV64I-NEXT: addi sp, sp, -32 579; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 580; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 581; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 582; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 583; RV64I-NEXT: mv s0, a2 584; RV64I-NEXT: mv s1, a1 585; RV64I-NEXT: li a1, 0 586; RV64I-NEXT: call __addsf3 587; RV64I-NEXT: mv s2, a0 588; RV64I-NEXT: mv a0, s0 589; RV64I-NEXT: li a1, 0 590; RV64I-NEXT: call __addsf3 591; RV64I-NEXT: lui a2, 524288 592; RV64I-NEXT: xor a1, s2, a2 593; RV64I-NEXT: xor a2, a0, a2 594; RV64I-NEXT: mv a0, a1 595; RV64I-NEXT: mv a1, s1 596; RV64I-NEXT: call fmaf 597; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 598; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 599; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 600; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 601; RV64I-NEXT: addi sp, sp, 32 602; RV64I-NEXT: ret 603 %a_ = fadd float 0.0, %a 604 %c_ = fadd float 0.0, %c 605 %nega = fsub float -0.0, %a_ 606 %negc = fsub float -0.0, %c_ 607 %1 = call float @llvm.fma.f32(float %nega, float %b, float %negc) 608 ret float %1 609} 610 611define float @fnmadd_s_2(float %a, float %b, float %c) nounwind { 612; CHECKIF-LABEL: fnmadd_s_2: 613; CHECKIF: # %bb.0: 614; CHECKIF-NEXT: fmv.w.x fa5, zero 615; CHECKIF-NEXT: fadd.s fa4, fa1, fa5 616; CHECKIF-NEXT: fadd.s fa5, fa2, fa5 617; CHECKIF-NEXT: fnmadd.s fa0, fa4, fa0, fa5 618; CHECKIF-NEXT: ret 619; 620; CHECKIZFINX-LABEL: fnmadd_s_2: 621; CHECKIZFINX: # %bb.0: 622; CHECKIZFINX-NEXT: fadd.s a1, a1, zero 623; CHECKIZFINX-NEXT: fadd.s a2, a2, zero 624; CHECKIZFINX-NEXT: fnmadd.s a0, a1, a0, a2 625; CHECKIZFINX-NEXT: ret 626; 627; RV32I-LABEL: fnmadd_s_2: 628; RV32I: # %bb.0: 629; RV32I-NEXT: addi sp, sp, -16 630; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 631; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 632; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 633; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 634; RV32I-NEXT: mv s0, a2 635; RV32I-NEXT: mv s1, a0 636; RV32I-NEXT: mv a0, a1 637; RV32I-NEXT: li a1, 0 638; RV32I-NEXT: call __addsf3 639; RV32I-NEXT: mv s2, a0 640; RV32I-NEXT: mv a0, s0 641; RV32I-NEXT: li a1, 0 642; RV32I-NEXT: call __addsf3 643; RV32I-NEXT: lui a2, 524288 644; RV32I-NEXT: xor a1, s2, a2 645; RV32I-NEXT: xor a2, a0, a2 646; RV32I-NEXT: mv a0, s1 647; RV32I-NEXT: call fmaf 648; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 649; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 650; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 651; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 652; RV32I-NEXT: addi sp, sp, 16 653; RV32I-NEXT: ret 654; 655; RV64I-LABEL: fnmadd_s_2: 656; RV64I: # %bb.0: 657; RV64I-NEXT: addi sp, sp, -32 658; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 659; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 660; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 661; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 662; RV64I-NEXT: mv s0, a2 663; RV64I-NEXT: mv s1, a0 664; RV64I-NEXT: mv a0, a1 665; RV64I-NEXT: li a1, 0 666; RV64I-NEXT: call __addsf3 667; RV64I-NEXT: mv s2, a0 668; RV64I-NEXT: mv a0, s0 669; RV64I-NEXT: li a1, 0 670; RV64I-NEXT: call __addsf3 671; RV64I-NEXT: lui a2, 524288 672; RV64I-NEXT: xor a1, s2, a2 673; RV64I-NEXT: xor a2, a0, a2 674; RV64I-NEXT: mv a0, s1 675; RV64I-NEXT: call fmaf 676; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 677; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 678; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 679; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 680; RV64I-NEXT: addi sp, sp, 32 681; RV64I-NEXT: ret 682 %b_ = fadd float 0.0, %b 683 %c_ = fadd float 0.0, %c 684 %negb = fsub float -0.0, %b_ 685 %negc = fsub float -0.0, %c_ 686 %1 = call float @llvm.fma.f32(float %a, float %negb, float %negc) 687 ret float %1 688} 689 690define float @fnmadd_s_3(float %a, float %b, float %c) nounwind { 691; RV32IF-LABEL: fnmadd_s_3: 692; RV32IF: # %bb.0: 693; RV32IF-NEXT: fmadd.s ft0, fa0, fa1, fa2 694; RV32IF-NEXT: fneg.s fa0, ft0 695; RV32IF-NEXT: ret 696; 697; RV64IF-LABEL: fnmadd_s_3: 698; RV64IF: # %bb.0: 699; RV64IF-NEXT: fmadd.s ft0, fa0, fa1, fa2 700; RV64IF-NEXT: fneg.s fa0, ft0 701; RV64IF-NEXT: ret 702; 703; CHECKIF-LABEL: fnmadd_s_3: 704; CHECKIF: # %bb.0: 705; CHECKIF-NEXT: fmadd.s fa5, fa0, fa1, fa2 706; CHECKIF-NEXT: fneg.s fa0, fa5 707; CHECKIF-NEXT: ret 708; 709; CHECKIZFINX-LABEL: fnmadd_s_3: 710; CHECKIZFINX: # %bb.0: 711; CHECKIZFINX-NEXT: fmadd.s a0, a0, a1, a2 712; CHECKIZFINX-NEXT: fneg.s a0, a0 713; CHECKIZFINX-NEXT: ret 714; 715; RV32I-LABEL: fnmadd_s_3: 716; RV32I: # %bb.0: 717; RV32I-NEXT: addi sp, sp, -16 718; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 719; RV32I-NEXT: call fmaf 720; RV32I-NEXT: lui a1, 524288 721; RV32I-NEXT: xor a0, a0, a1 722; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 723; RV32I-NEXT: addi sp, sp, 16 724; RV32I-NEXT: ret 725; 726; RV64I-LABEL: fnmadd_s_3: 727; RV64I: # %bb.0: 728; RV64I-NEXT: addi sp, sp, -16 729; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 730; RV64I-NEXT: call fmaf 731; RV64I-NEXT: lui a1, 524288 732; RV64I-NEXT: xor a0, a0, a1 733; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 734; RV64I-NEXT: addi sp, sp, 16 735; RV64I-NEXT: ret 736 %1 = call float @llvm.fma.f32(float %a, float %b, float %c) 737 %neg = fneg float %1 738 ret float %neg 739} 740 741define float @fnmadd_nsz(float %a, float %b, float %c) nounwind { 742; RV32IF-LABEL: fnmadd_nsz: 743; RV32IF: # %bb.0: 744; RV32IF-NEXT: fnmadd.s fa0, fa0, fa1, fa2 745; RV32IF-NEXT: ret 746; 747; RV64IF-LABEL: fnmadd_nsz: 748; RV64IF: # %bb.0: 749; RV64IF-NEXT: fnmadd.s fa0, fa0, fa1, fa2 750; RV64IF-NEXT: ret 751; 752; CHECKIF-LABEL: fnmadd_nsz: 753; CHECKIF: # %bb.0: 754; CHECKIF-NEXT: fnmadd.s fa0, fa0, fa1, fa2 755; CHECKIF-NEXT: ret 756; 757; CHECKIZFINX-LABEL: fnmadd_nsz: 758; CHECKIZFINX: # %bb.0: 759; CHECKIZFINX-NEXT: fnmadd.s a0, a0, a1, a2 760; CHECKIZFINX-NEXT: ret 761; 762; RV32I-LABEL: fnmadd_nsz: 763; RV32I: # %bb.0: 764; RV32I-NEXT: addi sp, sp, -16 765; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 766; RV32I-NEXT: call fmaf 767; RV32I-NEXT: lui a1, 524288 768; RV32I-NEXT: xor a0, a0, a1 769; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 770; RV32I-NEXT: addi sp, sp, 16 771; RV32I-NEXT: ret 772; 773; RV64I-LABEL: fnmadd_nsz: 774; RV64I: # %bb.0: 775; RV64I-NEXT: addi sp, sp, -16 776; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 777; RV64I-NEXT: call fmaf 778; RV64I-NEXT: lui a1, 524288 779; RV64I-NEXT: xor a0, a0, a1 780; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 781; RV64I-NEXT: addi sp, sp, 16 782; RV64I-NEXT: ret 783 %1 = call nsz float @llvm.fma.f32(float %a, float %b, float %c) 784 %neg = fneg nsz float %1 785 ret float %neg 786} 787 788define float @fnmsub_s(float %a, float %b, float %c) nounwind { 789; CHECKIF-LABEL: fnmsub_s: 790; CHECKIF: # %bb.0: 791; CHECKIF-NEXT: fmv.w.x fa5, zero 792; CHECKIF-NEXT: fadd.s fa5, fa0, fa5 793; CHECKIF-NEXT: fnmsub.s fa0, fa5, fa1, fa2 794; CHECKIF-NEXT: ret 795; 796; CHECKIZFINX-LABEL: fnmsub_s: 797; CHECKIZFINX: # %bb.0: 798; CHECKIZFINX-NEXT: fadd.s a0, a0, zero 799; CHECKIZFINX-NEXT: fnmsub.s a0, a0, a1, a2 800; CHECKIZFINX-NEXT: ret 801; 802; RV32I-LABEL: fnmsub_s: 803; RV32I: # %bb.0: 804; RV32I-NEXT: addi sp, sp, -16 805; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 806; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 807; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 808; RV32I-NEXT: mv s0, a2 809; RV32I-NEXT: mv s1, a1 810; RV32I-NEXT: li a1, 0 811; RV32I-NEXT: call __addsf3 812; RV32I-NEXT: lui a1, 524288 813; RV32I-NEXT: xor a0, a0, a1 814; RV32I-NEXT: mv a1, s1 815; RV32I-NEXT: mv a2, s0 816; RV32I-NEXT: call fmaf 817; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 818; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 819; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 820; RV32I-NEXT: addi sp, sp, 16 821; RV32I-NEXT: ret 822; 823; RV64I-LABEL: fnmsub_s: 824; RV64I: # %bb.0: 825; RV64I-NEXT: addi sp, sp, -32 826; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 827; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 828; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 829; RV64I-NEXT: mv s0, a2 830; RV64I-NEXT: mv s1, a1 831; RV64I-NEXT: li a1, 0 832; RV64I-NEXT: call __addsf3 833; RV64I-NEXT: lui a1, 524288 834; RV64I-NEXT: xor a0, a0, a1 835; RV64I-NEXT: mv a1, s1 836; RV64I-NEXT: mv a2, s0 837; RV64I-NEXT: call fmaf 838; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 839; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 840; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 841; RV64I-NEXT: addi sp, sp, 32 842; RV64I-NEXT: ret 843 %a_ = fadd float 0.0, %a 844 %nega = fsub float -0.0, %a_ 845 %1 = call float @llvm.fma.f32(float %nega, float %b, float %c) 846 ret float %1 847} 848 849define float @fnmsub_s_2(float %a, float %b, float %c) nounwind { 850; CHECKIF-LABEL: fnmsub_s_2: 851; CHECKIF: # %bb.0: 852; CHECKIF-NEXT: fmv.w.x fa5, zero 853; CHECKIF-NEXT: fadd.s fa5, fa1, fa5 854; CHECKIF-NEXT: fnmsub.s fa0, fa5, fa0, fa2 855; CHECKIF-NEXT: ret 856; 857; CHECKIZFINX-LABEL: fnmsub_s_2: 858; CHECKIZFINX: # %bb.0: 859; CHECKIZFINX-NEXT: fadd.s a1, a1, zero 860; CHECKIZFINX-NEXT: fnmsub.s a0, a1, a0, a2 861; CHECKIZFINX-NEXT: ret 862; 863; RV32I-LABEL: fnmsub_s_2: 864; RV32I: # %bb.0: 865; RV32I-NEXT: addi sp, sp, -16 866; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 867; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 868; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 869; RV32I-NEXT: mv s0, a2 870; RV32I-NEXT: mv s1, a0 871; RV32I-NEXT: mv a0, a1 872; RV32I-NEXT: li a1, 0 873; RV32I-NEXT: call __addsf3 874; RV32I-NEXT: lui a1, 524288 875; RV32I-NEXT: xor a1, a0, a1 876; RV32I-NEXT: mv a0, s1 877; RV32I-NEXT: mv a2, s0 878; RV32I-NEXT: call fmaf 879; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 880; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 881; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 882; RV32I-NEXT: addi sp, sp, 16 883; RV32I-NEXT: ret 884; 885; RV64I-LABEL: fnmsub_s_2: 886; RV64I: # %bb.0: 887; RV64I-NEXT: addi sp, sp, -32 888; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 889; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 890; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 891; RV64I-NEXT: mv s0, a2 892; RV64I-NEXT: mv s1, a0 893; RV64I-NEXT: mv a0, a1 894; RV64I-NEXT: li a1, 0 895; RV64I-NEXT: call __addsf3 896; RV64I-NEXT: lui a1, 524288 897; RV64I-NEXT: xor a1, a0, a1 898; RV64I-NEXT: mv a0, s1 899; RV64I-NEXT: mv a2, s0 900; RV64I-NEXT: call fmaf 901; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 902; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 903; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 904; RV64I-NEXT: addi sp, sp, 32 905; RV64I-NEXT: ret 906 %b_ = fadd float 0.0, %b 907 %negb = fsub float -0.0, %b_ 908 %1 = call float @llvm.fma.f32(float %a, float %negb, float %c) 909 ret float %1 910} 911 912define float @fmadd_s_contract(float %a, float %b, float %c) nounwind { 913; CHECKIF-LABEL: fmadd_s_contract: 914; CHECKIF: # %bb.0: 915; CHECKIF-NEXT: fmadd.s fa0, fa0, fa1, fa2 916; CHECKIF-NEXT: ret 917; 918; CHECKIZFINX-LABEL: fmadd_s_contract: 919; CHECKIZFINX: # %bb.0: 920; CHECKIZFINX-NEXT: fmadd.s a0, a0, a1, a2 921; CHECKIZFINX-NEXT: ret 922; 923; RV32I-LABEL: fmadd_s_contract: 924; RV32I: # %bb.0: 925; RV32I-NEXT: addi sp, sp, -16 926; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 927; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 928; RV32I-NEXT: mv s0, a2 929; RV32I-NEXT: call __mulsf3 930; RV32I-NEXT: mv a1, s0 931; RV32I-NEXT: call __addsf3 932; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 933; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 934; RV32I-NEXT: addi sp, sp, 16 935; RV32I-NEXT: ret 936; 937; RV64I-LABEL: fmadd_s_contract: 938; RV64I: # %bb.0: 939; RV64I-NEXT: addi sp, sp, -16 940; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 941; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill 942; RV64I-NEXT: mv s0, a2 943; RV64I-NEXT: call __mulsf3 944; RV64I-NEXT: mv a1, s0 945; RV64I-NEXT: call __addsf3 946; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 947; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload 948; RV64I-NEXT: addi sp, sp, 16 949; RV64I-NEXT: ret 950 %1 = fmul contract float %a, %b 951 %2 = fadd contract float %1, %c 952 ret float %2 953} 954 955define float @fmsub_s_contract(float %a, float %b, float %c) nounwind { 956; CHECKIF-LABEL: fmsub_s_contract: 957; CHECKIF: # %bb.0: 958; CHECKIF-NEXT: fmv.w.x fa5, zero 959; CHECKIF-NEXT: fadd.s fa5, fa2, fa5 960; CHECKIF-NEXT: fmsub.s fa0, fa0, fa1, fa5 961; CHECKIF-NEXT: ret 962; 963; CHECKIZFINX-LABEL: fmsub_s_contract: 964; CHECKIZFINX: # %bb.0: 965; CHECKIZFINX-NEXT: fadd.s a2, a2, zero 966; CHECKIZFINX-NEXT: fmsub.s a0, a0, a1, a2 967; CHECKIZFINX-NEXT: ret 968; 969; RV32I-LABEL: fmsub_s_contract: 970; RV32I: # %bb.0: 971; RV32I-NEXT: addi sp, sp, -16 972; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 973; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 974; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 975; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 976; RV32I-NEXT: mv s0, a1 977; RV32I-NEXT: mv s1, a0 978; RV32I-NEXT: mv a0, a2 979; RV32I-NEXT: li a1, 0 980; RV32I-NEXT: call __addsf3 981; RV32I-NEXT: mv s2, a0 982; RV32I-NEXT: mv a0, s1 983; RV32I-NEXT: mv a1, s0 984; RV32I-NEXT: call __mulsf3 985; RV32I-NEXT: mv a1, s2 986; RV32I-NEXT: call __subsf3 987; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 988; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 989; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 990; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 991; RV32I-NEXT: addi sp, sp, 16 992; RV32I-NEXT: ret 993; 994; RV64I-LABEL: fmsub_s_contract: 995; RV64I: # %bb.0: 996; RV64I-NEXT: addi sp, sp, -32 997; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 998; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 999; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 1000; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 1001; RV64I-NEXT: mv s0, a1 1002; RV64I-NEXT: mv s1, a0 1003; RV64I-NEXT: mv a0, a2 1004; RV64I-NEXT: li a1, 0 1005; RV64I-NEXT: call __addsf3 1006; RV64I-NEXT: mv s2, a0 1007; RV64I-NEXT: mv a0, s1 1008; RV64I-NEXT: mv a1, s0 1009; RV64I-NEXT: call __mulsf3 1010; RV64I-NEXT: mv a1, s2 1011; RV64I-NEXT: call __subsf3 1012; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 1013; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 1014; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 1015; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 1016; RV64I-NEXT: addi sp, sp, 32 1017; RV64I-NEXT: ret 1018 %c_ = fadd float 0.0, %c ; avoid negation using xor 1019 %1 = fmul contract float %a, %b 1020 %2 = fsub contract float %1, %c_ 1021 ret float %2 1022} 1023 1024define float @fnmadd_s_contract(float %a, float %b, float %c) nounwind { 1025; CHECKIF-LABEL: fnmadd_s_contract: 1026; CHECKIF: # %bb.0: 1027; CHECKIF-NEXT: fmv.w.x fa5, zero 1028; CHECKIF-NEXT: fadd.s fa4, fa0, fa5 1029; CHECKIF-NEXT: fadd.s fa3, fa1, fa5 1030; CHECKIF-NEXT: fadd.s fa5, fa2, fa5 1031; CHECKIF-NEXT: fnmadd.s fa0, fa4, fa3, fa5 1032; CHECKIF-NEXT: ret 1033; 1034; CHECKIZFINX-LABEL: fnmadd_s_contract: 1035; CHECKIZFINX: # %bb.0: 1036; CHECKIZFINX-NEXT: fadd.s a0, a0, zero 1037; CHECKIZFINX-NEXT: fadd.s a1, a1, zero 1038; CHECKIZFINX-NEXT: fadd.s a2, a2, zero 1039; CHECKIZFINX-NEXT: fnmadd.s a0, a0, a1, a2 1040; CHECKIZFINX-NEXT: ret 1041; 1042; RV32I-LABEL: fnmadd_s_contract: 1043; RV32I: # %bb.0: 1044; RV32I-NEXT: addi sp, sp, -16 1045; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 1046; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 1047; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 1048; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 1049; RV32I-NEXT: mv s0, a2 1050; RV32I-NEXT: mv s1, a1 1051; RV32I-NEXT: li a1, 0 1052; RV32I-NEXT: call __addsf3 1053; RV32I-NEXT: mv s2, a0 1054; RV32I-NEXT: mv a0, s1 1055; RV32I-NEXT: li a1, 0 1056; RV32I-NEXT: call __addsf3 1057; RV32I-NEXT: mv s1, a0 1058; RV32I-NEXT: mv a0, s0 1059; RV32I-NEXT: li a1, 0 1060; RV32I-NEXT: call __addsf3 1061; RV32I-NEXT: mv s0, a0 1062; RV32I-NEXT: mv a0, s2 1063; RV32I-NEXT: mv a1, s1 1064; RV32I-NEXT: call __mulsf3 1065; RV32I-NEXT: lui a1, 524288 1066; RV32I-NEXT: xor a0, a0, a1 1067; RV32I-NEXT: mv a1, s0 1068; RV32I-NEXT: call __subsf3 1069; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 1070; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 1071; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 1072; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 1073; RV32I-NEXT: addi sp, sp, 16 1074; RV32I-NEXT: ret 1075; 1076; RV64I-LABEL: fnmadd_s_contract: 1077; RV64I: # %bb.0: 1078; RV64I-NEXT: addi sp, sp, -32 1079; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 1080; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 1081; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 1082; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 1083; RV64I-NEXT: mv s0, a2 1084; RV64I-NEXT: mv s1, a1 1085; RV64I-NEXT: li a1, 0 1086; RV64I-NEXT: call __addsf3 1087; RV64I-NEXT: mv s2, a0 1088; RV64I-NEXT: mv a0, s1 1089; RV64I-NEXT: li a1, 0 1090; RV64I-NEXT: call __addsf3 1091; RV64I-NEXT: mv s1, a0 1092; RV64I-NEXT: mv a0, s0 1093; RV64I-NEXT: li a1, 0 1094; RV64I-NEXT: call __addsf3 1095; RV64I-NEXT: mv s0, a0 1096; RV64I-NEXT: mv a0, s2 1097; RV64I-NEXT: mv a1, s1 1098; RV64I-NEXT: call __mulsf3 1099; RV64I-NEXT: lui a1, 524288 1100; RV64I-NEXT: xor a0, a0, a1 1101; RV64I-NEXT: mv a1, s0 1102; RV64I-NEXT: call __subsf3 1103; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 1104; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 1105; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 1106; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 1107; RV64I-NEXT: addi sp, sp, 32 1108; RV64I-NEXT: ret 1109 %a_ = fadd float 0.0, %a ; avoid negation using xor 1110 %b_ = fadd float 0.0, %b ; avoid negation using xor 1111 %c_ = fadd float 0.0, %c ; avoid negation using xor 1112 %1 = fmul contract float %a_, %b_ 1113 %2 = fneg float %1 1114 %3 = fsub contract float %2, %c_ 1115 ret float %3 1116} 1117 1118define float @fnmsub_s_contract(float %a, float %b, float %c) nounwind { 1119; CHECKIF-LABEL: fnmsub_s_contract: 1120; CHECKIF: # %bb.0: 1121; CHECKIF-NEXT: fmv.w.x fa5, zero 1122; CHECKIF-NEXT: fadd.s fa4, fa0, fa5 1123; CHECKIF-NEXT: fadd.s fa5, fa1, fa5 1124; CHECKIF-NEXT: fnmsub.s fa0, fa4, fa5, fa2 1125; CHECKIF-NEXT: ret 1126; 1127; CHECKIZFINX-LABEL: fnmsub_s_contract: 1128; CHECKIZFINX: # %bb.0: 1129; CHECKIZFINX-NEXT: fadd.s a0, a0, zero 1130; CHECKIZFINX-NEXT: fadd.s a1, a1, zero 1131; CHECKIZFINX-NEXT: fnmsub.s a0, a0, a1, a2 1132; CHECKIZFINX-NEXT: ret 1133; 1134; RV32I-LABEL: fnmsub_s_contract: 1135; RV32I: # %bb.0: 1136; RV32I-NEXT: addi sp, sp, -16 1137; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 1138; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 1139; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 1140; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 1141; RV32I-NEXT: mv s0, a2 1142; RV32I-NEXT: mv s1, a1 1143; RV32I-NEXT: li a1, 0 1144; RV32I-NEXT: call __addsf3 1145; RV32I-NEXT: mv s2, a0 1146; RV32I-NEXT: mv a0, s1 1147; RV32I-NEXT: li a1, 0 1148; RV32I-NEXT: call __addsf3 1149; RV32I-NEXT: mv a1, a0 1150; RV32I-NEXT: mv a0, s2 1151; RV32I-NEXT: call __mulsf3 1152; RV32I-NEXT: mv a1, a0 1153; RV32I-NEXT: mv a0, s0 1154; RV32I-NEXT: call __subsf3 1155; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 1156; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 1157; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 1158; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 1159; RV32I-NEXT: addi sp, sp, 16 1160; RV32I-NEXT: ret 1161; 1162; RV64I-LABEL: fnmsub_s_contract: 1163; RV64I: # %bb.0: 1164; RV64I-NEXT: addi sp, sp, -32 1165; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 1166; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 1167; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 1168; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 1169; RV64I-NEXT: mv s0, a2 1170; RV64I-NEXT: mv s1, a1 1171; RV64I-NEXT: li a1, 0 1172; RV64I-NEXT: call __addsf3 1173; RV64I-NEXT: mv s2, a0 1174; RV64I-NEXT: mv a0, s1 1175; RV64I-NEXT: li a1, 0 1176; RV64I-NEXT: call __addsf3 1177; RV64I-NEXT: mv a1, a0 1178; RV64I-NEXT: mv a0, s2 1179; RV64I-NEXT: call __mulsf3 1180; RV64I-NEXT: mv a1, a0 1181; RV64I-NEXT: mv a0, s0 1182; RV64I-NEXT: call __subsf3 1183; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 1184; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 1185; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 1186; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 1187; RV64I-NEXT: addi sp, sp, 32 1188; RV64I-NEXT: ret 1189 %a_ = fadd float 0.0, %a ; avoid negation using xor 1190 %b_ = fadd float 0.0, %b ; avoid negation using xor 1191 %1 = fmul contract float %a_, %b_ 1192 %2 = fsub contract float %c, %1 1193 ret float %2 1194} 1195 1196define float @fsgnjx_f32(float %x, float %y) nounwind { 1197; CHECKIF-LABEL: fsgnjx_f32: 1198; CHECKIF: # %bb.0: 1199; CHECKIF-NEXT: fsgnjx.s fa0, fa1, fa0 1200; CHECKIF-NEXT: ret 1201; 1202; CHECKIZFINX-LABEL: fsgnjx_f32: 1203; CHECKIZFINX: # %bb.0: 1204; CHECKIZFINX-NEXT: fsgnjx.s a0, a1, a0 1205; CHECKIZFINX-NEXT: ret 1206; 1207; RV32I-LABEL: fsgnjx_f32: 1208; RV32I: # %bb.0: 1209; RV32I-NEXT: addi sp, sp, -16 1210; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 1211; RV32I-NEXT: lui a2, 524288 1212; RV32I-NEXT: and a0, a0, a2 1213; RV32I-NEXT: lui a2, 260096 1214; RV32I-NEXT: or a0, a0, a2 1215; RV32I-NEXT: call __mulsf3 1216; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 1217; RV32I-NEXT: addi sp, sp, 16 1218; RV32I-NEXT: ret 1219; 1220; RV64I-LABEL: fsgnjx_f32: 1221; RV64I: # %bb.0: 1222; RV64I-NEXT: addi sp, sp, -16 1223; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 1224; RV64I-NEXT: lui a2, 524288 1225; RV64I-NEXT: and a0, a0, a2 1226; RV64I-NEXT: lui a2, 260096 1227; RV64I-NEXT: or a0, a0, a2 1228; RV64I-NEXT: call __mulsf3 1229; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 1230; RV64I-NEXT: addi sp, sp, 16 1231; RV64I-NEXT: ret 1232 %z = call float @llvm.copysign.f32(float 1.0, float %x) 1233 %mul = fmul float %z, %y 1234 ret float %mul 1235} 1236;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: 1237; RV32IZFINX: {{.*}} 1238; RV64IZFINX: {{.*}} 1239