1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \ 3; RUN: -target-abi=ilp32d | FileCheck -check-prefixes=CHECKIFD,RV32IFD %s 4; RUN: llc -mtriple=riscv64 -mattr=+d -verify-machineinstrs < %s \ 5; RUN: -target-abi=lp64d | FileCheck -check-prefixes=CHECKIFD,RV64IFD %s 6; RUN: llc -mtriple=riscv32 -mattr=+zdinx -verify-machineinstrs < %s \ 7; RUN: -target-abi=ilp32 | FileCheck -check-prefix=RV32IZFINXZDINX %s 8; RUN: llc -mtriple=riscv64 -mattr=+zdinx -verify-machineinstrs < %s \ 9; RUN: -target-abi=lp64 | FileCheck -check-prefix=RV64IZFINXZDINX %s 10; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ 11; RUN: | FileCheck -check-prefix=RV32I %s 12; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ 13; RUN: | FileCheck -check-prefix=RV64I %s 14 15; These tests are each targeted at a particular RISC-V FPU instruction. 16; Compares and conversions can be found in double-fcmp.ll and double-convert.ll 17; respectively. Some other double-*.ll files in this folder exercise LLVM IR 18; instructions that don't directly match a RISC-V instruction. 19 20define double @fadd_d(double %a, double %b) nounwind { 21; CHECKIFD-LABEL: fadd_d: 22; CHECKIFD: # %bb.0: 23; CHECKIFD-NEXT: fadd.d fa0, fa0, fa1 24; CHECKIFD-NEXT: ret 25; 26; RV32IZFINXZDINX-LABEL: fadd_d: 27; RV32IZFINXZDINX: # %bb.0: 28; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a2 29; RV32IZFINXZDINX-NEXT: ret 30; 31; RV64IZFINXZDINX-LABEL: fadd_d: 32; RV64IZFINXZDINX: # %bb.0: 33; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, a1 34; RV64IZFINXZDINX-NEXT: ret 35; 36; RV32I-LABEL: fadd_d: 37; RV32I: # %bb.0: 38; RV32I-NEXT: addi sp, sp, -16 39; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 40; RV32I-NEXT: call __adddf3 41; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 42; RV32I-NEXT: addi sp, sp, 16 43; RV32I-NEXT: ret 44; 45; RV64I-LABEL: fadd_d: 46; RV64I: # %bb.0: 47; RV64I-NEXT: addi sp, sp, -16 48; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 49; RV64I-NEXT: call __adddf3 50; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 51; RV64I-NEXT: addi sp, sp, 16 52; RV64I-NEXT: ret 53 %1 = fadd double %a, %b 54 ret double %1 55} 56 57define double @fsub_d(double %a, double %b) nounwind { 58; CHECKIFD-LABEL: fsub_d: 59; CHECKIFD: # %bb.0: 60; CHECKIFD-NEXT: fsub.d fa0, fa0, fa1 61; CHECKIFD-NEXT: ret 62; 63; RV32IZFINXZDINX-LABEL: fsub_d: 64; RV32IZFINXZDINX: # %bb.0: 65; RV32IZFINXZDINX-NEXT: fsub.d a0, a0, a2 66; RV32IZFINXZDINX-NEXT: ret 67; 68; RV64IZFINXZDINX-LABEL: fsub_d: 69; RV64IZFINXZDINX: # %bb.0: 70; RV64IZFINXZDINX-NEXT: fsub.d a0, a0, a1 71; RV64IZFINXZDINX-NEXT: ret 72; 73; RV32I-LABEL: fsub_d: 74; RV32I: # %bb.0: 75; RV32I-NEXT: addi sp, sp, -16 76; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 77; RV32I-NEXT: call __subdf3 78; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 79; RV32I-NEXT: addi sp, sp, 16 80; RV32I-NEXT: ret 81; 82; RV64I-LABEL: fsub_d: 83; RV64I: # %bb.0: 84; RV64I-NEXT: addi sp, sp, -16 85; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 86; RV64I-NEXT: call __subdf3 87; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 88; RV64I-NEXT: addi sp, sp, 16 89; RV64I-NEXT: ret 90 %1 = fsub double %a, %b 91 ret double %1 92} 93 94define double @fmul_d(double %a, double %b) nounwind { 95; CHECKIFD-LABEL: fmul_d: 96; CHECKIFD: # %bb.0: 97; CHECKIFD-NEXT: fmul.d fa0, fa0, fa1 98; CHECKIFD-NEXT: ret 99; 100; RV32IZFINXZDINX-LABEL: fmul_d: 101; RV32IZFINXZDINX: # %bb.0: 102; RV32IZFINXZDINX-NEXT: fmul.d a0, a0, a2 103; RV32IZFINXZDINX-NEXT: ret 104; 105; RV64IZFINXZDINX-LABEL: fmul_d: 106; RV64IZFINXZDINX: # %bb.0: 107; RV64IZFINXZDINX-NEXT: fmul.d a0, a0, a1 108; RV64IZFINXZDINX-NEXT: ret 109; 110; RV32I-LABEL: fmul_d: 111; RV32I: # %bb.0: 112; RV32I-NEXT: addi sp, sp, -16 113; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 114; RV32I-NEXT: call __muldf3 115; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 116; RV32I-NEXT: addi sp, sp, 16 117; RV32I-NEXT: ret 118; 119; RV64I-LABEL: fmul_d: 120; RV64I: # %bb.0: 121; RV64I-NEXT: addi sp, sp, -16 122; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 123; RV64I-NEXT: call __muldf3 124; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 125; RV64I-NEXT: addi sp, sp, 16 126; RV64I-NEXT: ret 127 %1 = fmul double %a, %b 128 ret double %1 129} 130 131define double @fdiv_d(double %a, double %b) nounwind { 132; CHECKIFD-LABEL: fdiv_d: 133; CHECKIFD: # %bb.0: 134; CHECKIFD-NEXT: fdiv.d fa0, fa0, fa1 135; CHECKIFD-NEXT: ret 136; 137; RV32IZFINXZDINX-LABEL: fdiv_d: 138; RV32IZFINXZDINX: # %bb.0: 139; RV32IZFINXZDINX-NEXT: fdiv.d a0, a0, a2 140; RV32IZFINXZDINX-NEXT: ret 141; 142; RV64IZFINXZDINX-LABEL: fdiv_d: 143; RV64IZFINXZDINX: # %bb.0: 144; RV64IZFINXZDINX-NEXT: fdiv.d a0, a0, a1 145; RV64IZFINXZDINX-NEXT: ret 146; 147; RV32I-LABEL: fdiv_d: 148; RV32I: # %bb.0: 149; RV32I-NEXT: addi sp, sp, -16 150; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 151; RV32I-NEXT: call __divdf3 152; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 153; RV32I-NEXT: addi sp, sp, 16 154; RV32I-NEXT: ret 155; 156; RV64I-LABEL: fdiv_d: 157; RV64I: # %bb.0: 158; RV64I-NEXT: addi sp, sp, -16 159; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 160; RV64I-NEXT: call __divdf3 161; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 162; RV64I-NEXT: addi sp, sp, 16 163; RV64I-NEXT: ret 164 %1 = fdiv double %a, %b 165 ret double %1 166} 167 168declare double @llvm.sqrt.f64(double) 169 170define double @fsqrt_d(double %a) nounwind { 171; CHECKIFD-LABEL: fsqrt_d: 172; CHECKIFD: # %bb.0: 173; CHECKIFD-NEXT: fsqrt.d fa0, fa0 174; CHECKIFD-NEXT: ret 175; 176; RV32IZFINXZDINX-LABEL: fsqrt_d: 177; RV32IZFINXZDINX: # %bb.0: 178; RV32IZFINXZDINX-NEXT: fsqrt.d a0, a0 179; RV32IZFINXZDINX-NEXT: ret 180; 181; RV64IZFINXZDINX-LABEL: fsqrt_d: 182; RV64IZFINXZDINX: # %bb.0: 183; RV64IZFINXZDINX-NEXT: fsqrt.d a0, a0 184; RV64IZFINXZDINX-NEXT: ret 185; 186; RV32I-LABEL: fsqrt_d: 187; RV32I: # %bb.0: 188; RV32I-NEXT: addi sp, sp, -16 189; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 190; RV32I-NEXT: call sqrt 191; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 192; RV32I-NEXT: addi sp, sp, 16 193; RV32I-NEXT: ret 194; 195; RV64I-LABEL: fsqrt_d: 196; RV64I: # %bb.0: 197; RV64I-NEXT: addi sp, sp, -16 198; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 199; RV64I-NEXT: call sqrt 200; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 201; RV64I-NEXT: addi sp, sp, 16 202; RV64I-NEXT: ret 203 %1 = call double @llvm.sqrt.f64(double %a) 204 ret double %1 205} 206 207declare double @llvm.copysign.f64(double, double) 208 209define double @fsgnj_d(double %a, double %b) nounwind { 210; CHECKIFD-LABEL: fsgnj_d: 211; CHECKIFD: # %bb.0: 212; CHECKIFD-NEXT: fsgnj.d fa0, fa0, fa1 213; CHECKIFD-NEXT: ret 214; 215; RV32IZFINXZDINX-LABEL: fsgnj_d: 216; RV32IZFINXZDINX: # %bb.0: 217; RV32IZFINXZDINX-NEXT: fsgnj.d a0, a0, a2 218; RV32IZFINXZDINX-NEXT: ret 219; 220; RV64IZFINXZDINX-LABEL: fsgnj_d: 221; RV64IZFINXZDINX: # %bb.0: 222; RV64IZFINXZDINX-NEXT: fsgnj.d a0, a0, a1 223; RV64IZFINXZDINX-NEXT: ret 224; 225; RV32I-LABEL: fsgnj_d: 226; RV32I: # %bb.0: 227; RV32I-NEXT: lui a2, 524288 228; RV32I-NEXT: slli a1, a1, 1 229; RV32I-NEXT: and a2, a3, a2 230; RV32I-NEXT: srli a1, a1, 1 231; RV32I-NEXT: or a1, a1, a2 232; RV32I-NEXT: ret 233; 234; RV64I-LABEL: fsgnj_d: 235; RV64I: # %bb.0: 236; RV64I-NEXT: srli a1, a1, 63 237; RV64I-NEXT: slli a0, a0, 1 238; RV64I-NEXT: slli a1, a1, 63 239; RV64I-NEXT: srli a0, a0, 1 240; RV64I-NEXT: or a0, a0, a1 241; RV64I-NEXT: ret 242 %1 = call double @llvm.copysign.f64(double %a, double %b) 243 ret double %1 244} 245 246; This function performs extra work to ensure that 247; DAGCombiner::visitBITCAST doesn't replace the fneg with an xor. 248define i32 @fneg_d(double %a, double %b) nounwind { 249; CHECKIFD-LABEL: fneg_d: 250; CHECKIFD: # %bb.0: 251; CHECKIFD-NEXT: fadd.d fa5, fa0, fa0 252; CHECKIFD-NEXT: fneg.d fa4, fa5 253; CHECKIFD-NEXT: feq.d a0, fa5, fa4 254; CHECKIFD-NEXT: ret 255; 256; RV32IZFINXZDINX-LABEL: fneg_d: 257; RV32IZFINXZDINX: # %bb.0: 258; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a0 259; RV32IZFINXZDINX-NEXT: fneg.d a2, a0 260; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a2 261; RV32IZFINXZDINX-NEXT: ret 262; 263; RV64IZFINXZDINX-LABEL: fneg_d: 264; RV64IZFINXZDINX: # %bb.0: 265; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, a0 266; RV64IZFINXZDINX-NEXT: fneg.d a1, a0 267; RV64IZFINXZDINX-NEXT: feq.d a0, a0, a1 268; RV64IZFINXZDINX-NEXT: ret 269; 270; RV32I-LABEL: fneg_d: 271; RV32I: # %bb.0: 272; RV32I-NEXT: addi sp, sp, -16 273; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 274; RV32I-NEXT: mv a2, a0 275; RV32I-NEXT: mv a3, a1 276; RV32I-NEXT: call __adddf3 277; RV32I-NEXT: lui a3, 524288 278; RV32I-NEXT: xor a3, a1, a3 279; RV32I-NEXT: mv a2, a0 280; RV32I-NEXT: call __eqdf2 281; RV32I-NEXT: seqz a0, a0 282; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 283; RV32I-NEXT: addi sp, sp, 16 284; RV32I-NEXT: ret 285; 286; RV64I-LABEL: fneg_d: 287; RV64I: # %bb.0: 288; RV64I-NEXT: addi sp, sp, -16 289; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 290; RV64I-NEXT: mv a1, a0 291; RV64I-NEXT: call __adddf3 292; RV64I-NEXT: li a1, -1 293; RV64I-NEXT: slli a1, a1, 63 294; RV64I-NEXT: xor a1, a0, a1 295; RV64I-NEXT: call __eqdf2 296; RV64I-NEXT: seqz a0, a0 297; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 298; RV64I-NEXT: addi sp, sp, 16 299; RV64I-NEXT: ret 300 %1 = fadd double %a, %a 301 %2 = fneg double %1 302 %3 = fcmp oeq double %1, %2 303 %4 = zext i1 %3 to i32 304 ret i32 %4 305} 306 307define double @fsgnjn_d(double %a, double %b) nounwind { 308; TODO: fsgnjn.s isn't selected on RV64 because DAGCombiner::visitBITCAST will 309; convert (bitconvert (fneg x)) to a xor. 310; 311; CHECKIFD-LABEL: fsgnjn_d: 312; CHECKIFD: # %bb.0: 313; CHECKIFD-NEXT: fsgnjn.d fa0, fa0, fa1 314; CHECKIFD-NEXT: ret 315; 316; RV32IZFINXZDINX-LABEL: fsgnjn_d: 317; RV32IZFINXZDINX: # %bb.0: 318; RV32IZFINXZDINX-NEXT: fsgnjn.d a0, a0, a2 319; RV32IZFINXZDINX-NEXT: ret 320; 321; RV64IZFINXZDINX-LABEL: fsgnjn_d: 322; RV64IZFINXZDINX: # %bb.0: 323; RV64IZFINXZDINX-NEXT: fsgnjn.d a0, a0, a1 324; RV64IZFINXZDINX-NEXT: ret 325; 326; RV32I-LABEL: fsgnjn_d: 327; RV32I: # %bb.0: 328; RV32I-NEXT: not a2, a3 329; RV32I-NEXT: lui a3, 524288 330; RV32I-NEXT: slli a1, a1, 1 331; RV32I-NEXT: and a2, a2, a3 332; RV32I-NEXT: srli a1, a1, 1 333; RV32I-NEXT: or a1, a1, a2 334; RV32I-NEXT: ret 335; 336; RV64I-LABEL: fsgnjn_d: 337; RV64I: # %bb.0: 338; RV64I-NEXT: not a1, a1 339; RV64I-NEXT: slli a0, a0, 1 340; RV64I-NEXT: srli a0, a0, 1 341; RV64I-NEXT: srli a1, a1, 63 342; RV64I-NEXT: slli a1, a1, 63 343; RV64I-NEXT: or a0, a0, a1 344; RV64I-NEXT: ret 345 %1 = fsub double -0.0, %b 346 %2 = call double @llvm.copysign.f64(double %a, double %1) 347 ret double %2 348} 349 350declare double @llvm.fabs.f64(double) 351 352; This function performs extra work to ensure that 353; DAGCombiner::visitBITCAST doesn't replace the fabs with an and. 354define double @fabs_d(double %a, double %b) nounwind { 355; CHECKIFD-LABEL: fabs_d: 356; CHECKIFD: # %bb.0: 357; CHECKIFD-NEXT: fadd.d fa5, fa0, fa1 358; CHECKIFD-NEXT: fabs.d fa4, fa5 359; CHECKIFD-NEXT: fadd.d fa0, fa4, fa5 360; CHECKIFD-NEXT: ret 361; 362; RV32IZFINXZDINX-LABEL: fabs_d: 363; RV32IZFINXZDINX: # %bb.0: 364; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a2 365; RV32IZFINXZDINX-NEXT: fabs.d a2, a0 366; RV32IZFINXZDINX-NEXT: fadd.d a0, a2, a0 367; RV32IZFINXZDINX-NEXT: ret 368; 369; RV64IZFINXZDINX-LABEL: fabs_d: 370; RV64IZFINXZDINX: # %bb.0: 371; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, a1 372; RV64IZFINXZDINX-NEXT: fabs.d a1, a0 373; RV64IZFINXZDINX-NEXT: fadd.d a0, a1, a0 374; RV64IZFINXZDINX-NEXT: ret 375; 376; RV32I-LABEL: fabs_d: 377; RV32I: # %bb.0: 378; RV32I-NEXT: addi sp, sp, -16 379; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 380; RV32I-NEXT: call __adddf3 381; RV32I-NEXT: mv a3, a1 382; RV32I-NEXT: slli a1, a1, 1 383; RV32I-NEXT: srli a1, a1, 1 384; RV32I-NEXT: mv a2, a0 385; RV32I-NEXT: call __adddf3 386; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 387; RV32I-NEXT: addi sp, sp, 16 388; RV32I-NEXT: ret 389; 390; RV64I-LABEL: fabs_d: 391; RV64I: # %bb.0: 392; RV64I-NEXT: addi sp, sp, -16 393; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 394; RV64I-NEXT: call __adddf3 395; RV64I-NEXT: mv a1, a0 396; RV64I-NEXT: slli a0, a0, 1 397; RV64I-NEXT: srli a0, a0, 1 398; RV64I-NEXT: call __adddf3 399; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 400; RV64I-NEXT: addi sp, sp, 16 401; RV64I-NEXT: ret 402 %1 = fadd double %a, %b 403 %2 = call double @llvm.fabs.f64(double %1) 404 %3 = fadd double %2, %1 405 ret double %3 406} 407 408declare double @llvm.minnum.f64(double, double) 409 410define double @fmin_d(double %a, double %b) nounwind { 411; CHECKIFD-LABEL: fmin_d: 412; CHECKIFD: # %bb.0: 413; CHECKIFD-NEXT: fmin.d fa0, fa0, fa1 414; CHECKIFD-NEXT: ret 415; 416; RV32IZFINXZDINX-LABEL: fmin_d: 417; RV32IZFINXZDINX: # %bb.0: 418; RV32IZFINXZDINX-NEXT: fmin.d a0, a0, a2 419; RV32IZFINXZDINX-NEXT: ret 420; 421; RV64IZFINXZDINX-LABEL: fmin_d: 422; RV64IZFINXZDINX: # %bb.0: 423; RV64IZFINXZDINX-NEXT: fmin.d a0, a0, a1 424; RV64IZFINXZDINX-NEXT: ret 425; 426; RV32I-LABEL: fmin_d: 427; RV32I: # %bb.0: 428; RV32I-NEXT: addi sp, sp, -16 429; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 430; RV32I-NEXT: call fmin 431; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 432; RV32I-NEXT: addi sp, sp, 16 433; RV32I-NEXT: ret 434; 435; RV64I-LABEL: fmin_d: 436; RV64I: # %bb.0: 437; RV64I-NEXT: addi sp, sp, -16 438; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 439; RV64I-NEXT: call fmin 440; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 441; RV64I-NEXT: addi sp, sp, 16 442; RV64I-NEXT: ret 443 %1 = call double @llvm.minnum.f64(double %a, double %b) 444 ret double %1 445} 446 447declare double @llvm.maxnum.f64(double, double) 448 449define double @fmax_d(double %a, double %b) nounwind { 450; CHECKIFD-LABEL: fmax_d: 451; CHECKIFD: # %bb.0: 452; CHECKIFD-NEXT: fmax.d fa0, fa0, fa1 453; CHECKIFD-NEXT: ret 454; 455; RV32IZFINXZDINX-LABEL: fmax_d: 456; RV32IZFINXZDINX: # %bb.0: 457; RV32IZFINXZDINX-NEXT: fmax.d a0, a0, a2 458; RV32IZFINXZDINX-NEXT: ret 459; 460; RV64IZFINXZDINX-LABEL: fmax_d: 461; RV64IZFINXZDINX: # %bb.0: 462; RV64IZFINXZDINX-NEXT: fmax.d a0, a0, a1 463; RV64IZFINXZDINX-NEXT: ret 464; 465; RV32I-LABEL: fmax_d: 466; RV32I: # %bb.0: 467; RV32I-NEXT: addi sp, sp, -16 468; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 469; RV32I-NEXT: call fmax 470; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 471; RV32I-NEXT: addi sp, sp, 16 472; RV32I-NEXT: ret 473; 474; RV64I-LABEL: fmax_d: 475; RV64I: # %bb.0: 476; RV64I-NEXT: addi sp, sp, -16 477; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 478; RV64I-NEXT: call fmax 479; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 480; RV64I-NEXT: addi sp, sp, 16 481; RV64I-NEXT: ret 482 %1 = call double @llvm.maxnum.f64(double %a, double %b) 483 ret double %1 484} 485 486declare double @llvm.fma.f64(double, double, double) 487 488define double @fmadd_d(double %a, double %b, double %c) nounwind { 489; CHECKIFD-LABEL: fmadd_d: 490; CHECKIFD: # %bb.0: 491; CHECKIFD-NEXT: fmadd.d fa0, fa0, fa1, fa2 492; CHECKIFD-NEXT: ret 493; 494; RV32IZFINXZDINX-LABEL: fmadd_d: 495; RV32IZFINXZDINX: # %bb.0: 496; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a4 497; RV32IZFINXZDINX-NEXT: ret 498; 499; RV64IZFINXZDINX-LABEL: fmadd_d: 500; RV64IZFINXZDINX: # %bb.0: 501; RV64IZFINXZDINX-NEXT: fmadd.d a0, a0, a1, a2 502; RV64IZFINXZDINX-NEXT: ret 503; 504; RV32I-LABEL: fmadd_d: 505; RV32I: # %bb.0: 506; RV32I-NEXT: addi sp, sp, -16 507; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 508; RV32I-NEXT: call fma 509; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 510; RV32I-NEXT: addi sp, sp, 16 511; RV32I-NEXT: ret 512; 513; RV64I-LABEL: fmadd_d: 514; RV64I: # %bb.0: 515; RV64I-NEXT: addi sp, sp, -16 516; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 517; RV64I-NEXT: call fma 518; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 519; RV64I-NEXT: addi sp, sp, 16 520; RV64I-NEXT: ret 521 %1 = call double @llvm.fma.f64(double %a, double %b, double %c) 522 ret double %1 523} 524 525define double @fmsub_d(double %a, double %b, double %c) nounwind { 526; RV32IFD-LABEL: fmsub_d: 527; RV32IFD: # %bb.0: 528; RV32IFD-NEXT: fcvt.d.w fa5, zero 529; RV32IFD-NEXT: fadd.d fa5, fa2, fa5 530; RV32IFD-NEXT: fmsub.d fa0, fa0, fa1, fa5 531; RV32IFD-NEXT: ret 532; 533; RV64IFD-LABEL: fmsub_d: 534; RV64IFD: # %bb.0: 535; RV64IFD-NEXT: fmv.d.x fa5, zero 536; RV64IFD-NEXT: fadd.d fa5, fa2, fa5 537; RV64IFD-NEXT: fmsub.d fa0, fa0, fa1, fa5 538; RV64IFD-NEXT: ret 539; 540; RV32IZFINXZDINX-LABEL: fmsub_d: 541; RV32IZFINXZDINX: # %bb.0: 542; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero 543; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, a6 544; RV32IZFINXZDINX-NEXT: fmsub.d a0, a0, a2, a4 545; RV32IZFINXZDINX-NEXT: ret 546; 547; RV64IZFINXZDINX-LABEL: fmsub_d: 548; RV64IZFINXZDINX: # %bb.0: 549; RV64IZFINXZDINX-NEXT: fadd.d a2, a2, zero 550; RV64IZFINXZDINX-NEXT: fmsub.d a0, a0, a1, a2 551; RV64IZFINXZDINX-NEXT: ret 552; 553; RV32I-LABEL: fmsub_d: 554; RV32I: # %bb.0: 555; RV32I-NEXT: addi sp, sp, -32 556; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 557; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 558; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 559; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 560; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 561; RV32I-NEXT: mv s0, a3 562; RV32I-NEXT: mv s1, a2 563; RV32I-NEXT: mv s2, a1 564; RV32I-NEXT: mv s3, a0 565; RV32I-NEXT: mv a0, a4 566; RV32I-NEXT: mv a1, a5 567; RV32I-NEXT: li a2, 0 568; RV32I-NEXT: li a3, 0 569; RV32I-NEXT: call __adddf3 570; RV32I-NEXT: mv a4, a0 571; RV32I-NEXT: lui a5, 524288 572; RV32I-NEXT: xor a5, a1, a5 573; RV32I-NEXT: mv a0, s3 574; RV32I-NEXT: mv a1, s2 575; RV32I-NEXT: mv a2, s1 576; RV32I-NEXT: mv a3, s0 577; RV32I-NEXT: call fma 578; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 579; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 580; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 581; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 582; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 583; RV32I-NEXT: addi sp, sp, 32 584; RV32I-NEXT: ret 585; 586; RV64I-LABEL: fmsub_d: 587; RV64I: # %bb.0: 588; RV64I-NEXT: addi sp, sp, -32 589; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 590; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 591; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 592; RV64I-NEXT: mv s0, a1 593; RV64I-NEXT: mv s1, a0 594; RV64I-NEXT: mv a0, a2 595; RV64I-NEXT: li a1, 0 596; RV64I-NEXT: call __adddf3 597; RV64I-NEXT: li a1, -1 598; RV64I-NEXT: slli a1, a1, 63 599; RV64I-NEXT: xor a2, a0, a1 600; RV64I-NEXT: mv a0, s1 601; RV64I-NEXT: mv a1, s0 602; RV64I-NEXT: call fma 603; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 604; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 605; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 606; RV64I-NEXT: addi sp, sp, 32 607; RV64I-NEXT: ret 608 %c_ = fadd double 0.0, %c ; avoid negation using xor 609 %negc = fsub double -0.0, %c_ 610 %1 = call double @llvm.fma.f64(double %a, double %b, double %negc) 611 ret double %1 612} 613 614define double @fnmadd_d(double %a, double %b, double %c) nounwind { 615; RV32IFD-LABEL: fnmadd_d: 616; RV32IFD: # %bb.0: 617; RV32IFD-NEXT: fcvt.d.w fa5, zero 618; RV32IFD-NEXT: fadd.d fa4, fa0, fa5 619; RV32IFD-NEXT: fadd.d fa5, fa2, fa5 620; RV32IFD-NEXT: fnmadd.d fa0, fa4, fa1, fa5 621; RV32IFD-NEXT: ret 622; 623; RV64IFD-LABEL: fnmadd_d: 624; RV64IFD: # %bb.0: 625; RV64IFD-NEXT: fmv.d.x fa5, zero 626; RV64IFD-NEXT: fadd.d fa4, fa0, fa5 627; RV64IFD-NEXT: fadd.d fa5, fa2, fa5 628; RV64IFD-NEXT: fnmadd.d fa0, fa4, fa1, fa5 629; RV64IFD-NEXT: ret 630; 631; RV32IZFINXZDINX-LABEL: fnmadd_d: 632; RV32IZFINXZDINX: # %bb.0: 633; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero 634; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a6 635; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, a6 636; RV32IZFINXZDINX-NEXT: fnmadd.d a0, a0, a2, a4 637; RV32IZFINXZDINX-NEXT: ret 638; 639; RV64IZFINXZDINX-LABEL: fnmadd_d: 640; RV64IZFINXZDINX: # %bb.0: 641; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, zero 642; RV64IZFINXZDINX-NEXT: fadd.d a2, a2, zero 643; RV64IZFINXZDINX-NEXT: fnmadd.d a0, a0, a1, a2 644; RV64IZFINXZDINX-NEXT: ret 645; 646; RV32I-LABEL: fnmadd_d: 647; RV32I: # %bb.0: 648; RV32I-NEXT: addi sp, sp, -32 649; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 650; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 651; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 652; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 653; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 654; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill 655; RV32I-NEXT: sw s5, 4(sp) # 4-byte Folded Spill 656; RV32I-NEXT: mv s0, a5 657; RV32I-NEXT: mv s1, a4 658; RV32I-NEXT: mv s2, a3 659; RV32I-NEXT: mv s3, a2 660; RV32I-NEXT: li a2, 0 661; RV32I-NEXT: li a3, 0 662; RV32I-NEXT: call __adddf3 663; RV32I-NEXT: mv s4, a0 664; RV32I-NEXT: mv s5, a1 665; RV32I-NEXT: mv a0, s1 666; RV32I-NEXT: mv a1, s0 667; RV32I-NEXT: li a2, 0 668; RV32I-NEXT: li a3, 0 669; RV32I-NEXT: call __adddf3 670; RV32I-NEXT: mv a4, a0 671; RV32I-NEXT: lui a5, 524288 672; RV32I-NEXT: xor a2, s5, a5 673; RV32I-NEXT: xor a5, a1, a5 674; RV32I-NEXT: mv a0, s4 675; RV32I-NEXT: mv a1, a2 676; RV32I-NEXT: mv a2, s3 677; RV32I-NEXT: mv a3, s2 678; RV32I-NEXT: call fma 679; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 680; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 681; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 682; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 683; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 684; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload 685; RV32I-NEXT: lw s5, 4(sp) # 4-byte Folded Reload 686; RV32I-NEXT: addi sp, sp, 32 687; RV32I-NEXT: ret 688; 689; RV64I-LABEL: fnmadd_d: 690; RV64I: # %bb.0: 691; RV64I-NEXT: addi sp, sp, -32 692; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 693; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 694; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 695; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 696; RV64I-NEXT: mv s0, a2 697; RV64I-NEXT: mv s1, a1 698; RV64I-NEXT: li a1, 0 699; RV64I-NEXT: call __adddf3 700; RV64I-NEXT: mv s2, a0 701; RV64I-NEXT: mv a0, s0 702; RV64I-NEXT: li a1, 0 703; RV64I-NEXT: call __adddf3 704; RV64I-NEXT: li a1, -1 705; RV64I-NEXT: slli a2, a1, 63 706; RV64I-NEXT: xor a1, s2, a2 707; RV64I-NEXT: xor a2, a0, a2 708; RV64I-NEXT: mv a0, a1 709; RV64I-NEXT: mv a1, s1 710; RV64I-NEXT: call fma 711; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 712; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 713; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 714; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 715; RV64I-NEXT: addi sp, sp, 32 716; RV64I-NEXT: ret 717 %a_ = fadd double 0.0, %a 718 %c_ = fadd double 0.0, %c 719 %nega = fsub double -0.0, %a_ 720 %negc = fsub double -0.0, %c_ 721 %1 = call double @llvm.fma.f64(double %nega, double %b, double %negc) 722 ret double %1 723} 724 725define double @fnmadd_d_2(double %a, double %b, double %c) nounwind { 726; RV32IFD-LABEL: fnmadd_d_2: 727; RV32IFD: # %bb.0: 728; RV32IFD-NEXT: fcvt.d.w fa5, zero 729; RV32IFD-NEXT: fadd.d fa4, fa1, fa5 730; RV32IFD-NEXT: fadd.d fa5, fa2, fa5 731; RV32IFD-NEXT: fnmadd.d fa0, fa4, fa0, fa5 732; RV32IFD-NEXT: ret 733; 734; RV64IFD-LABEL: fnmadd_d_2: 735; RV64IFD: # %bb.0: 736; RV64IFD-NEXT: fmv.d.x fa5, zero 737; RV64IFD-NEXT: fadd.d fa4, fa1, fa5 738; RV64IFD-NEXT: fadd.d fa5, fa2, fa5 739; RV64IFD-NEXT: fnmadd.d fa0, fa4, fa0, fa5 740; RV64IFD-NEXT: ret 741; 742; RV32IZFINXZDINX-LABEL: fnmadd_d_2: 743; RV32IZFINXZDINX: # %bb.0: 744; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero 745; RV32IZFINXZDINX-NEXT: fadd.d a2, a2, a6 746; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, a6 747; RV32IZFINXZDINX-NEXT: fnmadd.d a0, a2, a0, a4 748; RV32IZFINXZDINX-NEXT: ret 749; 750; RV64IZFINXZDINX-LABEL: fnmadd_d_2: 751; RV64IZFINXZDINX: # %bb.0: 752; RV64IZFINXZDINX-NEXT: fadd.d a1, a1, zero 753; RV64IZFINXZDINX-NEXT: fadd.d a2, a2, zero 754; RV64IZFINXZDINX-NEXT: fnmadd.d a0, a1, a0, a2 755; RV64IZFINXZDINX-NEXT: ret 756; 757; RV32I-LABEL: fnmadd_d_2: 758; RV32I: # %bb.0: 759; RV32I-NEXT: addi sp, sp, -32 760; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 761; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 762; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 763; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 764; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 765; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill 766; RV32I-NEXT: sw s5, 4(sp) # 4-byte Folded Spill 767; RV32I-NEXT: mv s0, a5 768; RV32I-NEXT: mv s1, a4 769; RV32I-NEXT: mv s2, a1 770; RV32I-NEXT: mv s3, a0 771; RV32I-NEXT: mv a0, a2 772; RV32I-NEXT: mv a1, a3 773; RV32I-NEXT: li a2, 0 774; RV32I-NEXT: li a3, 0 775; RV32I-NEXT: call __adddf3 776; RV32I-NEXT: mv s4, a0 777; RV32I-NEXT: mv s5, a1 778; RV32I-NEXT: mv a0, s1 779; RV32I-NEXT: mv a1, s0 780; RV32I-NEXT: li a2, 0 781; RV32I-NEXT: li a3, 0 782; RV32I-NEXT: call __adddf3 783; RV32I-NEXT: mv a4, a0 784; RV32I-NEXT: lui a5, 524288 785; RV32I-NEXT: xor a3, s5, a5 786; RV32I-NEXT: xor a5, a1, a5 787; RV32I-NEXT: mv a0, s3 788; RV32I-NEXT: mv a1, s2 789; RV32I-NEXT: mv a2, s4 790; RV32I-NEXT: call fma 791; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 792; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 793; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 794; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 795; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 796; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload 797; RV32I-NEXT: lw s5, 4(sp) # 4-byte Folded Reload 798; RV32I-NEXT: addi sp, sp, 32 799; RV32I-NEXT: ret 800; 801; RV64I-LABEL: fnmadd_d_2: 802; RV64I: # %bb.0: 803; RV64I-NEXT: addi sp, sp, -32 804; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 805; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 806; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 807; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 808; RV64I-NEXT: mv s0, a2 809; RV64I-NEXT: mv s1, a0 810; RV64I-NEXT: mv a0, a1 811; RV64I-NEXT: li a1, 0 812; RV64I-NEXT: call __adddf3 813; RV64I-NEXT: mv s2, a0 814; RV64I-NEXT: mv a0, s0 815; RV64I-NEXT: li a1, 0 816; RV64I-NEXT: call __adddf3 817; RV64I-NEXT: li a1, -1 818; RV64I-NEXT: slli a2, a1, 63 819; RV64I-NEXT: xor a1, s2, a2 820; RV64I-NEXT: xor a2, a0, a2 821; RV64I-NEXT: mv a0, s1 822; RV64I-NEXT: call fma 823; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 824; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 825; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 826; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 827; RV64I-NEXT: addi sp, sp, 32 828; RV64I-NEXT: ret 829 %b_ = fadd double 0.0, %b 830 %c_ = fadd double 0.0, %c 831 %negb = fsub double -0.0, %b_ 832 %negc = fsub double -0.0, %c_ 833 %1 = call double @llvm.fma.f64(double %a, double %negb, double %negc) 834 ret double %1 835} 836 837define double @fnmadd_d_3(double %a, double %b, double %c) nounwind { 838; CHECKIFD-LABEL: fnmadd_d_3: 839; CHECKIFD: # %bb.0: 840; CHECKIFD-NEXT: fmadd.d fa5, fa0, fa1, fa2 841; CHECKIFD-NEXT: fneg.d fa0, fa5 842; CHECKIFD-NEXT: ret 843; 844; RV32IZFINXZDINX-LABEL: fnmadd_d_3: 845; RV32IZFINXZDINX: # %bb.0: 846; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a4 847; RV32IZFINXZDINX-NEXT: fneg.d a0, a0 848; RV32IZFINXZDINX-NEXT: ret 849; 850; RV64IZFINXZDINX-LABEL: fnmadd_d_3: 851; RV64IZFINXZDINX: # %bb.0: 852; RV64IZFINXZDINX-NEXT: fmadd.d a0, a0, a1, a2 853; RV64IZFINXZDINX-NEXT: fneg.d a0, a0 854; RV64IZFINXZDINX-NEXT: ret 855; 856; RV32I-LABEL: fnmadd_d_3: 857; RV32I: # %bb.0: 858; RV32I-NEXT: addi sp, sp, -16 859; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 860; RV32I-NEXT: call fma 861; RV32I-NEXT: lui a2, 524288 862; RV32I-NEXT: xor a1, a1, a2 863; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 864; RV32I-NEXT: addi sp, sp, 16 865; RV32I-NEXT: ret 866; 867; RV64I-LABEL: fnmadd_d_3: 868; RV64I: # %bb.0: 869; RV64I-NEXT: addi sp, sp, -16 870; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 871; RV64I-NEXT: call fma 872; RV64I-NEXT: li a1, -1 873; RV64I-NEXT: slli a1, a1, 63 874; RV64I-NEXT: xor a0, a0, a1 875; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 876; RV64I-NEXT: addi sp, sp, 16 877; RV64I-NEXT: ret 878 %1 = call double @llvm.fma.f64(double %a, double %b, double %c) 879 %neg = fneg double %1 880 ret double %neg 881} 882 883 884define double @fnmadd_nsz(double %a, double %b, double %c) nounwind { 885; CHECKIFD-LABEL: fnmadd_nsz: 886; CHECKIFD: # %bb.0: 887; CHECKIFD-NEXT: fnmadd.d fa0, fa0, fa1, fa2 888; CHECKIFD-NEXT: ret 889; 890; RV32IZFINXZDINX-LABEL: fnmadd_nsz: 891; RV32IZFINXZDINX: # %bb.0: 892; RV32IZFINXZDINX-NEXT: fnmadd.d a0, a0, a2, a4 893; RV32IZFINXZDINX-NEXT: ret 894; 895; RV64IZFINXZDINX-LABEL: fnmadd_nsz: 896; RV64IZFINXZDINX: # %bb.0: 897; RV64IZFINXZDINX-NEXT: fnmadd.d a0, a0, a1, a2 898; RV64IZFINXZDINX-NEXT: ret 899; 900; RV32I-LABEL: fnmadd_nsz: 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: call fma 905; RV32I-NEXT: lui a2, 524288 906; RV32I-NEXT: xor a1, a1, a2 907; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 908; RV32I-NEXT: addi sp, sp, 16 909; RV32I-NEXT: ret 910; 911; RV64I-LABEL: fnmadd_nsz: 912; RV64I: # %bb.0: 913; RV64I-NEXT: addi sp, sp, -16 914; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 915; RV64I-NEXT: call fma 916; RV64I-NEXT: li a1, -1 917; RV64I-NEXT: slli a1, a1, 63 918; RV64I-NEXT: xor a0, a0, a1 919; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 920; RV64I-NEXT: addi sp, sp, 16 921; RV64I-NEXT: ret 922 %1 = call nsz double @llvm.fma.f64(double %a, double %b, double %c) 923 %neg = fneg nsz double %1 924 ret double %neg 925} 926 927define double @fnmsub_d(double %a, double %b, double %c) nounwind { 928; RV32IFD-LABEL: fnmsub_d: 929; RV32IFD: # %bb.0: 930; RV32IFD-NEXT: fcvt.d.w fa5, zero 931; RV32IFD-NEXT: fadd.d fa5, fa0, fa5 932; RV32IFD-NEXT: fnmsub.d fa0, fa5, fa1, fa2 933; RV32IFD-NEXT: ret 934; 935; RV64IFD-LABEL: fnmsub_d: 936; RV64IFD: # %bb.0: 937; RV64IFD-NEXT: fmv.d.x fa5, zero 938; RV64IFD-NEXT: fadd.d fa5, fa0, fa5 939; RV64IFD-NEXT: fnmsub.d fa0, fa5, fa1, fa2 940; RV64IFD-NEXT: ret 941; 942; RV32IZFINXZDINX-LABEL: fnmsub_d: 943; RV32IZFINXZDINX: # %bb.0: 944; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero 945; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a6 946; RV32IZFINXZDINX-NEXT: fnmsub.d a0, a0, a2, a4 947; RV32IZFINXZDINX-NEXT: ret 948; 949; RV64IZFINXZDINX-LABEL: fnmsub_d: 950; RV64IZFINXZDINX: # %bb.0: 951; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, zero 952; RV64IZFINXZDINX-NEXT: fnmsub.d a0, a0, a1, a2 953; RV64IZFINXZDINX-NEXT: ret 954; 955; RV32I-LABEL: fnmsub_d: 956; RV32I: # %bb.0: 957; RV32I-NEXT: addi sp, sp, -32 958; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 959; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 960; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 961; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 962; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 963; RV32I-NEXT: mv s0, a5 964; RV32I-NEXT: mv s1, a4 965; RV32I-NEXT: mv s2, a3 966; RV32I-NEXT: mv s3, a2 967; RV32I-NEXT: li a2, 0 968; RV32I-NEXT: li a3, 0 969; RV32I-NEXT: call __adddf3 970; RV32I-NEXT: lui a2, 524288 971; RV32I-NEXT: xor a1, a1, a2 972; RV32I-NEXT: mv a2, s3 973; RV32I-NEXT: mv a3, s2 974; RV32I-NEXT: mv a4, s1 975; RV32I-NEXT: mv a5, s0 976; RV32I-NEXT: call fma 977; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 978; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 979; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 980; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 981; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 982; RV32I-NEXT: addi sp, sp, 32 983; RV32I-NEXT: ret 984; 985; RV64I-LABEL: fnmsub_d: 986; RV64I: # %bb.0: 987; RV64I-NEXT: addi sp, sp, -32 988; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 989; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 990; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 991; RV64I-NEXT: mv s0, a2 992; RV64I-NEXT: mv s1, a1 993; RV64I-NEXT: li a1, 0 994; RV64I-NEXT: call __adddf3 995; RV64I-NEXT: li a1, -1 996; RV64I-NEXT: slli a1, a1, 63 997; RV64I-NEXT: xor a0, a0, a1 998; RV64I-NEXT: mv a1, s1 999; RV64I-NEXT: mv a2, s0 1000; RV64I-NEXT: call fma 1001; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 1002; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 1003; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 1004; RV64I-NEXT: addi sp, sp, 32 1005; RV64I-NEXT: ret 1006 %a_ = fadd double 0.0, %a 1007 %nega = fsub double -0.0, %a_ 1008 %1 = call double @llvm.fma.f64(double %nega, double %b, double %c) 1009 ret double %1 1010} 1011 1012define double @fnmsub_d_2(double %a, double %b, double %c) nounwind { 1013; RV32IFD-LABEL: fnmsub_d_2: 1014; RV32IFD: # %bb.0: 1015; RV32IFD-NEXT: fcvt.d.w fa5, zero 1016; RV32IFD-NEXT: fadd.d fa5, fa1, fa5 1017; RV32IFD-NEXT: fnmsub.d fa0, fa5, fa0, fa2 1018; RV32IFD-NEXT: ret 1019; 1020; RV64IFD-LABEL: fnmsub_d_2: 1021; RV64IFD: # %bb.0: 1022; RV64IFD-NEXT: fmv.d.x fa5, zero 1023; RV64IFD-NEXT: fadd.d fa5, fa1, fa5 1024; RV64IFD-NEXT: fnmsub.d fa0, fa5, fa0, fa2 1025; RV64IFD-NEXT: ret 1026; 1027; RV32IZFINXZDINX-LABEL: fnmsub_d_2: 1028; RV32IZFINXZDINX: # %bb.0: 1029; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero 1030; RV32IZFINXZDINX-NEXT: fadd.d a2, a2, a6 1031; RV32IZFINXZDINX-NEXT: fnmsub.d a0, a2, a0, a4 1032; RV32IZFINXZDINX-NEXT: ret 1033; 1034; RV64IZFINXZDINX-LABEL: fnmsub_d_2: 1035; RV64IZFINXZDINX: # %bb.0: 1036; RV64IZFINXZDINX-NEXT: fadd.d a1, a1, zero 1037; RV64IZFINXZDINX-NEXT: fnmsub.d a0, a1, a0, a2 1038; RV64IZFINXZDINX-NEXT: ret 1039; 1040; RV32I-LABEL: fnmsub_d_2: 1041; RV32I: # %bb.0: 1042; RV32I-NEXT: addi sp, sp, -32 1043; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 1044; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 1045; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 1046; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 1047; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 1048; RV32I-NEXT: mv s0, a5 1049; RV32I-NEXT: mv s1, a4 1050; RV32I-NEXT: mv s2, a1 1051; RV32I-NEXT: mv s3, a0 1052; RV32I-NEXT: mv a0, a2 1053; RV32I-NEXT: mv a1, a3 1054; RV32I-NEXT: li a2, 0 1055; RV32I-NEXT: li a3, 0 1056; RV32I-NEXT: call __adddf3 1057; RV32I-NEXT: mv a2, a0 1058; RV32I-NEXT: lui a3, 524288 1059; RV32I-NEXT: xor a3, a1, a3 1060; RV32I-NEXT: mv a0, s3 1061; RV32I-NEXT: mv a1, s2 1062; RV32I-NEXT: mv a4, s1 1063; RV32I-NEXT: mv a5, s0 1064; RV32I-NEXT: call fma 1065; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 1066; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 1067; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 1068; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 1069; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 1070; RV32I-NEXT: addi sp, sp, 32 1071; RV32I-NEXT: ret 1072; 1073; RV64I-LABEL: fnmsub_d_2: 1074; RV64I: # %bb.0: 1075; RV64I-NEXT: addi sp, sp, -32 1076; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 1077; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 1078; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 1079; RV64I-NEXT: mv s0, a2 1080; RV64I-NEXT: mv s1, a0 1081; RV64I-NEXT: mv a0, a1 1082; RV64I-NEXT: li a1, 0 1083; RV64I-NEXT: call __adddf3 1084; RV64I-NEXT: li a1, -1 1085; RV64I-NEXT: slli a1, a1, 63 1086; RV64I-NEXT: xor a1, a0, a1 1087; RV64I-NEXT: mv a0, s1 1088; RV64I-NEXT: mv a2, s0 1089; RV64I-NEXT: call fma 1090; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 1091; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 1092; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 1093; RV64I-NEXT: addi sp, sp, 32 1094; RV64I-NEXT: ret 1095 %b_ = fadd double 0.0, %b 1096 %negb = fsub double -0.0, %b_ 1097 %1 = call double @llvm.fma.f64(double %a, double %negb, double %c) 1098 ret double %1 1099} 1100 1101define double @fmadd_d_contract(double %a, double %b, double %c) nounwind { 1102; CHECKIFD-LABEL: fmadd_d_contract: 1103; CHECKIFD: # %bb.0: 1104; CHECKIFD-NEXT: fmadd.d fa0, fa0, fa1, fa2 1105; CHECKIFD-NEXT: ret 1106; 1107; RV32IZFINXZDINX-LABEL: fmadd_d_contract: 1108; RV32IZFINXZDINX: # %bb.0: 1109; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a4 1110; RV32IZFINXZDINX-NEXT: ret 1111; 1112; RV64IZFINXZDINX-LABEL: fmadd_d_contract: 1113; RV64IZFINXZDINX: # %bb.0: 1114; RV64IZFINXZDINX-NEXT: fmadd.d a0, a0, a1, a2 1115; RV64IZFINXZDINX-NEXT: ret 1116; 1117; RV32I-LABEL: fmadd_d_contract: 1118; RV32I: # %bb.0: 1119; RV32I-NEXT: addi sp, sp, -16 1120; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 1121; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 1122; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 1123; RV32I-NEXT: mv s0, a5 1124; RV32I-NEXT: mv s1, a4 1125; RV32I-NEXT: call __muldf3 1126; RV32I-NEXT: mv a2, s1 1127; RV32I-NEXT: mv a3, s0 1128; RV32I-NEXT: call __adddf3 1129; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 1130; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 1131; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 1132; RV32I-NEXT: addi sp, sp, 16 1133; RV32I-NEXT: ret 1134; 1135; RV64I-LABEL: fmadd_d_contract: 1136; RV64I: # %bb.0: 1137; RV64I-NEXT: addi sp, sp, -16 1138; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 1139; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill 1140; RV64I-NEXT: mv s0, a2 1141; RV64I-NEXT: call __muldf3 1142; RV64I-NEXT: mv a1, s0 1143; RV64I-NEXT: call __adddf3 1144; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 1145; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload 1146; RV64I-NEXT: addi sp, sp, 16 1147; RV64I-NEXT: ret 1148 %1 = fmul contract double %a, %b 1149 %2 = fadd contract double %1, %c 1150 ret double %2 1151} 1152 1153define double @fmsub_d_contract(double %a, double %b, double %c) nounwind { 1154; RV32IFD-LABEL: fmsub_d_contract: 1155; RV32IFD: # %bb.0: 1156; RV32IFD-NEXT: fcvt.d.w fa5, zero 1157; RV32IFD-NEXT: fadd.d fa5, fa2, fa5 1158; RV32IFD-NEXT: fmsub.d fa0, fa0, fa1, fa5 1159; RV32IFD-NEXT: ret 1160; 1161; RV64IFD-LABEL: fmsub_d_contract: 1162; RV64IFD: # %bb.0: 1163; RV64IFD-NEXT: fmv.d.x fa5, zero 1164; RV64IFD-NEXT: fadd.d fa5, fa2, fa5 1165; RV64IFD-NEXT: fmsub.d fa0, fa0, fa1, fa5 1166; RV64IFD-NEXT: ret 1167; 1168; RV32IZFINXZDINX-LABEL: fmsub_d_contract: 1169; RV32IZFINXZDINX: # %bb.0: 1170; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero 1171; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, a6 1172; RV32IZFINXZDINX-NEXT: fmsub.d a0, a0, a2, a4 1173; RV32IZFINXZDINX-NEXT: ret 1174; 1175; RV64IZFINXZDINX-LABEL: fmsub_d_contract: 1176; RV64IZFINXZDINX: # %bb.0: 1177; RV64IZFINXZDINX-NEXT: fadd.d a2, a2, zero 1178; RV64IZFINXZDINX-NEXT: fmsub.d a0, a0, a1, a2 1179; RV64IZFINXZDINX-NEXT: ret 1180; 1181; RV32I-LABEL: fmsub_d_contract: 1182; RV32I: # %bb.0: 1183; RV32I-NEXT: addi sp, sp, -32 1184; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 1185; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 1186; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 1187; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 1188; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 1189; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill 1190; RV32I-NEXT: sw s5, 4(sp) # 4-byte Folded Spill 1191; RV32I-NEXT: mv s0, a3 1192; RV32I-NEXT: mv s1, a2 1193; RV32I-NEXT: mv s2, a1 1194; RV32I-NEXT: mv s3, a0 1195; RV32I-NEXT: mv a0, a4 1196; RV32I-NEXT: mv a1, a5 1197; RV32I-NEXT: li a2, 0 1198; RV32I-NEXT: li a3, 0 1199; RV32I-NEXT: call __adddf3 1200; RV32I-NEXT: mv s4, a0 1201; RV32I-NEXT: mv s5, a1 1202; RV32I-NEXT: mv a0, s3 1203; RV32I-NEXT: mv a1, s2 1204; RV32I-NEXT: mv a2, s1 1205; RV32I-NEXT: mv a3, s0 1206; RV32I-NEXT: call __muldf3 1207; RV32I-NEXT: mv a2, s4 1208; RV32I-NEXT: mv a3, s5 1209; RV32I-NEXT: call __subdf3 1210; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 1211; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 1212; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 1213; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 1214; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 1215; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload 1216; RV32I-NEXT: lw s5, 4(sp) # 4-byte Folded Reload 1217; RV32I-NEXT: addi sp, sp, 32 1218; RV32I-NEXT: ret 1219; 1220; RV64I-LABEL: fmsub_d_contract: 1221; RV64I: # %bb.0: 1222; RV64I-NEXT: addi sp, sp, -32 1223; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 1224; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 1225; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 1226; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 1227; RV64I-NEXT: mv s0, a1 1228; RV64I-NEXT: mv s1, a0 1229; RV64I-NEXT: mv a0, a2 1230; RV64I-NEXT: li a1, 0 1231; RV64I-NEXT: call __adddf3 1232; RV64I-NEXT: mv s2, a0 1233; RV64I-NEXT: mv a0, s1 1234; RV64I-NEXT: mv a1, s0 1235; RV64I-NEXT: call __muldf3 1236; RV64I-NEXT: mv a1, s2 1237; RV64I-NEXT: call __subdf3 1238; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 1239; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 1240; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 1241; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 1242; RV64I-NEXT: addi sp, sp, 32 1243; RV64I-NEXT: ret 1244 %c_ = fadd double 0.0, %c ; avoid negation using xor 1245 %1 = fmul contract double %a, %b 1246 %2 = fsub contract double %1, %c_ 1247 ret double %2 1248} 1249 1250define double @fnmadd_d_contract(double %a, double %b, double %c) nounwind { 1251; RV32IFD-LABEL: fnmadd_d_contract: 1252; RV32IFD: # %bb.0: 1253; RV32IFD-NEXT: fcvt.d.w fa5, zero 1254; RV32IFD-NEXT: fadd.d fa4, fa0, fa5 1255; RV32IFD-NEXT: fadd.d fa3, fa1, fa5 1256; RV32IFD-NEXT: fadd.d fa5, fa2, fa5 1257; RV32IFD-NEXT: fnmadd.d fa0, fa4, fa3, fa5 1258; RV32IFD-NEXT: ret 1259; 1260; RV64IFD-LABEL: fnmadd_d_contract: 1261; RV64IFD: # %bb.0: 1262; RV64IFD-NEXT: fmv.d.x fa5, zero 1263; RV64IFD-NEXT: fadd.d fa4, fa0, fa5 1264; RV64IFD-NEXT: fadd.d fa3, fa1, fa5 1265; RV64IFD-NEXT: fadd.d fa5, fa2, fa5 1266; RV64IFD-NEXT: fnmadd.d fa0, fa4, fa3, fa5 1267; RV64IFD-NEXT: ret 1268; 1269; RV32IZFINXZDINX-LABEL: fnmadd_d_contract: 1270; RV32IZFINXZDINX: # %bb.0: 1271; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero 1272; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a6 1273; RV32IZFINXZDINX-NEXT: fadd.d a2, a2, a6 1274; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, a6 1275; RV32IZFINXZDINX-NEXT: fnmadd.d a0, a0, a2, a4 1276; RV32IZFINXZDINX-NEXT: ret 1277; 1278; RV64IZFINXZDINX-LABEL: fnmadd_d_contract: 1279; RV64IZFINXZDINX: # %bb.0: 1280; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, zero 1281; RV64IZFINXZDINX-NEXT: fadd.d a1, a1, zero 1282; RV64IZFINXZDINX-NEXT: fadd.d a2, a2, zero 1283; RV64IZFINXZDINX-NEXT: fnmadd.d a0, a0, a1, a2 1284; RV64IZFINXZDINX-NEXT: ret 1285; 1286; RV32I-LABEL: fnmadd_d_contract: 1287; RV32I: # %bb.0: 1288; RV32I-NEXT: addi sp, sp, -32 1289; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 1290; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 1291; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 1292; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 1293; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 1294; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill 1295; RV32I-NEXT: sw s5, 4(sp) # 4-byte Folded Spill 1296; RV32I-NEXT: mv s0, a5 1297; RV32I-NEXT: mv s1, a4 1298; RV32I-NEXT: mv s2, a3 1299; RV32I-NEXT: mv s3, a2 1300; RV32I-NEXT: li a2, 0 1301; RV32I-NEXT: li a3, 0 1302; RV32I-NEXT: call __adddf3 1303; RV32I-NEXT: mv s4, a0 1304; RV32I-NEXT: mv s5, a1 1305; RV32I-NEXT: mv a0, s3 1306; RV32I-NEXT: mv a1, s2 1307; RV32I-NEXT: li a2, 0 1308; RV32I-NEXT: li a3, 0 1309; RV32I-NEXT: call __adddf3 1310; RV32I-NEXT: mv s2, a0 1311; RV32I-NEXT: mv s3, a1 1312; RV32I-NEXT: mv a0, s1 1313; RV32I-NEXT: mv a1, s0 1314; RV32I-NEXT: li a2, 0 1315; RV32I-NEXT: li a3, 0 1316; RV32I-NEXT: call __adddf3 1317; RV32I-NEXT: mv s0, a0 1318; RV32I-NEXT: mv s1, a1 1319; RV32I-NEXT: mv a0, s4 1320; RV32I-NEXT: mv a1, s5 1321; RV32I-NEXT: mv a2, s2 1322; RV32I-NEXT: mv a3, s3 1323; RV32I-NEXT: call __muldf3 1324; RV32I-NEXT: lui a2, 524288 1325; RV32I-NEXT: xor a1, a1, a2 1326; RV32I-NEXT: mv a2, s0 1327; RV32I-NEXT: mv a3, s1 1328; RV32I-NEXT: call __subdf3 1329; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 1330; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 1331; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 1332; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 1333; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 1334; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload 1335; RV32I-NEXT: lw s5, 4(sp) # 4-byte Folded Reload 1336; RV32I-NEXT: addi sp, sp, 32 1337; RV32I-NEXT: ret 1338; 1339; RV64I-LABEL: fnmadd_d_contract: 1340; RV64I: # %bb.0: 1341; RV64I-NEXT: addi sp, sp, -32 1342; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 1343; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 1344; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 1345; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 1346; RV64I-NEXT: mv s0, a2 1347; RV64I-NEXT: mv s1, a1 1348; RV64I-NEXT: li a1, 0 1349; RV64I-NEXT: call __adddf3 1350; RV64I-NEXT: mv s2, a0 1351; RV64I-NEXT: mv a0, s1 1352; RV64I-NEXT: li a1, 0 1353; RV64I-NEXT: call __adddf3 1354; RV64I-NEXT: mv s1, a0 1355; RV64I-NEXT: mv a0, s0 1356; RV64I-NEXT: li a1, 0 1357; RV64I-NEXT: call __adddf3 1358; RV64I-NEXT: mv s0, a0 1359; RV64I-NEXT: mv a0, s2 1360; RV64I-NEXT: mv a1, s1 1361; RV64I-NEXT: call __muldf3 1362; RV64I-NEXT: li a1, -1 1363; RV64I-NEXT: slli a1, a1, 63 1364; RV64I-NEXT: xor a0, a0, a1 1365; RV64I-NEXT: mv a1, s0 1366; RV64I-NEXT: call __subdf3 1367; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 1368; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 1369; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 1370; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 1371; RV64I-NEXT: addi sp, sp, 32 1372; RV64I-NEXT: ret 1373 %a_ = fadd double 0.0, %a ; avoid negation using xor 1374 %b_ = fadd double 0.0, %b ; avoid negation using xor 1375 %c_ = fadd double 0.0, %c ; avoid negation using xor 1376 %1 = fmul contract double %a_, %b_ 1377 %2 = fneg double %1 1378 %3 = fsub contract double %2, %c_ 1379 ret double %3 1380} 1381 1382define double @fnmsub_d_contract(double %a, double %b, double %c) nounwind { 1383; RV32IFD-LABEL: fnmsub_d_contract: 1384; RV32IFD: # %bb.0: 1385; RV32IFD-NEXT: fcvt.d.w fa5, zero 1386; RV32IFD-NEXT: fadd.d fa4, fa0, fa5 1387; RV32IFD-NEXT: fadd.d fa5, fa1, fa5 1388; RV32IFD-NEXT: fnmsub.d fa0, fa4, fa5, fa2 1389; RV32IFD-NEXT: ret 1390; 1391; RV64IFD-LABEL: fnmsub_d_contract: 1392; RV64IFD: # %bb.0: 1393; RV64IFD-NEXT: fmv.d.x fa5, zero 1394; RV64IFD-NEXT: fadd.d fa4, fa0, fa5 1395; RV64IFD-NEXT: fadd.d fa5, fa1, fa5 1396; RV64IFD-NEXT: fnmsub.d fa0, fa4, fa5, fa2 1397; RV64IFD-NEXT: ret 1398; 1399; RV32IZFINXZDINX-LABEL: fnmsub_d_contract: 1400; RV32IZFINXZDINX: # %bb.0: 1401; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero 1402; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a6 1403; RV32IZFINXZDINX-NEXT: fadd.d a2, a2, a6 1404; RV32IZFINXZDINX-NEXT: fnmsub.d a0, a0, a2, a4 1405; RV32IZFINXZDINX-NEXT: ret 1406; 1407; RV64IZFINXZDINX-LABEL: fnmsub_d_contract: 1408; RV64IZFINXZDINX: # %bb.0: 1409; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, zero 1410; RV64IZFINXZDINX-NEXT: fadd.d a1, a1, zero 1411; RV64IZFINXZDINX-NEXT: fnmsub.d a0, a0, a1, a2 1412; RV64IZFINXZDINX-NEXT: ret 1413; 1414; RV32I-LABEL: fnmsub_d_contract: 1415; RV32I: # %bb.0: 1416; RV32I-NEXT: addi sp, sp, -32 1417; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 1418; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill 1419; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill 1420; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill 1421; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill 1422; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill 1423; RV32I-NEXT: sw s5, 4(sp) # 4-byte Folded Spill 1424; RV32I-NEXT: mv s0, a5 1425; RV32I-NEXT: mv s1, a4 1426; RV32I-NEXT: mv s2, a3 1427; RV32I-NEXT: mv s3, a2 1428; RV32I-NEXT: li a2, 0 1429; RV32I-NEXT: li a3, 0 1430; RV32I-NEXT: call __adddf3 1431; RV32I-NEXT: mv s4, a0 1432; RV32I-NEXT: mv s5, a1 1433; RV32I-NEXT: mv a0, s3 1434; RV32I-NEXT: mv a1, s2 1435; RV32I-NEXT: li a2, 0 1436; RV32I-NEXT: li a3, 0 1437; RV32I-NEXT: call __adddf3 1438; RV32I-NEXT: mv a2, a0 1439; RV32I-NEXT: mv a3, a1 1440; RV32I-NEXT: mv a0, s4 1441; RV32I-NEXT: mv a1, s5 1442; RV32I-NEXT: call __muldf3 1443; RV32I-NEXT: mv a2, a0 1444; RV32I-NEXT: mv a3, a1 1445; RV32I-NEXT: mv a0, s1 1446; RV32I-NEXT: mv a1, s0 1447; RV32I-NEXT: call __subdf3 1448; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 1449; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload 1450; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload 1451; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload 1452; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload 1453; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload 1454; RV32I-NEXT: lw s5, 4(sp) # 4-byte Folded Reload 1455; RV32I-NEXT: addi sp, sp, 32 1456; RV32I-NEXT: ret 1457; 1458; RV64I-LABEL: fnmsub_d_contract: 1459; RV64I: # %bb.0: 1460; RV64I-NEXT: addi sp, sp, -32 1461; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 1462; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 1463; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 1464; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill 1465; RV64I-NEXT: mv s0, a2 1466; RV64I-NEXT: mv s1, a1 1467; RV64I-NEXT: li a1, 0 1468; RV64I-NEXT: call __adddf3 1469; RV64I-NEXT: mv s2, a0 1470; RV64I-NEXT: mv a0, s1 1471; RV64I-NEXT: li a1, 0 1472; RV64I-NEXT: call __adddf3 1473; RV64I-NEXT: mv a1, a0 1474; RV64I-NEXT: mv a0, s2 1475; RV64I-NEXT: call __muldf3 1476; RV64I-NEXT: mv a1, a0 1477; RV64I-NEXT: mv a0, s0 1478; RV64I-NEXT: call __subdf3 1479; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 1480; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload 1481; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload 1482; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload 1483; RV64I-NEXT: addi sp, sp, 32 1484; RV64I-NEXT: ret 1485 %a_ = fadd double 0.0, %a ; avoid negation using xor 1486 %b_ = fadd double 0.0, %b ; avoid negation using xor 1487 %1 = fmul contract double %a_, %b_ 1488 %2 = fsub contract double %c, %1 1489 ret double %2 1490} 1491 1492define double @fsgnjx_f64(double %x, double %y) nounwind { 1493; CHECKIFD-LABEL: fsgnjx_f64: 1494; CHECKIFD: # %bb.0: 1495; CHECKIFD-NEXT: fsgnjx.d fa0, fa1, fa0 1496; CHECKIFD-NEXT: ret 1497; 1498; RV32IZFINXZDINX-LABEL: fsgnjx_f64: 1499; RV32IZFINXZDINX: # %bb.0: 1500; RV32IZFINXZDINX-NEXT: fsgnjx.d a0, a2, a0 1501; RV32IZFINXZDINX-NEXT: ret 1502; 1503; RV64IZFINXZDINX-LABEL: fsgnjx_f64: 1504; RV64IZFINXZDINX: # %bb.0: 1505; RV64IZFINXZDINX-NEXT: fsgnjx.d a0, a1, a0 1506; RV64IZFINXZDINX-NEXT: ret 1507; 1508; RV32I-LABEL: fsgnjx_f64: 1509; RV32I: # %bb.0: 1510; RV32I-NEXT: addi sp, sp, -16 1511; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 1512; RV32I-NEXT: lui a0, 524288 1513; RV32I-NEXT: and a0, a1, a0 1514; RV32I-NEXT: lui a1, 261888 1515; RV32I-NEXT: or a1, a0, a1 1516; RV32I-NEXT: li a0, 0 1517; RV32I-NEXT: call __muldf3 1518; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 1519; RV32I-NEXT: addi sp, sp, 16 1520; RV32I-NEXT: ret 1521; 1522; RV64I-LABEL: fsgnjx_f64: 1523; RV64I: # %bb.0: 1524; RV64I-NEXT: addi sp, sp, -16 1525; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 1526; RV64I-NEXT: srli a0, a0, 63 1527; RV64I-NEXT: li a2, 1023 1528; RV64I-NEXT: slli a0, a0, 63 1529; RV64I-NEXT: slli a2, a2, 52 1530; RV64I-NEXT: or a0, a0, a2 1531; RV64I-NEXT: call __muldf3 1532; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 1533; RV64I-NEXT: addi sp, sp, 16 1534; RV64I-NEXT: ret 1535 %z = call double @llvm.copysign.f64(double 1.0, double %x) 1536 %mul = fmul double %z, %y 1537 ret double %mul 1538} 1539