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