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: -disable-strictnode-mutation -target-abi=ilp32f \ 4; RUN: | FileCheck -check-prefix=RV32IF %s 5; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs < %s \ 6; RUN: -disable-strictnode-mutation -target-abi=lp64f \ 7; RUN: | FileCheck -check-prefix=RV64IF %s 8; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ 9; RUN: -disable-strictnode-mutation | FileCheck -check-prefix=RV32I %s 10; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ 11; RUN: -disable-strictnode-mutation | FileCheck -check-prefix=RV64I %s 12 13define float @fadd_s(float %a, float %b) nounwind strictfp { 14; RV32IF-LABEL: fadd_s: 15; RV32IF: # %bb.0: 16; RV32IF-NEXT: fadd.s fa0, fa0, fa1 17; RV32IF-NEXT: ret 18; 19; RV64IF-LABEL: fadd_s: 20; RV64IF: # %bb.0: 21; RV64IF-NEXT: fadd.s fa0, fa0, fa1 22; RV64IF-NEXT: ret 23; 24; RV32I-LABEL: fadd_s: 25; RV32I: # %bb.0: 26; RV32I-NEXT: addi sp, sp, -16 27; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 28; RV32I-NEXT: call __addsf3@plt 29; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 30; RV32I-NEXT: addi sp, sp, 16 31; RV32I-NEXT: ret 32; 33; RV64I-LABEL: fadd_s: 34; RV64I: # %bb.0: 35; RV64I-NEXT: addi sp, sp, -16 36; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 37; RV64I-NEXT: call __addsf3@plt 38; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 39; RV64I-NEXT: addi sp, sp, 16 40; RV64I-NEXT: ret 41 %1 = call float @llvm.experimental.constrained.fadd.f32(float %a, float %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 42 ret float %1 43} 44declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata) 45 46define float @fsub_s(float %a, float %b) nounwind strictfp { 47; RV32IF-LABEL: fsub_s: 48; RV32IF: # %bb.0: 49; RV32IF-NEXT: fsub.s fa0, fa0, fa1 50; RV32IF-NEXT: ret 51; 52; RV64IF-LABEL: fsub_s: 53; RV64IF: # %bb.0: 54; RV64IF-NEXT: fsub.s fa0, fa0, fa1 55; RV64IF-NEXT: ret 56; 57; RV32I-LABEL: fsub_s: 58; RV32I: # %bb.0: 59; RV32I-NEXT: addi sp, sp, -16 60; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 61; RV32I-NEXT: call __subsf3@plt 62; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 63; RV32I-NEXT: addi sp, sp, 16 64; RV32I-NEXT: ret 65; 66; RV64I-LABEL: fsub_s: 67; RV64I: # %bb.0: 68; RV64I-NEXT: addi sp, sp, -16 69; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 70; RV64I-NEXT: call __subsf3@plt 71; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 72; RV64I-NEXT: addi sp, sp, 16 73; RV64I-NEXT: ret 74 %1 = call float @llvm.experimental.constrained.fsub.f32(float %a, float %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 75 ret float %1 76} 77declare float @llvm.experimental.constrained.fsub.f32(float, float, metadata, metadata) 78 79define float @fmul_s(float %a, float %b) nounwind strictfp { 80; RV32IF-LABEL: fmul_s: 81; RV32IF: # %bb.0: 82; RV32IF-NEXT: fmul.s fa0, fa0, fa1 83; RV32IF-NEXT: ret 84; 85; RV64IF-LABEL: fmul_s: 86; RV64IF: # %bb.0: 87; RV64IF-NEXT: fmul.s fa0, fa0, fa1 88; RV64IF-NEXT: ret 89; 90; RV32I-LABEL: fmul_s: 91; RV32I: # %bb.0: 92; RV32I-NEXT: addi sp, sp, -16 93; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 94; RV32I-NEXT: call __mulsf3@plt 95; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 96; RV32I-NEXT: addi sp, sp, 16 97; RV32I-NEXT: ret 98; 99; RV64I-LABEL: fmul_s: 100; RV64I: # %bb.0: 101; RV64I-NEXT: addi sp, sp, -16 102; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 103; RV64I-NEXT: call __mulsf3@plt 104; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 105; RV64I-NEXT: addi sp, sp, 16 106; RV64I-NEXT: ret 107 %1 = call float @llvm.experimental.constrained.fmul.f32(float %a, float %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 108 ret float %1 109} 110declare float @llvm.experimental.constrained.fmul.f32(float, float, metadata, metadata) 111 112define float @fdiv_s(float %a, float %b) nounwind strictfp { 113; RV32IF-LABEL: fdiv_s: 114; RV32IF: # %bb.0: 115; RV32IF-NEXT: fdiv.s fa0, fa0, fa1 116; RV32IF-NEXT: ret 117; 118; RV64IF-LABEL: fdiv_s: 119; RV64IF: # %bb.0: 120; RV64IF-NEXT: fdiv.s fa0, fa0, fa1 121; RV64IF-NEXT: ret 122; 123; RV32I-LABEL: fdiv_s: 124; RV32I: # %bb.0: 125; RV32I-NEXT: addi sp, sp, -16 126; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 127; RV32I-NEXT: call __divsf3@plt 128; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 129; RV32I-NEXT: addi sp, sp, 16 130; RV32I-NEXT: ret 131; 132; RV64I-LABEL: fdiv_s: 133; RV64I: # %bb.0: 134; RV64I-NEXT: addi sp, sp, -16 135; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 136; RV64I-NEXT: call __divsf3@plt 137; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 138; RV64I-NEXT: addi sp, sp, 16 139; RV64I-NEXT: ret 140 %1 = call float @llvm.experimental.constrained.fdiv.f32(float %a, float %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 141 ret float %1 142} 143declare float @llvm.experimental.constrained.fdiv.f32(float, float, metadata, metadata) 144 145define float @fsqrt_s(float %a) nounwind strictfp { 146; RV32IF-LABEL: fsqrt_s: 147; RV32IF: # %bb.0: 148; RV32IF-NEXT: fsqrt.s fa0, fa0 149; RV32IF-NEXT: ret 150; 151; RV64IF-LABEL: fsqrt_s: 152; RV64IF: # %bb.0: 153; RV64IF-NEXT: fsqrt.s fa0, fa0 154; RV64IF-NEXT: ret 155; 156; RV32I-LABEL: fsqrt_s: 157; RV32I: # %bb.0: 158; RV32I-NEXT: addi sp, sp, -16 159; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 160; RV32I-NEXT: call sqrtf@plt 161; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 162; RV32I-NEXT: addi sp, sp, 16 163; RV32I-NEXT: ret 164; 165; RV64I-LABEL: fsqrt_s: 166; RV64I: # %bb.0: 167; RV64I-NEXT: addi sp, sp, -16 168; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 169; RV64I-NEXT: call sqrtf@plt 170; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 171; RV64I-NEXT: addi sp, sp, 16 172; RV64I-NEXT: ret 173 %1 = call float @llvm.experimental.constrained.sqrt.f32(float %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 174 ret float %1 175} 176declare float @llvm.experimental.constrained.sqrt.f32(float, metadata, metadata) 177 178define float @fmin_s(float %a, float %b) nounwind strictfp { 179; RV32IF-LABEL: fmin_s: 180; RV32IF: # %bb.0: 181; RV32IF-NEXT: addi sp, sp, -16 182; RV32IF-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 183; RV32IF-NEXT: call fminf@plt 184; RV32IF-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 185; RV32IF-NEXT: addi sp, sp, 16 186; RV32IF-NEXT: ret 187; 188; RV64IF-LABEL: fmin_s: 189; RV64IF: # %bb.0: 190; RV64IF-NEXT: addi sp, sp, -16 191; RV64IF-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 192; RV64IF-NEXT: call fminf@plt 193; RV64IF-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 194; RV64IF-NEXT: addi sp, sp, 16 195; RV64IF-NEXT: ret 196; 197; RV32I-LABEL: fmin_s: 198; RV32I: # %bb.0: 199; RV32I-NEXT: addi sp, sp, -16 200; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 201; RV32I-NEXT: call fminf@plt 202; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 203; RV32I-NEXT: addi sp, sp, 16 204; RV32I-NEXT: ret 205; 206; RV64I-LABEL: fmin_s: 207; RV64I: # %bb.0: 208; RV64I-NEXT: addi sp, sp, -16 209; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 210; RV64I-NEXT: call fminf@plt 211; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 212; RV64I-NEXT: addi sp, sp, 16 213; RV64I-NEXT: ret 214 %1 = call float @llvm.experimental.constrained.minnum.f32(float %a, float %b, metadata !"fpexcept.strict") strictfp 215 ret float %1 216} 217declare float @llvm.experimental.constrained.minnum.f32(float, float, metadata) strictfp 218 219define float @fmax_s(float %a, float %b) nounwind strictfp { 220; RV32IF-LABEL: fmax_s: 221; RV32IF: # %bb.0: 222; RV32IF-NEXT: addi sp, sp, -16 223; RV32IF-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 224; RV32IF-NEXT: call fmaxf@plt 225; RV32IF-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 226; RV32IF-NEXT: addi sp, sp, 16 227; RV32IF-NEXT: ret 228; 229; RV64IF-LABEL: fmax_s: 230; RV64IF: # %bb.0: 231; RV64IF-NEXT: addi sp, sp, -16 232; RV64IF-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 233; RV64IF-NEXT: call fmaxf@plt 234; RV64IF-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 235; RV64IF-NEXT: addi sp, sp, 16 236; RV64IF-NEXT: ret 237; 238; RV32I-LABEL: fmax_s: 239; RV32I: # %bb.0: 240; RV32I-NEXT: addi sp, sp, -16 241; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 242; RV32I-NEXT: call fmaxf@plt 243; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 244; RV32I-NEXT: addi sp, sp, 16 245; RV32I-NEXT: ret 246; 247; RV64I-LABEL: fmax_s: 248; RV64I: # %bb.0: 249; RV64I-NEXT: addi sp, sp, -16 250; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 251; RV64I-NEXT: call fmaxf@plt 252; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 253; RV64I-NEXT: addi sp, sp, 16 254; RV64I-NEXT: ret 255 %1 = call float @llvm.experimental.constrained.maxnum.f32(float %a, float %b, metadata !"fpexcept.strict") strictfp 256 ret float %1 257} 258declare float @llvm.experimental.constrained.maxnum.f32(float, float, metadata) strictfp 259 260define float @fmadd_s(float %a, float %b, float %c) nounwind strictfp { 261; RV32IF-LABEL: fmadd_s: 262; RV32IF: # %bb.0: 263; RV32IF-NEXT: fmadd.s fa0, fa0, fa1, fa2 264; RV32IF-NEXT: ret 265; 266; RV64IF-LABEL: fmadd_s: 267; RV64IF: # %bb.0: 268; RV64IF-NEXT: fmadd.s fa0, fa0, fa1, fa2 269; RV64IF-NEXT: ret 270; 271; RV32I-LABEL: fmadd_s: 272; RV32I: # %bb.0: 273; RV32I-NEXT: addi sp, sp, -16 274; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 275; RV32I-NEXT: call fmaf@plt 276; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 277; RV32I-NEXT: addi sp, sp, 16 278; RV32I-NEXT: ret 279; 280; RV64I-LABEL: fmadd_s: 281; RV64I: # %bb.0: 282; RV64I-NEXT: addi sp, sp, -16 283; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 284; RV64I-NEXT: call fmaf@plt 285; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 286; RV64I-NEXT: addi sp, sp, 16 287; RV64I-NEXT: ret 288 %1 = call float @llvm.experimental.constrained.fma.f32(float %a, float %b, float %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 289 ret float %1 290} 291declare float @llvm.experimental.constrained.fma.f32(float, float, float, metadata, metadata) strictfp 292 293define float @fmsub_s(float %a, float %b, float %c) nounwind strictfp { 294; RV32IF-LABEL: fmsub_s: 295; RV32IF: # %bb.0: 296; RV32IF-NEXT: fmv.w.x ft0, zero 297; RV32IF-NEXT: fadd.s ft0, fa2, ft0 298; RV32IF-NEXT: fmsub.s fa0, fa0, fa1, ft0 299; RV32IF-NEXT: ret 300; 301; RV64IF-LABEL: fmsub_s: 302; RV64IF: # %bb.0: 303; RV64IF-NEXT: fmv.w.x ft0, zero 304; RV64IF-NEXT: fadd.s ft0, fa2, ft0 305; RV64IF-NEXT: fmsub.s fa0, fa0, fa1, ft0 306; RV64IF-NEXT: ret 307; 308; RV32I-LABEL: fmsub_s: 309; RV32I: # %bb.0: 310; RV32I-NEXT: addi sp, sp, -16 311; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 312; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 313; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 314; RV32I-NEXT: mv s0, a1 315; RV32I-NEXT: mv s1, a0 316; RV32I-NEXT: mv a0, a2 317; RV32I-NEXT: li a1, 0 318; RV32I-NEXT: call __addsf3@plt 319; RV32I-NEXT: lui a1, 524288 320; RV32I-NEXT: xor a2, a0, a1 321; RV32I-NEXT: mv a0, s1 322; RV32I-NEXT: mv a1, s0 323; RV32I-NEXT: call fmaf@plt 324; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 325; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 326; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 327; RV32I-NEXT: addi sp, sp, 16 328; RV32I-NEXT: ret 329; 330; RV64I-LABEL: fmsub_s: 331; RV64I: # %bb.0: 332; RV64I-NEXT: addi sp, sp, -32 333; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 334; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 335; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 336; RV64I-NEXT: mv s0, a1 337; RV64I-NEXT: mv s1, a0 338; RV64I-NEXT: mv a0, a2 339; RV64I-NEXT: li a1, 0 340; RV64I-NEXT: call __addsf3@plt 341; RV64I-NEXT: lui a1, 524288 342; RV64I-NEXT: xor a2, a0, a1 343; RV64I-NEXT: mv a0, s1 344; RV64I-NEXT: mv a1, s0 345; RV64I-NEXT: call fmaf@plt 346; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 347; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 348; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 349; RV64I-NEXT: addi sp, sp, 32 350; RV64I-NEXT: ret 351 %c_ = fadd float 0.0, %c ; avoid negation using xor 352 %negc = fneg float %c_ 353 %1 = call float @llvm.experimental.constrained.fma.f32(float %a, float %b, float %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 354 ret float %1 355} 356 357define float @fnmadd_s(float %a, float %b, float %c) nounwind strictfp { 358; RV32IF-LABEL: fnmadd_s: 359; RV32IF: # %bb.0: 360; RV32IF-NEXT: fmv.w.x ft0, zero 361; RV32IF-NEXT: fadd.s ft1, fa0, ft0 362; RV32IF-NEXT: fadd.s ft0, fa2, ft0 363; RV32IF-NEXT: fnmadd.s fa0, ft1, fa1, ft0 364; RV32IF-NEXT: ret 365; 366; RV64IF-LABEL: fnmadd_s: 367; RV64IF: # %bb.0: 368; RV64IF-NEXT: fmv.w.x ft0, zero 369; RV64IF-NEXT: fadd.s ft1, fa0, ft0 370; RV64IF-NEXT: fadd.s ft0, fa2, ft0 371; RV64IF-NEXT: fnmadd.s fa0, ft1, fa1, ft0 372; RV64IF-NEXT: ret 373; 374; RV32I-LABEL: fnmadd_s: 375; RV32I: # %bb.0: 376; RV32I-NEXT: addi sp, sp, -16 377; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 378; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 379; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 380; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 381; RV32I-NEXT: mv s0, a2 382; RV32I-NEXT: mv s2, a1 383; RV32I-NEXT: li a1, 0 384; RV32I-NEXT: call __addsf3@plt 385; RV32I-NEXT: mv s1, a0 386; RV32I-NEXT: mv a0, s0 387; RV32I-NEXT: li a1, 0 388; RV32I-NEXT: call __addsf3@plt 389; RV32I-NEXT: lui a2, 524288 390; RV32I-NEXT: xor a1, s1, a2 391; RV32I-NEXT: xor a2, a0, a2 392; RV32I-NEXT: mv a0, a1 393; RV32I-NEXT: mv a1, s2 394; RV32I-NEXT: call fmaf@plt 395; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 396; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 397; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 398; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 399; RV32I-NEXT: addi sp, sp, 16 400; RV32I-NEXT: ret 401; 402; RV64I-LABEL: fnmadd_s: 403; RV64I: # %bb.0: 404; RV64I-NEXT: addi sp, sp, -32 405; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 406; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 407; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 408; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 409; RV64I-NEXT: mv s0, a2 410; RV64I-NEXT: mv s2, a1 411; RV64I-NEXT: li a1, 0 412; RV64I-NEXT: call __addsf3@plt 413; RV64I-NEXT: mv s1, a0 414; RV64I-NEXT: mv a0, s0 415; RV64I-NEXT: li a1, 0 416; RV64I-NEXT: call __addsf3@plt 417; RV64I-NEXT: lui a2, 524288 418; RV64I-NEXT: xor a1, s1, a2 419; RV64I-NEXT: xor a2, a0, a2 420; RV64I-NEXT: mv a0, a1 421; RV64I-NEXT: mv a1, s2 422; RV64I-NEXT: call fmaf@plt 423; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 424; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 425; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 426; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 427; RV64I-NEXT: addi sp, sp, 32 428; RV64I-NEXT: ret 429 %a_ = fadd float 0.0, %a 430 %c_ = fadd float 0.0, %c 431 %nega = fneg float %a_ 432 %negc = fneg float %c_ 433 %1 = call float @llvm.experimental.constrained.fma.f32(float %nega, float %b, float %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 434 ret float %1 435} 436 437define float @fnmadd_s_2(float %a, float %b, float %c) nounwind strictfp { 438; RV32IF-LABEL: fnmadd_s_2: 439; RV32IF: # %bb.0: 440; RV32IF-NEXT: fmv.w.x ft0, zero 441; RV32IF-NEXT: fadd.s ft1, fa1, ft0 442; RV32IF-NEXT: fadd.s ft0, fa2, ft0 443; RV32IF-NEXT: fnmadd.s fa0, ft1, fa0, ft0 444; RV32IF-NEXT: ret 445; 446; RV64IF-LABEL: fnmadd_s_2: 447; RV64IF: # %bb.0: 448; RV64IF-NEXT: fmv.w.x ft0, zero 449; RV64IF-NEXT: fadd.s ft1, fa1, ft0 450; RV64IF-NEXT: fadd.s ft0, fa2, ft0 451; RV64IF-NEXT: fnmadd.s fa0, ft1, fa0, ft0 452; RV64IF-NEXT: ret 453; 454; RV32I-LABEL: fnmadd_s_2: 455; RV32I: # %bb.0: 456; RV32I-NEXT: addi sp, sp, -16 457; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 458; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 459; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 460; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 461; RV32I-NEXT: mv s0, a2 462; RV32I-NEXT: mv s2, a0 463; RV32I-NEXT: mv a0, a1 464; RV32I-NEXT: li a1, 0 465; RV32I-NEXT: call __addsf3@plt 466; RV32I-NEXT: mv s1, a0 467; RV32I-NEXT: mv a0, s0 468; RV32I-NEXT: li a1, 0 469; RV32I-NEXT: call __addsf3@plt 470; RV32I-NEXT: lui a2, 524288 471; RV32I-NEXT: xor a1, s1, a2 472; RV32I-NEXT: xor a2, a0, a2 473; RV32I-NEXT: mv a0, s2 474; RV32I-NEXT: call fmaf@plt 475; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 476; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 477; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 478; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 479; RV32I-NEXT: addi sp, sp, 16 480; RV32I-NEXT: ret 481; 482; RV64I-LABEL: fnmadd_s_2: 483; RV64I: # %bb.0: 484; RV64I-NEXT: addi sp, sp, -32 485; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 486; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 487; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 488; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 489; RV64I-NEXT: mv s0, a2 490; RV64I-NEXT: mv s2, a0 491; RV64I-NEXT: mv a0, a1 492; RV64I-NEXT: li a1, 0 493; RV64I-NEXT: call __addsf3@plt 494; RV64I-NEXT: mv s1, a0 495; RV64I-NEXT: mv a0, s0 496; RV64I-NEXT: li a1, 0 497; RV64I-NEXT: call __addsf3@plt 498; RV64I-NEXT: lui a2, 524288 499; RV64I-NEXT: xor a1, s1, a2 500; RV64I-NEXT: xor a2, a0, a2 501; RV64I-NEXT: mv a0, s2 502; RV64I-NEXT: call fmaf@plt 503; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 504; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 505; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 506; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 507; RV64I-NEXT: addi sp, sp, 32 508; RV64I-NEXT: ret 509 %b_ = fadd float 0.0, %b 510 %c_ = fadd float 0.0, %c 511 %negb = fneg float %b_ 512 %negc = fneg float %c_ 513 %1 = call float @llvm.experimental.constrained.fma.f32(float %a, float %negb, float %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 514 ret float %1 515} 516 517define float @fnmsub_s(float %a, float %b, float %c) nounwind strictfp { 518; RV32IF-LABEL: fnmsub_s: 519; RV32IF: # %bb.0: 520; RV32IF-NEXT: fmv.w.x ft0, zero 521; RV32IF-NEXT: fadd.s ft0, fa0, ft0 522; RV32IF-NEXT: fnmsub.s fa0, ft0, fa1, fa2 523; RV32IF-NEXT: ret 524; 525; RV64IF-LABEL: fnmsub_s: 526; RV64IF: # %bb.0: 527; RV64IF-NEXT: fmv.w.x ft0, zero 528; RV64IF-NEXT: fadd.s ft0, fa0, ft0 529; RV64IF-NEXT: fnmsub.s fa0, ft0, fa1, fa2 530; RV64IF-NEXT: ret 531; 532; RV32I-LABEL: fnmsub_s: 533; RV32I: # %bb.0: 534; RV32I-NEXT: addi sp, sp, -16 535; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 536; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 537; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 538; RV32I-NEXT: mv s0, a2 539; RV32I-NEXT: mv s1, a1 540; RV32I-NEXT: li a1, 0 541; RV32I-NEXT: call __addsf3@plt 542; RV32I-NEXT: lui a1, 524288 543; RV32I-NEXT: xor a0, a0, a1 544; RV32I-NEXT: mv a1, s1 545; RV32I-NEXT: mv a2, s0 546; RV32I-NEXT: call fmaf@plt 547; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 548; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 549; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 550; RV32I-NEXT: addi sp, sp, 16 551; RV32I-NEXT: ret 552; 553; RV64I-LABEL: fnmsub_s: 554; RV64I: # %bb.0: 555; RV64I-NEXT: addi sp, sp, -32 556; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 557; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 558; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 559; RV64I-NEXT: mv s0, a2 560; RV64I-NEXT: mv s1, a1 561; RV64I-NEXT: li a1, 0 562; RV64I-NEXT: call __addsf3@plt 563; RV64I-NEXT: lui a1, 524288 564; RV64I-NEXT: xor a0, a0, a1 565; RV64I-NEXT: mv a1, s1 566; RV64I-NEXT: mv a2, s0 567; RV64I-NEXT: call fmaf@plt 568; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 569; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 570; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 571; RV64I-NEXT: addi sp, sp, 32 572; RV64I-NEXT: ret 573 %a_ = fadd float 0.0, %a 574 %nega = fneg float %a_ 575 %1 = call float @llvm.experimental.constrained.fma.f32(float %nega, float %b, float %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 576 ret float %1 577} 578 579define float @fnmsub_s_2(float %a, float %b, float %c) nounwind strictfp { 580; RV32IF-LABEL: fnmsub_s_2: 581; RV32IF: # %bb.0: 582; RV32IF-NEXT: fmv.w.x ft0, zero 583; RV32IF-NEXT: fadd.s ft0, fa1, ft0 584; RV32IF-NEXT: fnmsub.s fa0, ft0, fa0, fa2 585; RV32IF-NEXT: ret 586; 587; RV64IF-LABEL: fnmsub_s_2: 588; RV64IF: # %bb.0: 589; RV64IF-NEXT: fmv.w.x ft0, zero 590; RV64IF-NEXT: fadd.s ft0, fa1, ft0 591; RV64IF-NEXT: fnmsub.s fa0, ft0, fa0, fa2 592; RV64IF-NEXT: ret 593; 594; RV32I-LABEL: fnmsub_s_2: 595; RV32I: # %bb.0: 596; RV32I-NEXT: addi sp, sp, -16 597; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 598; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 599; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 600; RV32I-NEXT: mv s0, a2 601; RV32I-NEXT: mv s1, a0 602; RV32I-NEXT: mv a0, a1 603; RV32I-NEXT: li a1, 0 604; RV32I-NEXT: call __addsf3@plt 605; RV32I-NEXT: lui a1, 524288 606; RV32I-NEXT: xor a1, a0, a1 607; RV32I-NEXT: mv a0, s1 608; RV32I-NEXT: mv a2, s0 609; RV32I-NEXT: call fmaf@plt 610; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 611; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 612; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 613; RV32I-NEXT: addi sp, sp, 16 614; RV32I-NEXT: ret 615; 616; RV64I-LABEL: fnmsub_s_2: 617; RV64I: # %bb.0: 618; RV64I-NEXT: addi sp, sp, -32 619; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 620; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 621; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 622; RV64I-NEXT: mv s0, a2 623; RV64I-NEXT: mv s1, a0 624; RV64I-NEXT: mv a0, a1 625; RV64I-NEXT: li a1, 0 626; RV64I-NEXT: call __addsf3@plt 627; RV64I-NEXT: lui a1, 524288 628; RV64I-NEXT: xor a1, a0, a1 629; RV64I-NEXT: mv a0, s1 630; RV64I-NEXT: mv a2, s0 631; RV64I-NEXT: call fmaf@plt 632; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 633; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 634; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 635; RV64I-NEXT: addi sp, sp, 32 636; RV64I-NEXT: ret 637 %b_ = fadd float 0.0, %b 638 %negb = fneg float %b_ 639 %1 = call float @llvm.experimental.constrained.fma.f32(float %a, float %negb, float %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp 640 ret float %1 641} 642