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