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; RV32I-LABEL: fnmadd_s_3: 615; RV32I: # %bb.0: 616; RV32I-NEXT: addi sp, sp, -16 617; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 618; RV32I-NEXT: call fmaf@plt 619; RV32I-NEXT: lui a1, 524288 620; RV32I-NEXT: xor a0, a0, a1 621; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 622; RV32I-NEXT: addi sp, sp, 16 623; RV32I-NEXT: ret 624; 625; RV64I-LABEL: fnmadd_s_3: 626; RV64I: # %bb.0: 627; RV64I-NEXT: addi sp, sp, -16 628; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 629; RV64I-NEXT: call fmaf@plt 630; RV64I-NEXT: lui a1, 524288 631; RV64I-NEXT: xor a0, a0, a1 632; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 633; RV64I-NEXT: addi sp, sp, 16 634; RV64I-NEXT: ret 635 %1 = call float @llvm.fma.f32(float %a, float %b, float %c) 636 %neg = fneg float %1 637 ret float %neg 638} 639 640define float @fnmadd_nsz(float %a, float %b, float %c) nounwind { 641; RV32IF-LABEL: fnmadd_nsz: 642; RV32IF: # %bb.0: 643; RV32IF-NEXT: fnmadd.s fa0, fa0, fa1, fa2 644; RV32IF-NEXT: ret 645; 646; RV64IF-LABEL: fnmadd_nsz: 647; RV64IF: # %bb.0: 648; RV64IF-NEXT: fnmadd.s fa0, fa0, fa1, fa2 649; RV64IF-NEXT: ret 650; 651; RV32I-LABEL: fnmadd_nsz: 652; RV32I: # %bb.0: 653; RV32I-NEXT: addi sp, sp, -16 654; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 655; RV32I-NEXT: call fmaf@plt 656; RV32I-NEXT: lui a1, 524288 657; RV32I-NEXT: xor a0, a0, a1 658; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 659; RV32I-NEXT: addi sp, sp, 16 660; RV32I-NEXT: ret 661; 662; RV64I-LABEL: fnmadd_nsz: 663; RV64I: # %bb.0: 664; RV64I-NEXT: addi sp, sp, -16 665; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 666; RV64I-NEXT: call fmaf@plt 667; RV64I-NEXT: lui a1, 524288 668; RV64I-NEXT: xor a0, a0, a1 669; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 670; RV64I-NEXT: addi sp, sp, 16 671; RV64I-NEXT: ret 672 %1 = call nsz float @llvm.fma.f32(float %a, float %b, float %c) 673 %neg = fneg nsz float %1 674 ret float %neg 675} 676 677define float @fnmsub_s(float %a, float %b, float %c) nounwind { 678; CHECKIF-LABEL: fnmsub_s: 679; CHECKIF: # %bb.0: 680; CHECKIF-NEXT: fmv.w.x ft0, zero 681; CHECKIF-NEXT: fadd.s ft0, fa0, ft0 682; CHECKIF-NEXT: fnmsub.s fa0, ft0, fa1, fa2 683; CHECKIF-NEXT: ret 684; 685; RV32I-LABEL: fnmsub_s: 686; RV32I: # %bb.0: 687; RV32I-NEXT: addi sp, sp, -16 688; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 689; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 690; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 691; RV32I-NEXT: mv s0, a2 692; RV32I-NEXT: mv s1, a1 693; RV32I-NEXT: li a1, 0 694; RV32I-NEXT: call __addsf3@plt 695; RV32I-NEXT: lui a1, 524288 696; RV32I-NEXT: xor a0, a0, a1 697; RV32I-NEXT: mv a1, s1 698; RV32I-NEXT: mv a2, s0 699; RV32I-NEXT: call fmaf@plt 700; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 701; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 702; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 703; RV32I-NEXT: addi sp, sp, 16 704; RV32I-NEXT: ret 705; 706; RV64I-LABEL: fnmsub_s: 707; RV64I: # %bb.0: 708; RV64I-NEXT: addi sp, sp, -32 709; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 710; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 711; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 712; RV64I-NEXT: mv s0, a2 713; RV64I-NEXT: mv s1, a1 714; RV64I-NEXT: li a1, 0 715; RV64I-NEXT: call __addsf3@plt 716; RV64I-NEXT: lui a1, 524288 717; RV64I-NEXT: xor a0, a0, a1 718; RV64I-NEXT: mv a1, s1 719; RV64I-NEXT: mv a2, s0 720; RV64I-NEXT: call fmaf@plt 721; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 722; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 723; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 724; RV64I-NEXT: addi sp, sp, 32 725; RV64I-NEXT: ret 726 %a_ = fadd float 0.0, %a 727 %nega = fsub float -0.0, %a_ 728 %1 = call float @llvm.fma.f32(float %nega, float %b, float %c) 729 ret float %1 730} 731 732define float @fnmsub_s_2(float %a, float %b, float %c) nounwind { 733; CHECKIF-LABEL: fnmsub_s_2: 734; CHECKIF: # %bb.0: 735; CHECKIF-NEXT: fmv.w.x ft0, zero 736; CHECKIF-NEXT: fadd.s ft0, fa1, ft0 737; CHECKIF-NEXT: fnmsub.s fa0, ft0, fa0, fa2 738; CHECKIF-NEXT: ret 739; 740; RV32I-LABEL: fnmsub_s_2: 741; RV32I: # %bb.0: 742; RV32I-NEXT: addi sp, sp, -16 743; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 744; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 745; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 746; RV32I-NEXT: mv s0, a2 747; RV32I-NEXT: mv s1, a0 748; RV32I-NEXT: mv a0, a1 749; RV32I-NEXT: li a1, 0 750; RV32I-NEXT: call __addsf3@plt 751; RV32I-NEXT: lui a1, 524288 752; RV32I-NEXT: xor a1, a0, a1 753; RV32I-NEXT: mv a0, s1 754; RV32I-NEXT: mv a2, s0 755; RV32I-NEXT: call fmaf@plt 756; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 757; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 758; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 759; RV32I-NEXT: addi sp, sp, 16 760; RV32I-NEXT: ret 761; 762; RV64I-LABEL: fnmsub_s_2: 763; RV64I: # %bb.0: 764; RV64I-NEXT: addi sp, sp, -32 765; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 766; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 767; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 768; RV64I-NEXT: mv s0, a2 769; RV64I-NEXT: mv s1, a0 770; RV64I-NEXT: mv a0, a1 771; RV64I-NEXT: li a1, 0 772; RV64I-NEXT: call __addsf3@plt 773; RV64I-NEXT: lui a1, 524288 774; RV64I-NEXT: xor a1, a0, a1 775; RV64I-NEXT: mv a0, s1 776; RV64I-NEXT: mv a2, s0 777; RV64I-NEXT: call fmaf@plt 778; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 779; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 780; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 781; RV64I-NEXT: addi sp, sp, 32 782; RV64I-NEXT: ret 783 %b_ = fadd float 0.0, %b 784 %negb = fsub float -0.0, %b_ 785 %1 = call float @llvm.fma.f32(float %a, float %negb, float %c) 786 ret float %1 787} 788 789define float @fmadd_s_contract(float %a, float %b, float %c) nounwind { 790; CHECKIF-LABEL: fmadd_s_contract: 791; CHECKIF: # %bb.0: 792; CHECKIF-NEXT: fmadd.s fa0, fa0, fa1, fa2 793; CHECKIF-NEXT: ret 794; 795; RV32I-LABEL: fmadd_s_contract: 796; RV32I: # %bb.0: 797; RV32I-NEXT: addi sp, sp, -16 798; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 799; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 800; RV32I-NEXT: mv s0, a2 801; RV32I-NEXT: call __mulsf3@plt 802; RV32I-NEXT: mv a1, s0 803; RV32I-NEXT: call __addsf3@plt 804; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 805; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 806; RV32I-NEXT: addi sp, sp, 16 807; RV32I-NEXT: ret 808; 809; RV64I-LABEL: fmadd_s_contract: 810; RV64I: # %bb.0: 811; RV64I-NEXT: addi sp, sp, -16 812; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 813; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill 814; RV64I-NEXT: mv s0, a2 815; RV64I-NEXT: call __mulsf3@plt 816; RV64I-NEXT: mv a1, s0 817; RV64I-NEXT: call __addsf3@plt 818; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 819; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload 820; RV64I-NEXT: addi sp, sp, 16 821; RV64I-NEXT: ret 822 %1 = fmul contract float %a, %b 823 %2 = fadd contract float %1, %c 824 ret float %2 825} 826 827define float @fmsub_s_contract(float %a, float %b, float %c) nounwind { 828; CHECKIF-LABEL: fmsub_s_contract: 829; CHECKIF: # %bb.0: 830; CHECKIF-NEXT: fmv.w.x ft0, zero 831; CHECKIF-NEXT: fadd.s ft0, fa2, ft0 832; CHECKIF-NEXT: fmsub.s fa0, fa0, fa1, ft0 833; CHECKIF-NEXT: ret 834; 835; RV32I-LABEL: fmsub_s_contract: 836; RV32I: # %bb.0: 837; RV32I-NEXT: addi sp, sp, -16 838; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 839; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 840; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 841; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 842; RV32I-NEXT: mv s0, a1 843; RV32I-NEXT: mv s1, a0 844; RV32I-NEXT: mv a0, a2 845; RV32I-NEXT: li a1, 0 846; RV32I-NEXT: call __addsf3@plt 847; RV32I-NEXT: mv s2, a0 848; RV32I-NEXT: mv a0, s1 849; RV32I-NEXT: mv a1, s0 850; RV32I-NEXT: call __mulsf3@plt 851; RV32I-NEXT: mv a1, s2 852; RV32I-NEXT: call __subsf3@plt 853; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 854; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 855; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 856; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 857; RV32I-NEXT: addi sp, sp, 16 858; RV32I-NEXT: ret 859; 860; RV64I-LABEL: fmsub_s_contract: 861; RV64I: # %bb.0: 862; RV64I-NEXT: addi sp, sp, -32 863; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 864; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 865; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 866; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 867; RV64I-NEXT: mv s0, a1 868; RV64I-NEXT: mv s1, a0 869; RV64I-NEXT: mv a0, a2 870; RV64I-NEXT: li a1, 0 871; RV64I-NEXT: call __addsf3@plt 872; RV64I-NEXT: mv s2, a0 873; RV64I-NEXT: mv a0, s1 874; RV64I-NEXT: mv a1, s0 875; RV64I-NEXT: call __mulsf3@plt 876; RV64I-NEXT: mv a1, s2 877; RV64I-NEXT: call __subsf3@plt 878; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 879; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 880; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 881; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 882; RV64I-NEXT: addi sp, sp, 32 883; RV64I-NEXT: ret 884 %c_ = fadd float 0.0, %c ; avoid negation using xor 885 %1 = fmul contract float %a, %b 886 %2 = fsub contract float %1, %c_ 887 ret float %2 888} 889 890define float @fnmadd_s_contract(float %a, float %b, float %c) nounwind { 891; CHECKIF-LABEL: fnmadd_s_contract: 892; CHECKIF: # %bb.0: 893; CHECKIF-NEXT: fmv.w.x ft0, zero 894; CHECKIF-NEXT: fadd.s ft1, fa0, ft0 895; CHECKIF-NEXT: fadd.s ft2, fa1, ft0 896; CHECKIF-NEXT: fadd.s ft0, fa2, ft0 897; CHECKIF-NEXT: fnmadd.s fa0, ft1, ft2, ft0 898; CHECKIF-NEXT: ret 899; 900; RV32I-LABEL: fnmadd_s_contract: 901; RV32I: # %bb.0: 902; RV32I-NEXT: addi sp, sp, -16 903; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 904; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 905; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 906; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 907; RV32I-NEXT: mv s0, a2 908; RV32I-NEXT: mv s1, a1 909; RV32I-NEXT: li a1, 0 910; RV32I-NEXT: call __addsf3@plt 911; RV32I-NEXT: mv s2, a0 912; RV32I-NEXT: mv a0, s1 913; RV32I-NEXT: li a1, 0 914; RV32I-NEXT: call __addsf3@plt 915; RV32I-NEXT: mv s1, a0 916; RV32I-NEXT: mv a0, s0 917; RV32I-NEXT: li a1, 0 918; RV32I-NEXT: call __addsf3@plt 919; RV32I-NEXT: mv s0, a0 920; RV32I-NEXT: mv a0, s2 921; RV32I-NEXT: mv a1, s1 922; RV32I-NEXT: call __mulsf3@plt 923; RV32I-NEXT: lui a1, 524288 924; RV32I-NEXT: xor a0, a0, a1 925; RV32I-NEXT: mv a1, s0 926; RV32I-NEXT: call __subsf3@plt 927; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 928; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 929; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 930; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 931; RV32I-NEXT: addi sp, sp, 16 932; RV32I-NEXT: ret 933; 934; RV64I-LABEL: fnmadd_s_contract: 935; RV64I: # %bb.0: 936; RV64I-NEXT: addi sp, sp, -32 937; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 938; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 939; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 940; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 941; RV64I-NEXT: mv s0, a2 942; RV64I-NEXT: mv s1, a1 943; RV64I-NEXT: li a1, 0 944; RV64I-NEXT: call __addsf3@plt 945; RV64I-NEXT: mv s2, a0 946; RV64I-NEXT: mv a0, s1 947; RV64I-NEXT: li a1, 0 948; RV64I-NEXT: call __addsf3@plt 949; RV64I-NEXT: mv s1, a0 950; RV64I-NEXT: mv a0, s0 951; RV64I-NEXT: li a1, 0 952; RV64I-NEXT: call __addsf3@plt 953; RV64I-NEXT: mv s0, a0 954; RV64I-NEXT: mv a0, s2 955; RV64I-NEXT: mv a1, s1 956; RV64I-NEXT: call __mulsf3@plt 957; RV64I-NEXT: lui a1, 524288 958; RV64I-NEXT: xor a0, a0, a1 959; RV64I-NEXT: mv a1, s0 960; RV64I-NEXT: call __subsf3@plt 961; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 962; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 963; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 964; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 965; RV64I-NEXT: addi sp, sp, 32 966; RV64I-NEXT: ret 967 %a_ = fadd float 0.0, %a ; avoid negation using xor 968 %b_ = fadd float 0.0, %b ; avoid negation using xor 969 %c_ = fadd float 0.0, %c ; avoid negation using xor 970 %1 = fmul contract float %a_, %b_ 971 %2 = fneg float %1 972 %3 = fsub contract float %2, %c_ 973 ret float %3 974} 975 976define float @fnmsub_s_contract(float %a, float %b, float %c) nounwind { 977; CHECKIF-LABEL: fnmsub_s_contract: 978; CHECKIF: # %bb.0: 979; CHECKIF-NEXT: fmv.w.x ft0, zero 980; CHECKIF-NEXT: fadd.s ft1, fa0, ft0 981; CHECKIF-NEXT: fadd.s ft0, fa1, ft0 982; CHECKIF-NEXT: fnmsub.s fa0, ft1, ft0, fa2 983; CHECKIF-NEXT: ret 984; 985; RV32I-LABEL: fnmsub_s_contract: 986; RV32I: # %bb.0: 987; RV32I-NEXT: addi sp, sp, -16 988; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 989; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 990; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 991; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill 992; RV32I-NEXT: mv s0, a2 993; RV32I-NEXT: mv s1, a1 994; RV32I-NEXT: li a1, 0 995; RV32I-NEXT: call __addsf3@plt 996; RV32I-NEXT: mv s2, a0 997; RV32I-NEXT: mv a0, s1 998; RV32I-NEXT: li a1, 0 999; RV32I-NEXT: call __addsf3@plt 1000; RV32I-NEXT: mv a1, a0 1001; RV32I-NEXT: mv a0, s2 1002; RV32I-NEXT: call __mulsf3@plt 1003; RV32I-NEXT: mv a1, a0 1004; RV32I-NEXT: mv a0, s0 1005; RV32I-NEXT: call __subsf3@plt 1006; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 1007; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 1008; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 1009; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload 1010; RV32I-NEXT: addi sp, sp, 16 1011; RV32I-NEXT: ret 1012; 1013; RV64I-LABEL: fnmsub_s_contract: 1014; RV64I: # %bb.0: 1015; RV64I-NEXT: addi sp, sp, -32 1016; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 1017; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 1018; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 1019; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 1020; RV64I-NEXT: mv s0, a2 1021; RV64I-NEXT: mv s1, a1 1022; RV64I-NEXT: li a1, 0 1023; RV64I-NEXT: call __addsf3@plt 1024; RV64I-NEXT: mv s2, a0 1025; RV64I-NEXT: mv a0, s1 1026; RV64I-NEXT: li a1, 0 1027; RV64I-NEXT: call __addsf3@plt 1028; RV64I-NEXT: mv a1, a0 1029; RV64I-NEXT: mv a0, s2 1030; RV64I-NEXT: call __mulsf3@plt 1031; RV64I-NEXT: mv a1, a0 1032; RV64I-NEXT: mv a0, s0 1033; RV64I-NEXT: call __subsf3@plt 1034; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 1035; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 1036; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 1037; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 1038; RV64I-NEXT: addi sp, sp, 32 1039; RV64I-NEXT: ret 1040 %a_ = fadd float 0.0, %a ; avoid negation using xor 1041 %b_ = fadd float 0.0, %b ; avoid negation using xor 1042 %1 = fmul contract float %a_, %b_ 1043 %2 = fsub contract float %c, %1 1044 ret float %2 1045} 1046