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 -verify-machineinstrs < %s \ 7; RUN: | FileCheck -check-prefix=RV32I %s 8; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ 9; RUN: | FileCheck -check-prefix=RV64I %s 10 11; These tests are each targeted at a particular RISC-V FPU instruction. 12; Compares and conversions can be found in 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@plt 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@plt 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@plt 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@plt 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@plt 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@plt 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@plt 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@plt 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@plt 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@plt 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: and a1, a1, a2 165; RV32I-NEXT: slli a0, a0, 1 166; RV32I-NEXT: srli a0, a0, 1 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: and a1, a1, a2 174; RV64I-NEXT: slli a0, a0, 33 175; RV64I-NEXT: srli a0, a0, 33 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 ft0, fa0, fa0 186; CHECKIF-NEXT: fneg.s ft1, ft0 187; CHECKIF-NEXT: feq.s a0, ft0, ft1 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@plt 196; RV32I-NEXT: lui a1, 524288 197; RV32I-NEXT: xor a1, a0, a1 198; RV32I-NEXT: call __eqsf2@plt 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@plt 210; RV64I-NEXT: lui a1, 524288 211; RV64I-NEXT: xor a1, a0, a1 212; RV64I-NEXT: call __eqsf2@plt 213; RV64I-NEXT: seqz a0, a0 214; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 215; RV64I-NEXT: addi sp, sp, 16 216; RV64I-NEXT: ret 217 %1 = fadd float %a, %a 218 %2 = fneg float %1 219 %3 = fcmp oeq float %1, %2 220 %4 = zext i1 %3 to i32 221 ret i32 %4 222} 223 224define float @fsgnjn_s(float %a, float %b) nounwind { 225; CHECKIF-LABEL: fsgnjn_s: 226; CHECKIF: # %bb.0: 227; CHECKIF-NEXT: fadd.s ft0, fa0, fa1 228; CHECKIF-NEXT: fsgnjn.s fa0, fa0, ft0 229; CHECKIF-NEXT: ret 230; 231; RV32I-LABEL: fsgnjn_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: sw s0, 8(sp) # 4-byte Folded Spill 236; RV32I-NEXT: mv s0, a0 237; RV32I-NEXT: call __addsf3@plt 238; RV32I-NEXT: not a0, a0 239; RV32I-NEXT: lui a1, 524288 240; RV32I-NEXT: and a0, a0, a1 241; RV32I-NEXT: slli a1, s0, 1 242; RV32I-NEXT: srli a1, a1, 1 243; RV32I-NEXT: or a0, a1, a0 244; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 245; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 246; RV32I-NEXT: addi sp, sp, 16 247; RV32I-NEXT: ret 248; 249; RV64I-LABEL: fsgnjn_s: 250; RV64I: # %bb.0: 251; RV64I-NEXT: addi sp, sp, -16 252; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 253; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill 254; RV64I-NEXT: mv s0, a0 255; RV64I-NEXT: call __addsf3@plt 256; RV64I-NEXT: not a0, a0 257; RV64I-NEXT: lui a1, 524288 258; RV64I-NEXT: and a0, a0, a1 259; RV64I-NEXT: slli a1, s0, 33 260; RV64I-NEXT: srli a1, a1, 33 261; RV64I-NEXT: or a0, a1, a0 262; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 263; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload 264; RV64I-NEXT: addi sp, sp, 16 265; RV64I-NEXT: ret 266 %1 = fadd float %a, %b 267 %2 = fneg float %1 268 %3 = call float @llvm.copysign.f32(float %a, float %2) 269 ret float %3 270} 271 272declare float @llvm.fabs.f32(float) 273 274define float @fabs_s(float %a, float %b) nounwind { 275; CHECKIF-LABEL: fabs_s: 276; CHECKIF: # %bb.0: 277; CHECKIF-NEXT: fadd.s ft0, fa0, fa1 278; CHECKIF-NEXT: fabs.s ft1, ft0 279; CHECKIF-NEXT: fadd.s fa0, ft1, ft0 280; CHECKIF-NEXT: ret 281; 282; RV32I-LABEL: fabs_s: 283; RV32I: # %bb.0: 284; RV32I-NEXT: addi sp, sp, -16 285; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 286; RV32I-NEXT: call __addsf3@plt 287; RV32I-NEXT: mv a1, a0 288; RV32I-NEXT: slli a0, a0, 1 289; RV32I-NEXT: srli a0, a0, 1 290; RV32I-NEXT: call __addsf3@plt 291; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 292; RV32I-NEXT: addi sp, sp, 16 293; RV32I-NEXT: ret 294; 295; RV64I-LABEL: fabs_s: 296; RV64I: # %bb.0: 297; RV64I-NEXT: addi sp, sp, -16 298; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 299; RV64I-NEXT: call __addsf3@plt 300; RV64I-NEXT: mv a1, a0 301; RV64I-NEXT: slli a0, a0, 33 302; RV64I-NEXT: srli a0, a0, 33 303; RV64I-NEXT: call __addsf3@plt 304; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 305; RV64I-NEXT: addi sp, sp, 16 306; RV64I-NEXT: ret 307 %1 = fadd float %a, %b 308 %2 = call float @llvm.fabs.f32(float %1) 309 %3 = fadd float %2, %1 310 ret float %3 311} 312 313declare float @llvm.minnum.f32(float, float) 314 315define float @fmin_s(float %a, float %b) nounwind { 316; CHECKIF-LABEL: fmin_s: 317; CHECKIF: # %bb.0: 318; CHECKIF-NEXT: fmin.s fa0, fa0, fa1 319; CHECKIF-NEXT: ret 320; 321; RV32I-LABEL: fmin_s: 322; RV32I: # %bb.0: 323; RV32I-NEXT: addi sp, sp, -16 324; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 325; RV32I-NEXT: call fminf@plt 326; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 327; RV32I-NEXT: addi sp, sp, 16 328; RV32I-NEXT: ret 329; 330; RV64I-LABEL: fmin_s: 331; RV64I: # %bb.0: 332; RV64I-NEXT: addi sp, sp, -16 333; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 334; RV64I-NEXT: call fminf@plt 335; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 336; RV64I-NEXT: addi sp, sp, 16 337; RV64I-NEXT: ret 338 %1 = call float @llvm.minnum.f32(float %a, float %b) 339 ret float %1 340} 341 342declare float @llvm.maxnum.f32(float, float) 343 344define float @fmax_s(float %a, float %b) nounwind { 345; CHECKIF-LABEL: fmax_s: 346; CHECKIF: # %bb.0: 347; CHECKIF-NEXT: fmax.s fa0, fa0, fa1 348; CHECKIF-NEXT: ret 349; 350; RV32I-LABEL: fmax_s: 351; RV32I: # %bb.0: 352; RV32I-NEXT: addi sp, sp, -16 353; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 354; RV32I-NEXT: call fmaxf@plt 355; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 356; RV32I-NEXT: addi sp, sp, 16 357; RV32I-NEXT: ret 358; 359; RV64I-LABEL: fmax_s: 360; RV64I: # %bb.0: 361; RV64I-NEXT: addi sp, sp, -16 362; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 363; RV64I-NEXT: call fmaxf@plt 364; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 365; RV64I-NEXT: addi sp, sp, 16 366; RV64I-NEXT: ret 367 %1 = call float @llvm.maxnum.f32(float %a, float %b) 368 ret float %1 369} 370 371declare float @llvm.fma.f32(float, float, float) 372 373define float @fmadd_s(float %a, float %b, float %c) nounwind { 374; CHECKIF-LABEL: fmadd_s: 375; CHECKIF: # %bb.0: 376; CHECKIF-NEXT: fmadd.s fa0, fa0, fa1, fa2 377; CHECKIF-NEXT: ret 378; 379; RV32I-LABEL: fmadd_s: 380; RV32I: # %bb.0: 381; RV32I-NEXT: addi sp, sp, -16 382; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 383; RV32I-NEXT: call fmaf@plt 384; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 385; RV32I-NEXT: addi sp, sp, 16 386; RV32I-NEXT: ret 387; 388; RV64I-LABEL: fmadd_s: 389; RV64I: # %bb.0: 390; RV64I-NEXT: addi sp, sp, -16 391; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 392; RV64I-NEXT: call fmaf@plt 393; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 394; RV64I-NEXT: addi sp, sp, 16 395; RV64I-NEXT: ret 396 %1 = call float @llvm.fma.f32(float %a, float %b, float %c) 397 ret float %1 398} 399 400define float @fmsub_s(float %a, float %b, float %c) nounwind { 401; CHECKIF-LABEL: fmsub_s: 402; CHECKIF: # %bb.0: 403; CHECKIF-NEXT: fmv.w.x ft0, zero 404; CHECKIF-NEXT: fadd.s ft0, fa2, ft0 405; CHECKIF-NEXT: fmsub.s fa0, fa0, fa1, ft0 406; CHECKIF-NEXT: ret 407; 408; RV32I-LABEL: fmsub_s: 409; RV32I: # %bb.0: 410; RV32I-NEXT: addi sp, sp, -16 411; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 412; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 413; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 414; RV32I-NEXT: mv s0, a1 415; RV32I-NEXT: mv s1, a0 416; RV32I-NEXT: mv a0, a2 417; RV32I-NEXT: li a1, 0 418; RV32I-NEXT: call __addsf3@plt 419; RV32I-NEXT: lui a1, 524288 420; RV32I-NEXT: xor a2, a0, a1 421; RV32I-NEXT: mv a0, s1 422; RV32I-NEXT: mv a1, s0 423; RV32I-NEXT: call fmaf@plt 424; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 425; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 426; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 427; RV32I-NEXT: addi sp, sp, 16 428; RV32I-NEXT: ret 429; 430; RV64I-LABEL: fmsub_s: 431; RV64I: # %bb.0: 432; RV64I-NEXT: addi sp, sp, -32 433; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 434; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 435; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 436; RV64I-NEXT: mv s0, a1 437; RV64I-NEXT: mv s1, a0 438; RV64I-NEXT: mv a0, a2 439; RV64I-NEXT: li a1, 0 440; RV64I-NEXT: call __addsf3@plt 441; RV64I-NEXT: lui a1, 524288 442; RV64I-NEXT: xor a2, a0, a1 443; RV64I-NEXT: mv a0, s1 444; RV64I-NEXT: mv a1, s0 445; RV64I-NEXT: call fmaf@plt 446; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 447; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 448; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 449; RV64I-NEXT: addi sp, sp, 32 450; RV64I-NEXT: ret 451 %c_ = fadd float 0.0, %c ; avoid negation using xor 452 %negc = fsub float -0.0, %c_ 453 %1 = call float @llvm.fma.f32(float %a, float %b, float %negc) 454 ret float %1 455} 456 457define float @fnmadd_s(float %a, float %b, float %c) nounwind { 458; CHECKIF-LABEL: fnmadd_s: 459; CHECKIF: # %bb.0: 460; CHECKIF-NEXT: fmv.w.x ft0, zero 461; CHECKIF-NEXT: fadd.s ft1, fa0, ft0 462; CHECKIF-NEXT: fadd.s ft0, fa2, ft0 463; CHECKIF-NEXT: fnmadd.s fa0, ft1, fa1, ft0 464; CHECKIF-NEXT: ret 465; 466; RV32I-LABEL: fnmadd_s: 467; RV32I: # %bb.0: 468; RV32I-NEXT: addi sp, sp, -16 469; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 470; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 471; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 472; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 473; RV32I-NEXT: mv s0, a2 474; RV32I-NEXT: mv s1, a1 475; RV32I-NEXT: li a1, 0 476; RV32I-NEXT: call __addsf3@plt 477; RV32I-NEXT: mv s2, a0 478; RV32I-NEXT: mv a0, s0 479; RV32I-NEXT: li a1, 0 480; RV32I-NEXT: call __addsf3@plt 481; RV32I-NEXT: lui a2, 524288 482; RV32I-NEXT: xor a1, s2, a2 483; RV32I-NEXT: xor a2, a0, a2 484; RV32I-NEXT: mv a0, a1 485; RV32I-NEXT: mv a1, s1 486; RV32I-NEXT: call fmaf@plt 487; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 488; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 489; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 490; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 491; RV32I-NEXT: addi sp, sp, 16 492; RV32I-NEXT: ret 493; 494; RV64I-LABEL: fnmadd_s: 495; RV64I: # %bb.0: 496; RV64I-NEXT: addi sp, sp, -32 497; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 498; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 499; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 500; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 501; RV64I-NEXT: mv s0, a2 502; RV64I-NEXT: mv s1, a1 503; RV64I-NEXT: li a1, 0 504; RV64I-NEXT: call __addsf3@plt 505; RV64I-NEXT: mv s2, a0 506; RV64I-NEXT: mv a0, s0 507; RV64I-NEXT: li a1, 0 508; RV64I-NEXT: call __addsf3@plt 509; RV64I-NEXT: lui a2, 524288 510; RV64I-NEXT: xor a1, s2, a2 511; RV64I-NEXT: xor a2, a0, a2 512; RV64I-NEXT: mv a0, a1 513; RV64I-NEXT: mv a1, s1 514; RV64I-NEXT: call fmaf@plt 515; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 516; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 517; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 518; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 519; RV64I-NEXT: addi sp, sp, 32 520; RV64I-NEXT: ret 521 %a_ = fadd float 0.0, %a 522 %c_ = fadd float 0.0, %c 523 %nega = fsub float -0.0, %a_ 524 %negc = fsub float -0.0, %c_ 525 %1 = call float @llvm.fma.f32(float %nega, float %b, float %negc) 526 ret float %1 527} 528 529define float @fnmadd_s_2(float %a, float %b, float %c) nounwind { 530; CHECKIF-LABEL: fnmadd_s_2: 531; CHECKIF: # %bb.0: 532; CHECKIF-NEXT: fmv.w.x ft0, zero 533; CHECKIF-NEXT: fadd.s ft1, fa1, ft0 534; CHECKIF-NEXT: fadd.s ft0, fa2, ft0 535; CHECKIF-NEXT: fnmadd.s fa0, ft1, fa0, ft0 536; CHECKIF-NEXT: ret 537; 538; RV32I-LABEL: fnmadd_s_2: 539; RV32I: # %bb.0: 540; RV32I-NEXT: addi sp, sp, -16 541; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 542; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 543; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 544; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 545; RV32I-NEXT: mv s0, a2 546; RV32I-NEXT: mv s1, a0 547; RV32I-NEXT: mv a0, a1 548; RV32I-NEXT: li a1, 0 549; RV32I-NEXT: call __addsf3@plt 550; RV32I-NEXT: mv s2, a0 551; RV32I-NEXT: mv a0, s0 552; RV32I-NEXT: li a1, 0 553; RV32I-NEXT: call __addsf3@plt 554; RV32I-NEXT: lui a2, 524288 555; RV32I-NEXT: xor a1, s2, a2 556; RV32I-NEXT: xor a2, a0, a2 557; RV32I-NEXT: mv a0, s1 558; RV32I-NEXT: call fmaf@plt 559; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 560; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 561; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 562; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 563; RV32I-NEXT: addi sp, sp, 16 564; RV32I-NEXT: ret 565; 566; RV64I-LABEL: fnmadd_s_2: 567; RV64I: # %bb.0: 568; RV64I-NEXT: addi sp, sp, -32 569; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 570; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 571; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 572; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 573; RV64I-NEXT: mv s0, a2 574; RV64I-NEXT: mv s1, a0 575; RV64I-NEXT: mv a0, a1 576; RV64I-NEXT: li a1, 0 577; RV64I-NEXT: call __addsf3@plt 578; RV64I-NEXT: mv s2, a0 579; RV64I-NEXT: mv a0, s0 580; RV64I-NEXT: li a1, 0 581; RV64I-NEXT: call __addsf3@plt 582; RV64I-NEXT: lui a2, 524288 583; RV64I-NEXT: xor a1, s2, a2 584; RV64I-NEXT: xor a2, a0, a2 585; RV64I-NEXT: mv a0, s1 586; RV64I-NEXT: call fmaf@plt 587; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 588; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 589; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 590; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 591; RV64I-NEXT: addi sp, sp, 32 592; RV64I-NEXT: ret 593 %b_ = fadd float 0.0, %b 594 %c_ = fadd float 0.0, %c 595 %negb = fsub float -0.0, %b_ 596 %negc = fsub float -0.0, %c_ 597 %1 = call float @llvm.fma.f32(float %a, float %negb, float %negc) 598 ret float %1 599} 600 601define float @fnmadd_s_3(float %a, float %b, float %c) nounwind { 602; RV32IF-LABEL: fnmadd_s_3: 603; RV32IF: # %bb.0: 604; RV32IF-NEXT: fmadd.s ft0, fa0, fa1, fa2 605; RV32IF-NEXT: fneg.s fa0, ft0 606; RV32IF-NEXT: ret 607; 608; RV64IF-LABEL: fnmadd_s_3: 609; RV64IF: # %bb.0: 610; RV64IF-NEXT: fmadd.s ft0, fa0, fa1, fa2 611; RV64IF-NEXT: fneg.s fa0, ft0 612; RV64IF-NEXT: ret 613; 614; CHECKIF-LABEL: fnmadd_s_3: 615; CHECKIF: # %bb.0: 616; CHECKIF-NEXT: fmadd.s ft0, fa0, fa1, fa2 617; CHECKIF-NEXT: fneg.s fa0, ft0 618; CHECKIF-NEXT: ret 619; 620; RV32I-LABEL: fnmadd_s_3: 621; RV32I: # %bb.0: 622; RV32I-NEXT: addi sp, sp, -16 623; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 624; RV32I-NEXT: call fmaf@plt 625; RV32I-NEXT: lui a1, 524288 626; RV32I-NEXT: xor a0, a0, a1 627; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 628; RV32I-NEXT: addi sp, sp, 16 629; RV32I-NEXT: ret 630; 631; RV64I-LABEL: fnmadd_s_3: 632; RV64I: # %bb.0: 633; RV64I-NEXT: addi sp, sp, -16 634; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 635; RV64I-NEXT: call fmaf@plt 636; RV64I-NEXT: lui a1, 524288 637; RV64I-NEXT: xor a0, a0, a1 638; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 639; RV64I-NEXT: addi sp, sp, 16 640; RV64I-NEXT: ret 641 %1 = call float @llvm.fma.f32(float %a, float %b, float %c) 642 %neg = fneg float %1 643 ret float %neg 644} 645 646define float @fnmadd_nsz(float %a, float %b, float %c) nounwind { 647; RV32IF-LABEL: fnmadd_nsz: 648; RV32IF: # %bb.0: 649; RV32IF-NEXT: fnmadd.s fa0, fa0, fa1, fa2 650; RV32IF-NEXT: ret 651; 652; RV64IF-LABEL: fnmadd_nsz: 653; RV64IF: # %bb.0: 654; RV64IF-NEXT: fnmadd.s fa0, fa0, fa1, fa2 655; RV64IF-NEXT: ret 656; 657; CHECKIF-LABEL: fnmadd_nsz: 658; CHECKIF: # %bb.0: 659; CHECKIF-NEXT: fnmadd.s fa0, fa0, fa1, fa2 660; CHECKIF-NEXT: ret 661; 662; RV32I-LABEL: fnmadd_nsz: 663; RV32I: # %bb.0: 664; RV32I-NEXT: addi sp, sp, -16 665; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 666; RV32I-NEXT: call fmaf@plt 667; RV32I-NEXT: lui a1, 524288 668; RV32I-NEXT: xor a0, a0, a1 669; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 670; RV32I-NEXT: addi sp, sp, 16 671; RV32I-NEXT: ret 672; 673; RV64I-LABEL: fnmadd_nsz: 674; RV64I: # %bb.0: 675; RV64I-NEXT: addi sp, sp, -16 676; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 677; RV64I-NEXT: call fmaf@plt 678; RV64I-NEXT: lui a1, 524288 679; RV64I-NEXT: xor a0, a0, a1 680; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 681; RV64I-NEXT: addi sp, sp, 16 682; RV64I-NEXT: ret 683 %1 = call nsz float @llvm.fma.f32(float %a, float %b, float %c) 684 %neg = fneg nsz float %1 685 ret float %neg 686} 687 688define float @fnmsub_s(float %a, float %b, float %c) nounwind { 689; CHECKIF-LABEL: fnmsub_s: 690; CHECKIF: # %bb.0: 691; CHECKIF-NEXT: fmv.w.x ft0, zero 692; CHECKIF-NEXT: fadd.s ft0, fa0, ft0 693; CHECKIF-NEXT: fnmsub.s fa0, ft0, fa1, fa2 694; CHECKIF-NEXT: ret 695; 696; RV32I-LABEL: fnmsub_s: 697; RV32I: # %bb.0: 698; RV32I-NEXT: addi sp, sp, -16 699; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 700; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 701; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 702; RV32I-NEXT: mv s0, a2 703; RV32I-NEXT: mv s1, a1 704; RV32I-NEXT: li a1, 0 705; RV32I-NEXT: call __addsf3@plt 706; RV32I-NEXT: lui a1, 524288 707; RV32I-NEXT: xor a0, a0, a1 708; RV32I-NEXT: mv a1, s1 709; RV32I-NEXT: mv a2, s0 710; RV32I-NEXT: call fmaf@plt 711; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 712; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 713; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 714; RV32I-NEXT: addi sp, sp, 16 715; RV32I-NEXT: ret 716; 717; RV64I-LABEL: fnmsub_s: 718; RV64I: # %bb.0: 719; RV64I-NEXT: addi sp, sp, -32 720; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 721; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 722; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 723; RV64I-NEXT: mv s0, a2 724; RV64I-NEXT: mv s1, a1 725; RV64I-NEXT: li a1, 0 726; RV64I-NEXT: call __addsf3@plt 727; RV64I-NEXT: lui a1, 524288 728; RV64I-NEXT: xor a0, a0, a1 729; RV64I-NEXT: mv a1, s1 730; RV64I-NEXT: mv a2, s0 731; RV64I-NEXT: call fmaf@plt 732; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 733; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 734; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 735; RV64I-NEXT: addi sp, sp, 32 736; RV64I-NEXT: ret 737 %a_ = fadd float 0.0, %a 738 %nega = fsub float -0.0, %a_ 739 %1 = call float @llvm.fma.f32(float %nega, float %b, float %c) 740 ret float %1 741} 742 743define float @fnmsub_s_2(float %a, float %b, float %c) nounwind { 744; CHECKIF-LABEL: fnmsub_s_2: 745; CHECKIF: # %bb.0: 746; CHECKIF-NEXT: fmv.w.x ft0, zero 747; CHECKIF-NEXT: fadd.s ft0, fa1, ft0 748; CHECKIF-NEXT: fnmsub.s fa0, ft0, fa0, fa2 749; CHECKIF-NEXT: ret 750; 751; RV32I-LABEL: fnmsub_s_2: 752; RV32I: # %bb.0: 753; RV32I-NEXT: addi sp, sp, -16 754; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 755; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 756; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 757; RV32I-NEXT: mv s0, a2 758; RV32I-NEXT: mv s1, a0 759; RV32I-NEXT: mv a0, a1 760; RV32I-NEXT: li a1, 0 761; RV32I-NEXT: call __addsf3@plt 762; RV32I-NEXT: lui a1, 524288 763; RV32I-NEXT: xor a1, a0, a1 764; RV32I-NEXT: mv a0, s1 765; RV32I-NEXT: mv a2, s0 766; RV32I-NEXT: call fmaf@plt 767; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 768; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 769; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 770; RV32I-NEXT: addi sp, sp, 16 771; RV32I-NEXT: ret 772; 773; RV64I-LABEL: fnmsub_s_2: 774; RV64I: # %bb.0: 775; RV64I-NEXT: addi sp, sp, -32 776; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 777; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 778; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 779; RV64I-NEXT: mv s0, a2 780; RV64I-NEXT: mv s1, a0 781; RV64I-NEXT: mv a0, a1 782; RV64I-NEXT: li a1, 0 783; RV64I-NEXT: call __addsf3@plt 784; RV64I-NEXT: lui a1, 524288 785; RV64I-NEXT: xor a1, a0, a1 786; RV64I-NEXT: mv a0, s1 787; RV64I-NEXT: mv a2, s0 788; RV64I-NEXT: call fmaf@plt 789; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 790; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 791; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 792; RV64I-NEXT: addi sp, sp, 32 793; RV64I-NEXT: ret 794 %b_ = fadd float 0.0, %b 795 %negb = fsub float -0.0, %b_ 796 %1 = call float @llvm.fma.f32(float %a, float %negb, float %c) 797 ret float %1 798} 799 800define float @fmadd_s_contract(float %a, float %b, float %c) nounwind { 801; CHECKIF-LABEL: fmadd_s_contract: 802; CHECKIF: # %bb.0: 803; CHECKIF-NEXT: fmadd.s fa0, fa0, fa1, fa2 804; CHECKIF-NEXT: ret 805; 806; RV32I-LABEL: fmadd_s_contract: 807; RV32I: # %bb.0: 808; RV32I-NEXT: addi sp, sp, -16 809; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 810; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 811; RV32I-NEXT: mv s0, a2 812; RV32I-NEXT: call __mulsf3@plt 813; RV32I-NEXT: mv a1, s0 814; RV32I-NEXT: call __addsf3@plt 815; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 816; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 817; RV32I-NEXT: addi sp, sp, 16 818; RV32I-NEXT: ret 819; 820; RV64I-LABEL: fmadd_s_contract: 821; RV64I: # %bb.0: 822; RV64I-NEXT: addi sp, sp, -16 823; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 824; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill 825; RV64I-NEXT: mv s0, a2 826; RV64I-NEXT: call __mulsf3@plt 827; RV64I-NEXT: mv a1, s0 828; RV64I-NEXT: call __addsf3@plt 829; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 830; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload 831; RV64I-NEXT: addi sp, sp, 16 832; RV64I-NEXT: ret 833 %1 = fmul contract float %a, %b 834 %2 = fadd contract float %1, %c 835 ret float %2 836} 837 838define float @fmsub_s_contract(float %a, float %b, float %c) nounwind { 839; CHECKIF-LABEL: fmsub_s_contract: 840; CHECKIF: # %bb.0: 841; CHECKIF-NEXT: fmv.w.x ft0, zero 842; CHECKIF-NEXT: fadd.s ft0, fa2, ft0 843; CHECKIF-NEXT: fmsub.s fa0, fa0, fa1, ft0 844; CHECKIF-NEXT: ret 845; 846; RV32I-LABEL: fmsub_s_contract: 847; RV32I: # %bb.0: 848; RV32I-NEXT: addi sp, sp, -16 849; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 850; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 851; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 852; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 853; RV32I-NEXT: mv s0, a1 854; RV32I-NEXT: mv s1, a0 855; RV32I-NEXT: mv a0, a2 856; RV32I-NEXT: li a1, 0 857; RV32I-NEXT: call __addsf3@plt 858; RV32I-NEXT: mv s2, a0 859; RV32I-NEXT: mv a0, s1 860; RV32I-NEXT: mv a1, s0 861; RV32I-NEXT: call __mulsf3@plt 862; RV32I-NEXT: mv a1, s2 863; RV32I-NEXT: call __subsf3@plt 864; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 865; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 866; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 867; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 868; RV32I-NEXT: addi sp, sp, 16 869; RV32I-NEXT: ret 870; 871; RV64I-LABEL: fmsub_s_contract: 872; RV64I: # %bb.0: 873; RV64I-NEXT: addi sp, sp, -32 874; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 875; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 876; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 877; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 878; RV64I-NEXT: mv s0, a1 879; RV64I-NEXT: mv s1, a0 880; RV64I-NEXT: mv a0, a2 881; RV64I-NEXT: li a1, 0 882; RV64I-NEXT: call __addsf3@plt 883; RV64I-NEXT: mv s2, a0 884; RV64I-NEXT: mv a0, s1 885; RV64I-NEXT: mv a1, s0 886; RV64I-NEXT: call __mulsf3@plt 887; RV64I-NEXT: mv a1, s2 888; RV64I-NEXT: call __subsf3@plt 889; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 890; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 891; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 892; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 893; RV64I-NEXT: addi sp, sp, 32 894; RV64I-NEXT: ret 895 %c_ = fadd float 0.0, %c ; avoid negation using xor 896 %1 = fmul contract float %a, %b 897 %2 = fsub contract float %1, %c_ 898 ret float %2 899} 900 901define float @fnmadd_s_contract(float %a, float %b, float %c) nounwind { 902; CHECKIF-LABEL: fnmadd_s_contract: 903; CHECKIF: # %bb.0: 904; CHECKIF-NEXT: fmv.w.x ft0, zero 905; CHECKIF-NEXT: fadd.s ft1, fa0, ft0 906; CHECKIF-NEXT: fadd.s ft2, fa1, ft0 907; CHECKIF-NEXT: fadd.s ft0, fa2, ft0 908; CHECKIF-NEXT: fnmadd.s fa0, ft1, ft2, ft0 909; CHECKIF-NEXT: ret 910; 911; RV32I-LABEL: fnmadd_s_contract: 912; RV32I: # %bb.0: 913; RV32I-NEXT: addi sp, sp, -16 914; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 915; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 916; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 917; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 918; RV32I-NEXT: mv s0, a2 919; RV32I-NEXT: mv s1, a1 920; RV32I-NEXT: li a1, 0 921; RV32I-NEXT: call __addsf3@plt 922; RV32I-NEXT: mv s2, a0 923; RV32I-NEXT: mv a0, s1 924; RV32I-NEXT: li a1, 0 925; RV32I-NEXT: call __addsf3@plt 926; RV32I-NEXT: mv s1, a0 927; RV32I-NEXT: mv a0, s0 928; RV32I-NEXT: li a1, 0 929; RV32I-NEXT: call __addsf3@plt 930; RV32I-NEXT: mv s0, a0 931; RV32I-NEXT: mv a0, s2 932; RV32I-NEXT: mv a1, s1 933; RV32I-NEXT: call __mulsf3@plt 934; RV32I-NEXT: lui a1, 524288 935; RV32I-NEXT: xor a0, a0, a1 936; RV32I-NEXT: mv a1, s0 937; RV32I-NEXT: call __subsf3@plt 938; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 939; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 940; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 941; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 942; RV32I-NEXT: addi sp, sp, 16 943; RV32I-NEXT: ret 944; 945; RV64I-LABEL: fnmadd_s_contract: 946; RV64I: # %bb.0: 947; RV64I-NEXT: addi sp, sp, -32 948; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 949; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 950; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 951; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 952; RV64I-NEXT: mv s0, a2 953; RV64I-NEXT: mv s1, a1 954; RV64I-NEXT: li a1, 0 955; RV64I-NEXT: call __addsf3@plt 956; RV64I-NEXT: mv s2, a0 957; RV64I-NEXT: mv a0, s1 958; RV64I-NEXT: li a1, 0 959; RV64I-NEXT: call __addsf3@plt 960; RV64I-NEXT: mv s1, a0 961; RV64I-NEXT: mv a0, s0 962; RV64I-NEXT: li a1, 0 963; RV64I-NEXT: call __addsf3@plt 964; RV64I-NEXT: mv s0, a0 965; RV64I-NEXT: mv a0, s2 966; RV64I-NEXT: mv a1, s1 967; RV64I-NEXT: call __mulsf3@plt 968; RV64I-NEXT: lui a1, 524288 969; RV64I-NEXT: xor a0, a0, a1 970; RV64I-NEXT: mv a1, s0 971; RV64I-NEXT: call __subsf3@plt 972; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 973; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 974; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 975; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 976; RV64I-NEXT: addi sp, sp, 32 977; RV64I-NEXT: ret 978 %a_ = fadd float 0.0, %a ; avoid negation using xor 979 %b_ = fadd float 0.0, %b ; avoid negation using xor 980 %c_ = fadd float 0.0, %c ; avoid negation using xor 981 %1 = fmul contract float %a_, %b_ 982 %2 = fneg float %1 983 %3 = fsub contract float %2, %c_ 984 ret float %3 985} 986 987define float @fnmsub_s_contract(float %a, float %b, float %c) nounwind { 988; CHECKIF-LABEL: fnmsub_s_contract: 989; CHECKIF: # %bb.0: 990; CHECKIF-NEXT: fmv.w.x ft0, zero 991; CHECKIF-NEXT: fadd.s ft1, fa0, ft0 992; CHECKIF-NEXT: fadd.s ft0, fa1, ft0 993; CHECKIF-NEXT: fnmsub.s fa0, ft1, ft0, fa2 994; CHECKIF-NEXT: ret 995; 996; RV32I-LABEL: fnmsub_s_contract: 997; RV32I: # %bb.0: 998; RV32I-NEXT: addi sp, sp, -16 999; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 1000; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 1001; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 1002; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 1003; RV32I-NEXT: mv s0, a2 1004; RV32I-NEXT: mv s1, a1 1005; RV32I-NEXT: li a1, 0 1006; RV32I-NEXT: call __addsf3@plt 1007; RV32I-NEXT: mv s2, a0 1008; RV32I-NEXT: mv a0, s1 1009; RV32I-NEXT: li a1, 0 1010; RV32I-NEXT: call __addsf3@plt 1011; RV32I-NEXT: mv a1, a0 1012; RV32I-NEXT: mv a0, s2 1013; RV32I-NEXT: call __mulsf3@plt 1014; RV32I-NEXT: mv a1, a0 1015; RV32I-NEXT: mv a0, s0 1016; RV32I-NEXT: call __subsf3@plt 1017; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 1018; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 1019; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 1020; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 1021; RV32I-NEXT: addi sp, sp, 16 1022; RV32I-NEXT: ret 1023; 1024; RV64I-LABEL: fnmsub_s_contract: 1025; RV64I: # %bb.0: 1026; RV64I-NEXT: addi sp, sp, -32 1027; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 1028; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 1029; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 1030; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 1031; RV64I-NEXT: mv s0, a2 1032; RV64I-NEXT: mv s1, a1 1033; RV64I-NEXT: li a1, 0 1034; RV64I-NEXT: call __addsf3@plt 1035; RV64I-NEXT: mv s2, a0 1036; RV64I-NEXT: mv a0, s1 1037; RV64I-NEXT: li a1, 0 1038; RV64I-NEXT: call __addsf3@plt 1039; RV64I-NEXT: mv a1, a0 1040; RV64I-NEXT: mv a0, s2 1041; RV64I-NEXT: call __mulsf3@plt 1042; RV64I-NEXT: mv a1, a0 1043; RV64I-NEXT: mv a0, s0 1044; RV64I-NEXT: call __subsf3@plt 1045; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 1046; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 1047; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 1048; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 1049; RV64I-NEXT: addi sp, sp, 32 1050; RV64I-NEXT: ret 1051 %a_ = fadd float 0.0, %a ; avoid negation using xor 1052 %b_ = fadd float 0.0, %b ; avoid negation using xor 1053 %1 = fmul contract float %a_, %b_ 1054 %2 = fsub contract float %c, %1 1055 ret float %2 1056} 1057