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