1678 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \3; RUN: -target-abi=ilp32d | FileCheck -check-prefixes=CHECKIFD,RV32IFD %s4; RUN: llc -mtriple=riscv64 -mattr=+d -verify-machineinstrs < %s \5; RUN: -target-abi=lp64d | FileCheck -check-prefixes=CHECKIFD,RV64IFD %s6; RUN: llc -mtriple=riscv32 -mattr=+zdinx -verify-machineinstrs < %s \7; RUN: -target-abi=ilp32 | FileCheck -check-prefix=RV32IZFINXZDINX %s8; RUN: llc -mtriple=riscv64 -mattr=+zdinx -verify-machineinstrs < %s \9; RUN: -target-abi=lp64 | FileCheck -check-prefix=RV64IZFINXZDINX %s10; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \11; RUN: | FileCheck -check-prefix=RV32I %s12; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \13; RUN: | FileCheck -check-prefix=RV64I %s14 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.ll17; respectively. Some other double-*.ll files in this folder exercise LLVM IR18; 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, fa124; CHECKIFD-NEXT: ret25;26; RV32IZFINXZDINX-LABEL: fadd_d:27; RV32IZFINXZDINX: # %bb.0:28; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a229; RV32IZFINXZDINX-NEXT: ret30;31; RV64IZFINXZDINX-LABEL: fadd_d:32; RV64IZFINXZDINX: # %bb.0:33; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, a134; RV64IZFINXZDINX-NEXT: ret35;36; RV32I-LABEL: fadd_d:37; RV32I: # %bb.0:38; RV32I-NEXT: addi sp, sp, -1639; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill40; RV32I-NEXT: call __adddf341; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload42; RV32I-NEXT: addi sp, sp, 1643; RV32I-NEXT: ret44;45; RV64I-LABEL: fadd_d:46; RV64I: # %bb.0:47; RV64I-NEXT: addi sp, sp, -1648; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill49; RV64I-NEXT: call __adddf350; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload51; RV64I-NEXT: addi sp, sp, 1652; RV64I-NEXT: ret53 %1 = fadd double %a, %b54 ret double %155}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, fa161; CHECKIFD-NEXT: ret62;63; RV32IZFINXZDINX-LABEL: fsub_d:64; RV32IZFINXZDINX: # %bb.0:65; RV32IZFINXZDINX-NEXT: fsub.d a0, a0, a266; RV32IZFINXZDINX-NEXT: ret67;68; RV64IZFINXZDINX-LABEL: fsub_d:69; RV64IZFINXZDINX: # %bb.0:70; RV64IZFINXZDINX-NEXT: fsub.d a0, a0, a171; RV64IZFINXZDINX-NEXT: ret72;73; RV32I-LABEL: fsub_d:74; RV32I: # %bb.0:75; RV32I-NEXT: addi sp, sp, -1676; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill77; RV32I-NEXT: call __subdf378; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload79; RV32I-NEXT: addi sp, sp, 1680; RV32I-NEXT: ret81;82; RV64I-LABEL: fsub_d:83; RV64I: # %bb.0:84; RV64I-NEXT: addi sp, sp, -1685; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill86; RV64I-NEXT: call __subdf387; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload88; RV64I-NEXT: addi sp, sp, 1689; RV64I-NEXT: ret90 %1 = fsub double %a, %b91 ret double %192}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, fa198; CHECKIFD-NEXT: ret99;100; RV32IZFINXZDINX-LABEL: fmul_d:101; RV32IZFINXZDINX: # %bb.0:102; RV32IZFINXZDINX-NEXT: fmul.d a0, a0, a2103; RV32IZFINXZDINX-NEXT: ret104;105; RV64IZFINXZDINX-LABEL: fmul_d:106; RV64IZFINXZDINX: # %bb.0:107; RV64IZFINXZDINX-NEXT: fmul.d a0, a0, a1108; RV64IZFINXZDINX-NEXT: ret109;110; RV32I-LABEL: fmul_d:111; RV32I: # %bb.0:112; RV32I-NEXT: addi sp, sp, -16113; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill114; RV32I-NEXT: call __muldf3115; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload116; RV32I-NEXT: addi sp, sp, 16117; RV32I-NEXT: ret118;119; RV64I-LABEL: fmul_d:120; RV64I: # %bb.0:121; RV64I-NEXT: addi sp, sp, -16122; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill123; RV64I-NEXT: call __muldf3124; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload125; RV64I-NEXT: addi sp, sp, 16126; RV64I-NEXT: ret127 %1 = fmul double %a, %b128 ret double %1129}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, fa1135; CHECKIFD-NEXT: ret136;137; RV32IZFINXZDINX-LABEL: fdiv_d:138; RV32IZFINXZDINX: # %bb.0:139; RV32IZFINXZDINX-NEXT: fdiv.d a0, a0, a2140; RV32IZFINXZDINX-NEXT: ret141;142; RV64IZFINXZDINX-LABEL: fdiv_d:143; RV64IZFINXZDINX: # %bb.0:144; RV64IZFINXZDINX-NEXT: fdiv.d a0, a0, a1145; RV64IZFINXZDINX-NEXT: ret146;147; RV32I-LABEL: fdiv_d:148; RV32I: # %bb.0:149; RV32I-NEXT: addi sp, sp, -16150; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill151; RV32I-NEXT: call __divdf3152; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload153; RV32I-NEXT: addi sp, sp, 16154; RV32I-NEXT: ret155;156; RV64I-LABEL: fdiv_d:157; RV64I: # %bb.0:158; RV64I-NEXT: addi sp, sp, -16159; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill160; RV64I-NEXT: call __divdf3161; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload162; RV64I-NEXT: addi sp, sp, 16163; RV64I-NEXT: ret164 %1 = fdiv double %a, %b165 ret double %1166}167 168define double @fsqrt_d(double %a) nounwind {169; CHECKIFD-LABEL: fsqrt_d:170; CHECKIFD: # %bb.0:171; CHECKIFD-NEXT: fsqrt.d fa0, fa0172; CHECKIFD-NEXT: ret173;174; RV32IZFINXZDINX-LABEL: fsqrt_d:175; RV32IZFINXZDINX: # %bb.0:176; RV32IZFINXZDINX-NEXT: fsqrt.d a0, a0177; RV32IZFINXZDINX-NEXT: ret178;179; RV64IZFINXZDINX-LABEL: fsqrt_d:180; RV64IZFINXZDINX: # %bb.0:181; RV64IZFINXZDINX-NEXT: fsqrt.d a0, a0182; RV64IZFINXZDINX-NEXT: ret183;184; RV32I-LABEL: fsqrt_d:185; RV32I: # %bb.0:186; RV32I-NEXT: addi sp, sp, -16187; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill188; RV32I-NEXT: call sqrt189; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload190; RV32I-NEXT: addi sp, sp, 16191; RV32I-NEXT: ret192;193; RV64I-LABEL: fsqrt_d:194; RV64I: # %bb.0:195; RV64I-NEXT: addi sp, sp, -16196; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill197; RV64I-NEXT: call sqrt198; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload199; RV64I-NEXT: addi sp, sp, 16200; RV64I-NEXT: ret201 %1 = call double @llvm.sqrt.f64(double %a)202 ret double %1203}204 205define double @fsgnj_d(double %a, double %b) nounwind {206; CHECKIFD-LABEL: fsgnj_d:207; CHECKIFD: # %bb.0:208; CHECKIFD-NEXT: fsgnj.d fa0, fa0, fa1209; CHECKIFD-NEXT: ret210;211; RV32IZFINXZDINX-LABEL: fsgnj_d:212; RV32IZFINXZDINX: # %bb.0:213; RV32IZFINXZDINX-NEXT: fsgnj.d a0, a0, a2214; RV32IZFINXZDINX-NEXT: ret215;216; RV64IZFINXZDINX-LABEL: fsgnj_d:217; RV64IZFINXZDINX: # %bb.0:218; RV64IZFINXZDINX-NEXT: fsgnj.d a0, a0, a1219; RV64IZFINXZDINX-NEXT: ret220;221; RV32I-LABEL: fsgnj_d:222; RV32I: # %bb.0:223; RV32I-NEXT: lui a2, 524288224; RV32I-NEXT: slli a1, a1, 1225; RV32I-NEXT: and a2, a3, a2226; RV32I-NEXT: srli a1, a1, 1227; RV32I-NEXT: or a1, a1, a2228; RV32I-NEXT: ret229;230; RV64I-LABEL: fsgnj_d:231; RV64I: # %bb.0:232; RV64I-NEXT: srli a1, a1, 63233; RV64I-NEXT: slli a0, a0, 1234; RV64I-NEXT: slli a1, a1, 63235; RV64I-NEXT: srli a0, a0, 1236; RV64I-NEXT: or a0, a0, a1237; RV64I-NEXT: ret238 %1 = call double @llvm.copysign.f64(double %a, double %b)239 ret double %1240}241 242; This function performs extra work to ensure that243; DAGCombiner::visitBITCAST doesn't replace the fneg with an xor.244define i32 @fneg_d(double %a, double %b) nounwind {245; CHECKIFD-LABEL: fneg_d:246; CHECKIFD: # %bb.0:247; CHECKIFD-NEXT: fadd.d fa5, fa0, fa0248; CHECKIFD-NEXT: fneg.d fa4, fa5249; CHECKIFD-NEXT: feq.d a0, fa5, fa4250; CHECKIFD-NEXT: ret251;252; RV32IZFINXZDINX-LABEL: fneg_d:253; RV32IZFINXZDINX: # %bb.0:254; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a0255; RV32IZFINXZDINX-NEXT: fneg.d a2, a0256; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a2257; RV32IZFINXZDINX-NEXT: ret258;259; RV64IZFINXZDINX-LABEL: fneg_d:260; RV64IZFINXZDINX: # %bb.0:261; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, a0262; RV64IZFINXZDINX-NEXT: fneg.d a1, a0263; RV64IZFINXZDINX-NEXT: feq.d a0, a0, a1264; RV64IZFINXZDINX-NEXT: ret265;266; RV32I-LABEL: fneg_d:267; RV32I: # %bb.0:268; RV32I-NEXT: addi sp, sp, -16269; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill270; RV32I-NEXT: mv a2, a0271; RV32I-NEXT: mv a3, a1272; RV32I-NEXT: call __adddf3273; RV32I-NEXT: lui a3, 524288274; RV32I-NEXT: xor a3, a1, a3275; RV32I-NEXT: mv a2, a0276; RV32I-NEXT: call __eqdf2277; RV32I-NEXT: seqz a0, a0278; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload279; RV32I-NEXT: addi sp, sp, 16280; RV32I-NEXT: ret281;282; RV64I-LABEL: fneg_d:283; RV64I: # %bb.0:284; RV64I-NEXT: addi sp, sp, -16285; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill286; RV64I-NEXT: mv a1, a0287; RV64I-NEXT: call __adddf3288; RV64I-NEXT: li a1, -1289; RV64I-NEXT: slli a1, a1, 63290; RV64I-NEXT: xor a1, a0, a1291; RV64I-NEXT: call __eqdf2292; RV64I-NEXT: seqz a0, a0293; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload294; RV64I-NEXT: addi sp, sp, 16295; RV64I-NEXT: ret296 %1 = fadd double %a, %a297 %2 = fneg double %1298 %3 = fcmp oeq double %1, %2299 %4 = zext i1 %3 to i32300 ret i32 %4301}302 303define double @fsgnjn_d(double %a, double %b) nounwind {304; CHECKIFD-LABEL: fsgnjn_d:305; CHECKIFD: # %bb.0:306; CHECKIFD-NEXT: fsgnjn.d fa0, fa0, fa1307; CHECKIFD-NEXT: ret308;309; RV32IZFINXZDINX-LABEL: fsgnjn_d:310; RV32IZFINXZDINX: # %bb.0:311; RV32IZFINXZDINX-NEXT: fsgnjn.d a0, a0, a2312; RV32IZFINXZDINX-NEXT: ret313;314; RV64IZFINXZDINX-LABEL: fsgnjn_d:315; RV64IZFINXZDINX: # %bb.0:316; RV64IZFINXZDINX-NEXT: fsgnjn.d a0, a0, a1317; RV64IZFINXZDINX-NEXT: ret318;319; RV32I-LABEL: fsgnjn_d:320; RV32I: # %bb.0:321; RV32I-NEXT: not a2, a3322; RV32I-NEXT: lui a3, 524288323; RV32I-NEXT: slli a1, a1, 1324; RV32I-NEXT: and a2, a2, a3325; RV32I-NEXT: srli a1, a1, 1326; RV32I-NEXT: or a1, a1, a2327; RV32I-NEXT: ret328;329; RV64I-LABEL: fsgnjn_d:330; RV64I: # %bb.0:331; RV64I-NEXT: not a1, a1332; RV64I-NEXT: slli a0, a0, 1333; RV64I-NEXT: srli a0, a0, 1334; RV64I-NEXT: srli a1, a1, 63335; RV64I-NEXT: slli a1, a1, 63336; RV64I-NEXT: or a0, a0, a1337; RV64I-NEXT: ret338 %1 = fsub double -0.0, %b339 %2 = call double @llvm.copysign.f64(double %a, double %1)340 ret double %2341}342 343; This function performs extra work to ensure that344; DAGCombiner::visitBITCAST doesn't replace the fabs with an and.345define double @fabs_d(double %a, double %b) nounwind {346; CHECKIFD-LABEL: fabs_d:347; CHECKIFD: # %bb.0:348; CHECKIFD-NEXT: fadd.d fa5, fa0, fa1349; CHECKIFD-NEXT: fabs.d fa4, fa5350; CHECKIFD-NEXT: fadd.d fa0, fa4, fa5351; CHECKIFD-NEXT: ret352;353; RV32IZFINXZDINX-LABEL: fabs_d:354; RV32IZFINXZDINX: # %bb.0:355; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a2356; RV32IZFINXZDINX-NEXT: fabs.d a2, a0357; RV32IZFINXZDINX-NEXT: fadd.d a0, a2, a0358; RV32IZFINXZDINX-NEXT: ret359;360; RV64IZFINXZDINX-LABEL: fabs_d:361; RV64IZFINXZDINX: # %bb.0:362; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, a1363; RV64IZFINXZDINX-NEXT: fabs.d a1, a0364; RV64IZFINXZDINX-NEXT: fadd.d a0, a1, a0365; RV64IZFINXZDINX-NEXT: ret366;367; RV32I-LABEL: fabs_d:368; RV32I: # %bb.0:369; RV32I-NEXT: addi sp, sp, -16370; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill371; RV32I-NEXT: call __adddf3372; RV32I-NEXT: mv a3, a1373; RV32I-NEXT: slli a1, a1, 1374; RV32I-NEXT: srli a1, a1, 1375; RV32I-NEXT: mv a2, a0376; RV32I-NEXT: call __adddf3377; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload378; RV32I-NEXT: addi sp, sp, 16379; RV32I-NEXT: ret380;381; RV64I-LABEL: fabs_d:382; RV64I: # %bb.0:383; RV64I-NEXT: addi sp, sp, -16384; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill385; RV64I-NEXT: call __adddf3386; RV64I-NEXT: mv a1, a0387; RV64I-NEXT: slli a0, a0, 1388; RV64I-NEXT: srli a0, a0, 1389; RV64I-NEXT: call __adddf3390; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload391; RV64I-NEXT: addi sp, sp, 16392; RV64I-NEXT: ret393 %1 = fadd double %a, %b394 %2 = call double @llvm.fabs.f64(double %1)395 %3 = fadd double %2, %1396 ret double %3397}398 399define double @fmin_d(double %a, double %b) nounwind {400; CHECKIFD-LABEL: fmin_d:401; CHECKIFD: # %bb.0:402; CHECKIFD-NEXT: fmin.d fa0, fa0, fa1403; CHECKIFD-NEXT: ret404;405; RV32IZFINXZDINX-LABEL: fmin_d:406; RV32IZFINXZDINX: # %bb.0:407; RV32IZFINXZDINX-NEXT: fmin.d a0, a0, a2408; RV32IZFINXZDINX-NEXT: ret409;410; RV64IZFINXZDINX-LABEL: fmin_d:411; RV64IZFINXZDINX: # %bb.0:412; RV64IZFINXZDINX-NEXT: fmin.d a0, a0, a1413; RV64IZFINXZDINX-NEXT: ret414;415; RV32I-LABEL: fmin_d:416; RV32I: # %bb.0:417; RV32I-NEXT: addi sp, sp, -16418; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill419; RV32I-NEXT: call fmin420; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload421; RV32I-NEXT: addi sp, sp, 16422; RV32I-NEXT: ret423;424; RV64I-LABEL: fmin_d:425; RV64I: # %bb.0:426; RV64I-NEXT: addi sp, sp, -16427; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill428; RV64I-NEXT: call fmin429; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload430; RV64I-NEXT: addi sp, sp, 16431; RV64I-NEXT: ret432 %1 = call double @llvm.minnum.f64(double %a, double %b)433 ret double %1434}435 436define double @fmax_d(double %a, double %b) nounwind {437; CHECKIFD-LABEL: fmax_d:438; CHECKIFD: # %bb.0:439; CHECKIFD-NEXT: fmax.d fa0, fa0, fa1440; CHECKIFD-NEXT: ret441;442; RV32IZFINXZDINX-LABEL: fmax_d:443; RV32IZFINXZDINX: # %bb.0:444; RV32IZFINXZDINX-NEXT: fmax.d a0, a0, a2445; RV32IZFINXZDINX-NEXT: ret446;447; RV64IZFINXZDINX-LABEL: fmax_d:448; RV64IZFINXZDINX: # %bb.0:449; RV64IZFINXZDINX-NEXT: fmax.d a0, a0, a1450; RV64IZFINXZDINX-NEXT: ret451;452; RV32I-LABEL: fmax_d:453; RV32I: # %bb.0:454; RV32I-NEXT: addi sp, sp, -16455; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill456; RV32I-NEXT: call fmax457; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload458; RV32I-NEXT: addi sp, sp, 16459; RV32I-NEXT: ret460;461; RV64I-LABEL: fmax_d:462; RV64I: # %bb.0:463; RV64I-NEXT: addi sp, sp, -16464; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill465; RV64I-NEXT: call fmax466; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload467; RV64I-NEXT: addi sp, sp, 16468; RV64I-NEXT: ret469 %1 = call double @llvm.maxnum.f64(double %a, double %b)470 ret double %1471}472 473define double @fmadd_d(double %a, double %b, double %c) nounwind {474; CHECKIFD-LABEL: fmadd_d:475; CHECKIFD: # %bb.0:476; CHECKIFD-NEXT: fmadd.d fa0, fa0, fa1, fa2477; CHECKIFD-NEXT: ret478;479; RV32IZFINXZDINX-LABEL: fmadd_d:480; RV32IZFINXZDINX: # %bb.0:481; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a4482; RV32IZFINXZDINX-NEXT: ret483;484; RV64IZFINXZDINX-LABEL: fmadd_d:485; RV64IZFINXZDINX: # %bb.0:486; RV64IZFINXZDINX-NEXT: fmadd.d a0, a0, a1, a2487; RV64IZFINXZDINX-NEXT: ret488;489; RV32I-LABEL: fmadd_d:490; RV32I: # %bb.0:491; RV32I-NEXT: addi sp, sp, -16492; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill493; RV32I-NEXT: call fma494; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload495; RV32I-NEXT: addi sp, sp, 16496; RV32I-NEXT: ret497;498; RV64I-LABEL: fmadd_d:499; RV64I: # %bb.0:500; RV64I-NEXT: addi sp, sp, -16501; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill502; RV64I-NEXT: call fma503; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload504; RV64I-NEXT: addi sp, sp, 16505; RV64I-NEXT: ret506 %1 = call double @llvm.fma.f64(double %a, double %b, double %c)507 ret double %1508}509 510define double @fmsub_d(double %a, double %b, double %c) nounwind {511; RV32IFD-LABEL: fmsub_d:512; RV32IFD: # %bb.0:513; RV32IFD-NEXT: fcvt.d.w fa5, zero514; RV32IFD-NEXT: fadd.d fa5, fa2, fa5515; RV32IFD-NEXT: fmsub.d fa0, fa0, fa1, fa5516; RV32IFD-NEXT: ret517;518; RV64IFD-LABEL: fmsub_d:519; RV64IFD: # %bb.0:520; RV64IFD-NEXT: fmv.d.x fa5, zero521; RV64IFD-NEXT: fadd.d fa5, fa2, fa5522; RV64IFD-NEXT: fmsub.d fa0, fa0, fa1, fa5523; RV64IFD-NEXT: ret524;525; RV32IZFINXZDINX-LABEL: fmsub_d:526; RV32IZFINXZDINX: # %bb.0:527; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, zero528; RV32IZFINXZDINX-NEXT: fmsub.d a0, a0, a2, a4529; RV32IZFINXZDINX-NEXT: ret530;531; RV64IZFINXZDINX-LABEL: fmsub_d:532; RV64IZFINXZDINX: # %bb.0:533; RV64IZFINXZDINX-NEXT: fadd.d a2, a2, zero534; RV64IZFINXZDINX-NEXT: fmsub.d a0, a0, a1, a2535; RV64IZFINXZDINX-NEXT: ret536;537; RV32I-LABEL: fmsub_d:538; RV32I: # %bb.0:539; RV32I-NEXT: addi sp, sp, -32540; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill541; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill542; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill543; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill544; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill545; RV32I-NEXT: mv s0, a3546; RV32I-NEXT: mv s1, a2547; RV32I-NEXT: mv s2, a1548; RV32I-NEXT: mv s3, a0549; RV32I-NEXT: mv a0, a4550; RV32I-NEXT: mv a1, a5551; RV32I-NEXT: li a2, 0552; RV32I-NEXT: li a3, 0553; RV32I-NEXT: call __adddf3554; RV32I-NEXT: mv a4, a0555; RV32I-NEXT: lui a5, 524288556; RV32I-NEXT: xor a5, a1, a5557; RV32I-NEXT: mv a0, s3558; RV32I-NEXT: mv a1, s2559; RV32I-NEXT: mv a2, s1560; RV32I-NEXT: mv a3, s0561; RV32I-NEXT: call fma562; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload563; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload564; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload565; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload566; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload567; RV32I-NEXT: addi sp, sp, 32568; RV32I-NEXT: ret569;570; RV64I-LABEL: fmsub_d:571; RV64I: # %bb.0:572; RV64I-NEXT: addi sp, sp, -32573; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill574; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill575; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill576; RV64I-NEXT: mv s0, a1577; RV64I-NEXT: mv s1, a0578; RV64I-NEXT: mv a0, a2579; RV64I-NEXT: li a1, 0580; RV64I-NEXT: call __adddf3581; RV64I-NEXT: li a1, -1582; RV64I-NEXT: slli a1, a1, 63583; RV64I-NEXT: xor a2, a0, a1584; RV64I-NEXT: mv a0, s1585; RV64I-NEXT: mv a1, s0586; RV64I-NEXT: call fma587; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload588; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload589; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload590; RV64I-NEXT: addi sp, sp, 32591; RV64I-NEXT: ret592 %c_ = fadd double 0.0, %c ; avoid negation using xor593 %negc = fsub double -0.0, %c_594 %1 = call double @llvm.fma.f64(double %a, double %b, double %negc)595 ret double %1596}597 598define double @fmsub_d_fmul_fneg(double %a, double %b, double %c, double %d) nounwind {599; CHECKIFD-LABEL: fmsub_d_fmul_fneg:600; CHECKIFD: # %bb.0:601; CHECKIFD-NEXT: fmul.d fa5, fa2, fa3602; CHECKIFD-NEXT: fmsub.d fa0, fa0, fa1, fa5603; CHECKIFD-NEXT: ret604;605; RV32IZFINXZDINX-LABEL: fmsub_d_fmul_fneg:606; RV32IZFINXZDINX: # %bb.0:607; RV32IZFINXZDINX-NEXT: fmul.d a4, a4, a6608; RV32IZFINXZDINX-NEXT: fmsub.d a0, a0, a2, a4609; RV32IZFINXZDINX-NEXT: ret610;611; RV64IZFINXZDINX-LABEL: fmsub_d_fmul_fneg:612; RV64IZFINXZDINX: # %bb.0:613; RV64IZFINXZDINX-NEXT: fmul.d a2, a2, a3614; RV64IZFINXZDINX-NEXT: fmsub.d a0, a0, a1, a2615; RV64IZFINXZDINX-NEXT: ret616;617; RV32I-LABEL: fmsub_d_fmul_fneg:618; RV32I: # %bb.0:619; RV32I-NEXT: addi sp, sp, -32620; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill621; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill622; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill623; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill624; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill625; RV32I-NEXT: mv s0, a3626; RV32I-NEXT: mv s1, a2627; RV32I-NEXT: mv s2, a1628; RV32I-NEXT: mv s3, a0629; RV32I-NEXT: lui a0, 524288630; RV32I-NEXT: xor a3, a7, a0631; RV32I-NEXT: mv a0, a4632; RV32I-NEXT: mv a1, a5633; RV32I-NEXT: mv a2, a6634; RV32I-NEXT: call __muldf3635; RV32I-NEXT: mv a4, a0636; RV32I-NEXT: mv a5, a1637; RV32I-NEXT: mv a0, s3638; RV32I-NEXT: mv a1, s2639; RV32I-NEXT: mv a2, s1640; RV32I-NEXT: mv a3, s0641; RV32I-NEXT: call fma642; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload643; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload644; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload645; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload646; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload647; RV32I-NEXT: addi sp, sp, 32648; RV32I-NEXT: ret649;650; RV64I-LABEL: fmsub_d_fmul_fneg:651; RV64I: # %bb.0:652; RV64I-NEXT: addi sp, sp, -32653; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill654; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill655; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill656; RV64I-NEXT: mv s0, a1657; RV64I-NEXT: mv s1, a0658; RV64I-NEXT: li a0, -1659; RV64I-NEXT: slli a0, a0, 63660; RV64I-NEXT: xor a1, a3, a0661; RV64I-NEXT: mv a0, a2662; RV64I-NEXT: call __muldf3663; RV64I-NEXT: mv a2, a0664; RV64I-NEXT: mv a0, s1665; RV64I-NEXT: mv a1, s0666; RV64I-NEXT: call fma667; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload668; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload669; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload670; RV64I-NEXT: addi sp, sp, 32671; RV64I-NEXT: ret672 %negd = fneg double %d673 %fmul = fmul double %c, %negd674 %1 = call double @llvm.fma.f64(double %a, double %b, double %fmul)675 ret double %1676}677 678define double @fnmadd_d(double %a, double %b, double %c) nounwind {679; RV32IFD-LABEL: fnmadd_d:680; RV32IFD: # %bb.0:681; RV32IFD-NEXT: fcvt.d.w fa5, zero682; RV32IFD-NEXT: fadd.d fa4, fa0, fa5683; RV32IFD-NEXT: fadd.d fa5, fa2, fa5684; RV32IFD-NEXT: fnmadd.d fa0, fa4, fa1, fa5685; RV32IFD-NEXT: ret686;687; RV64IFD-LABEL: fnmadd_d:688; RV64IFD: # %bb.0:689; RV64IFD-NEXT: fmv.d.x fa5, zero690; RV64IFD-NEXT: fadd.d fa4, fa0, fa5691; RV64IFD-NEXT: fadd.d fa5, fa2, fa5692; RV64IFD-NEXT: fnmadd.d fa0, fa4, fa1, fa5693; RV64IFD-NEXT: ret694;695; RV32IZFINXZDINX-LABEL: fnmadd_d:696; RV32IZFINXZDINX: # %bb.0:697; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, zero698; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, zero699; RV32IZFINXZDINX-NEXT: fnmadd.d a0, a0, a2, a4700; RV32IZFINXZDINX-NEXT: ret701;702; RV64IZFINXZDINX-LABEL: fnmadd_d:703; RV64IZFINXZDINX: # %bb.0:704; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, zero705; RV64IZFINXZDINX-NEXT: fadd.d a2, a2, zero706; RV64IZFINXZDINX-NEXT: fnmadd.d a0, a0, a1, a2707; RV64IZFINXZDINX-NEXT: ret708;709; RV32I-LABEL: fnmadd_d:710; RV32I: # %bb.0:711; RV32I-NEXT: addi sp, sp, -32712; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill713; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill714; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill715; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill716; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill717; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill718; RV32I-NEXT: sw s5, 4(sp) # 4-byte Folded Spill719; RV32I-NEXT: mv s0, a5720; RV32I-NEXT: mv s1, a4721; RV32I-NEXT: mv s2, a3722; RV32I-NEXT: mv s3, a2723; RV32I-NEXT: li a2, 0724; RV32I-NEXT: li a3, 0725; RV32I-NEXT: call __adddf3726; RV32I-NEXT: mv s4, a0727; RV32I-NEXT: mv s5, a1728; RV32I-NEXT: mv a0, s1729; RV32I-NEXT: mv a1, s0730; RV32I-NEXT: li a2, 0731; RV32I-NEXT: li a3, 0732; RV32I-NEXT: call __adddf3733; RV32I-NEXT: mv a4, a0734; RV32I-NEXT: lui a5, 524288735; RV32I-NEXT: xor a2, s5, a5736; RV32I-NEXT: xor a5, a1, a5737; RV32I-NEXT: mv a0, s4738; RV32I-NEXT: mv a1, a2739; RV32I-NEXT: mv a2, s3740; RV32I-NEXT: mv a3, s2741; RV32I-NEXT: call fma742; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload743; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload744; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload745; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload746; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload747; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload748; RV32I-NEXT: lw s5, 4(sp) # 4-byte Folded Reload749; RV32I-NEXT: addi sp, sp, 32750; RV32I-NEXT: ret751;752; RV64I-LABEL: fnmadd_d:753; RV64I: # %bb.0:754; RV64I-NEXT: addi sp, sp, -32755; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill756; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill757; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill758; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill759; RV64I-NEXT: mv s0, a2760; RV64I-NEXT: mv s1, a1761; RV64I-NEXT: li a1, 0762; RV64I-NEXT: call __adddf3763; RV64I-NEXT: mv s2, a0764; RV64I-NEXT: mv a0, s0765; RV64I-NEXT: li a1, 0766; RV64I-NEXT: call __adddf3767; RV64I-NEXT: li a1, -1768; RV64I-NEXT: slli a2, a1, 63769; RV64I-NEXT: xor a1, s2, a2770; RV64I-NEXT: xor a2, a0, a2771; RV64I-NEXT: mv a0, a1772; RV64I-NEXT: mv a1, s1773; RV64I-NEXT: call fma774; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload775; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload776; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload777; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload778; RV64I-NEXT: addi sp, sp, 32779; RV64I-NEXT: ret780 %a_ = fadd double 0.0, %a781 %c_ = fadd double 0.0, %c782 %nega = fsub double -0.0, %a_783 %negc = fsub double -0.0, %c_784 %1 = call double @llvm.fma.f64(double %nega, double %b, double %negc)785 ret double %1786}787 788define double @fnmadd_d_2(double %a, double %b, double %c) nounwind {789; RV32IFD-LABEL: fnmadd_d_2:790; RV32IFD: # %bb.0:791; RV32IFD-NEXT: fcvt.d.w fa5, zero792; RV32IFD-NEXT: fadd.d fa4, fa1, fa5793; RV32IFD-NEXT: fadd.d fa5, fa2, fa5794; RV32IFD-NEXT: fnmadd.d fa0, fa4, fa0, fa5795; RV32IFD-NEXT: ret796;797; RV64IFD-LABEL: fnmadd_d_2:798; RV64IFD: # %bb.0:799; RV64IFD-NEXT: fmv.d.x fa5, zero800; RV64IFD-NEXT: fadd.d fa4, fa1, fa5801; RV64IFD-NEXT: fadd.d fa5, fa2, fa5802; RV64IFD-NEXT: fnmadd.d fa0, fa4, fa0, fa5803; RV64IFD-NEXT: ret804;805; RV32IZFINXZDINX-LABEL: fnmadd_d_2:806; RV32IZFINXZDINX: # %bb.0:807; RV32IZFINXZDINX-NEXT: fadd.d a2, a2, zero808; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, zero809; RV32IZFINXZDINX-NEXT: fnmadd.d a0, a2, a0, a4810; RV32IZFINXZDINX-NEXT: ret811;812; RV64IZFINXZDINX-LABEL: fnmadd_d_2:813; RV64IZFINXZDINX: # %bb.0:814; RV64IZFINXZDINX-NEXT: fadd.d a1, a1, zero815; RV64IZFINXZDINX-NEXT: fadd.d a2, a2, zero816; RV64IZFINXZDINX-NEXT: fnmadd.d a0, a1, a0, a2817; RV64IZFINXZDINX-NEXT: ret818;819; RV32I-LABEL: fnmadd_d_2:820; RV32I: # %bb.0:821; RV32I-NEXT: addi sp, sp, -32822; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill823; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill824; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill825; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill826; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill827; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill828; RV32I-NEXT: sw s5, 4(sp) # 4-byte Folded Spill829; RV32I-NEXT: mv s0, a5830; RV32I-NEXT: mv s1, a4831; RV32I-NEXT: mv s2, a1832; RV32I-NEXT: mv s3, a0833; RV32I-NEXT: mv a0, a2834; RV32I-NEXT: mv a1, a3835; RV32I-NEXT: li a2, 0836; RV32I-NEXT: li a3, 0837; RV32I-NEXT: call __adddf3838; RV32I-NEXT: mv s4, a0839; RV32I-NEXT: mv s5, a1840; RV32I-NEXT: mv a0, s1841; RV32I-NEXT: mv a1, s0842; RV32I-NEXT: li a2, 0843; RV32I-NEXT: li a3, 0844; RV32I-NEXT: call __adddf3845; RV32I-NEXT: mv a4, a0846; RV32I-NEXT: lui a5, 524288847; RV32I-NEXT: xor a3, s5, a5848; RV32I-NEXT: xor a5, a1, a5849; RV32I-NEXT: mv a0, s3850; RV32I-NEXT: mv a1, s2851; RV32I-NEXT: mv a2, s4852; RV32I-NEXT: call fma853; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload854; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload855; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload856; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload857; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload858; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload859; RV32I-NEXT: lw s5, 4(sp) # 4-byte Folded Reload860; RV32I-NEXT: addi sp, sp, 32861; RV32I-NEXT: ret862;863; RV64I-LABEL: fnmadd_d_2:864; RV64I: # %bb.0:865; RV64I-NEXT: addi sp, sp, -32866; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill867; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill868; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill869; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill870; RV64I-NEXT: mv s0, a2871; RV64I-NEXT: mv s1, a0872; RV64I-NEXT: mv a0, a1873; RV64I-NEXT: li a1, 0874; RV64I-NEXT: call __adddf3875; RV64I-NEXT: mv s2, a0876; RV64I-NEXT: mv a0, s0877; RV64I-NEXT: li a1, 0878; RV64I-NEXT: call __adddf3879; RV64I-NEXT: li a1, -1880; RV64I-NEXT: slli a2, a1, 63881; RV64I-NEXT: xor a1, s2, a2882; RV64I-NEXT: xor a2, a0, a2883; RV64I-NEXT: mv a0, s1884; RV64I-NEXT: call fma885; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload886; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload887; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload888; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload889; RV64I-NEXT: addi sp, sp, 32890; RV64I-NEXT: ret891 %b_ = fadd double 0.0, %b892 %c_ = fadd double 0.0, %c893 %negb = fsub double -0.0, %b_894 %negc = fsub double -0.0, %c_895 %1 = call double @llvm.fma.f64(double %a, double %negb, double %negc)896 ret double %1897}898 899define double @fnmadd_d_3(double %a, double %b, double %c) nounwind {900; CHECKIFD-LABEL: fnmadd_d_3:901; CHECKIFD: # %bb.0:902; CHECKIFD-NEXT: fmadd.d fa5, fa0, fa1, fa2903; CHECKIFD-NEXT: fneg.d fa0, fa5904; CHECKIFD-NEXT: ret905;906; RV32IZFINXZDINX-LABEL: fnmadd_d_3:907; RV32IZFINXZDINX: # %bb.0:908; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a4909; RV32IZFINXZDINX-NEXT: fneg.d a0, a0910; RV32IZFINXZDINX-NEXT: ret911;912; RV64IZFINXZDINX-LABEL: fnmadd_d_3:913; RV64IZFINXZDINX: # %bb.0:914; RV64IZFINXZDINX-NEXT: fmadd.d a0, a0, a1, a2915; RV64IZFINXZDINX-NEXT: fneg.d a0, a0916; RV64IZFINXZDINX-NEXT: ret917;918; RV32I-LABEL: fnmadd_d_3:919; RV32I: # %bb.0:920; RV32I-NEXT: addi sp, sp, -16921; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill922; RV32I-NEXT: call fma923; RV32I-NEXT: lui a2, 524288924; RV32I-NEXT: xor a1, a1, a2925; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload926; RV32I-NEXT: addi sp, sp, 16927; RV32I-NEXT: ret928;929; RV64I-LABEL: fnmadd_d_3:930; RV64I: # %bb.0:931; RV64I-NEXT: addi sp, sp, -16932; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill933; RV64I-NEXT: call fma934; RV64I-NEXT: li a1, -1935; RV64I-NEXT: slli a1, a1, 63936; RV64I-NEXT: xor a0, a0, a1937; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload938; RV64I-NEXT: addi sp, sp, 16939; RV64I-NEXT: ret940 %1 = call double @llvm.fma.f64(double %a, double %b, double %c)941 %neg = fneg double %1942 ret double %neg943}944 945define double @fnmadd_d_fmul_fneg(double %a, double %b, double %c, double %d) nounwind {946; CHECKIFD-LABEL: fnmadd_d_fmul_fneg:947; CHECKIFD: # %bb.0:948; CHECKIFD-NEXT: fmul.d fa5, fa1, fa0949; CHECKIFD-NEXT: fmsub.d fa0, fa2, fa3, fa5950; CHECKIFD-NEXT: ret951;952; RV32IZFINXZDINX-LABEL: fnmadd_d_fmul_fneg:953; RV32IZFINXZDINX: # %bb.0:954; RV32IZFINXZDINX-NEXT: fmul.d a0, a2, a0955; RV32IZFINXZDINX-NEXT: fmsub.d a0, a4, a6, a0956; RV32IZFINXZDINX-NEXT: ret957;958; RV64IZFINXZDINX-LABEL: fnmadd_d_fmul_fneg:959; RV64IZFINXZDINX: # %bb.0:960; RV64IZFINXZDINX-NEXT: fmul.d a0, a1, a0961; RV64IZFINXZDINX-NEXT: fmsub.d a0, a2, a3, a0962; RV64IZFINXZDINX-NEXT: ret963;964; RV32I-LABEL: fnmadd_d_fmul_fneg:965; RV32I: # %bb.0:966; RV32I-NEXT: addi sp, sp, -32967; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill968; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill969; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill970; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill971; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill972; RV32I-NEXT: mv s0, a7973; RV32I-NEXT: mv s1, a6974; RV32I-NEXT: mv s2, a5975; RV32I-NEXT: mv s3, a4976; RV32I-NEXT: mv a5, a3977; RV32I-NEXT: mv a4, a0978; RV32I-NEXT: lui a3, 524288979; RV32I-NEXT: xor a3, a1, a3980; RV32I-NEXT: mv a0, a2981; RV32I-NEXT: mv a1, a5982; RV32I-NEXT: mv a2, a4983; RV32I-NEXT: call __muldf3984; RV32I-NEXT: mv a4, a0985; RV32I-NEXT: mv a5, a1986; RV32I-NEXT: mv a0, s3987; RV32I-NEXT: mv a1, s2988; RV32I-NEXT: mv a2, s1989; RV32I-NEXT: mv a3, s0990; RV32I-NEXT: call fma991; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload992; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload993; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload994; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload995; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload996; RV32I-NEXT: addi sp, sp, 32997; RV32I-NEXT: ret998;999; RV64I-LABEL: fnmadd_d_fmul_fneg:1000; RV64I: # %bb.0:1001; RV64I-NEXT: addi sp, sp, -321002; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill1003; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill1004; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill1005; RV64I-NEXT: mv s0, a31006; RV64I-NEXT: mv s1, a21007; RV64I-NEXT: mv a2, a11008; RV64I-NEXT: li a1, -11009; RV64I-NEXT: slli a1, a1, 631010; RV64I-NEXT: xor a1, a0, a11011; RV64I-NEXT: mv a0, a21012; RV64I-NEXT: call __muldf31013; RV64I-NEXT: mv a2, a01014; RV64I-NEXT: mv a0, s11015; RV64I-NEXT: mv a1, s01016; RV64I-NEXT: call fma1017; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload1018; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload1019; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload1020; RV64I-NEXT: addi sp, sp, 321021; RV64I-NEXT: ret1022 %nega = fneg double %a1023 %mul = fmul double %b, %nega1024 %1 = call double @llvm.fma.f64(double %c, double %d, double %mul)1025 ret double %11026}1027 1028define double @fnmadd_nsz(double %a, double %b, double %c) nounwind {1029; CHECKIFD-LABEL: fnmadd_nsz:1030; CHECKIFD: # %bb.0:1031; CHECKIFD-NEXT: fnmadd.d fa0, fa0, fa1, fa21032; CHECKIFD-NEXT: ret1033;1034; RV32IZFINXZDINX-LABEL: fnmadd_nsz:1035; RV32IZFINXZDINX: # %bb.0:1036; RV32IZFINXZDINX-NEXT: fnmadd.d a0, a0, a2, a41037; RV32IZFINXZDINX-NEXT: ret1038;1039; RV64IZFINXZDINX-LABEL: fnmadd_nsz:1040; RV64IZFINXZDINX: # %bb.0:1041; RV64IZFINXZDINX-NEXT: fnmadd.d a0, a0, a1, a21042; RV64IZFINXZDINX-NEXT: ret1043;1044; RV32I-LABEL: fnmadd_nsz:1045; RV32I: # %bb.0:1046; RV32I-NEXT: addi sp, sp, -161047; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill1048; RV32I-NEXT: call fma1049; RV32I-NEXT: lui a2, 5242881050; RV32I-NEXT: xor a1, a1, a21051; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload1052; RV32I-NEXT: addi sp, sp, 161053; RV32I-NEXT: ret1054;1055; RV64I-LABEL: fnmadd_nsz:1056; RV64I: # %bb.0:1057; RV64I-NEXT: addi sp, sp, -161058; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill1059; RV64I-NEXT: call fma1060; RV64I-NEXT: li a1, -11061; RV64I-NEXT: slli a1, a1, 631062; RV64I-NEXT: xor a0, a0, a11063; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload1064; RV64I-NEXT: addi sp, sp, 161065; RV64I-NEXT: ret1066 %1 = call nsz double @llvm.fma.f64(double %a, double %b, double %c)1067 %neg = fneg nsz double %11068 ret double %neg1069}1070 1071define double @fnmsub_d(double %a, double %b, double %c) nounwind {1072; RV32IFD-LABEL: fnmsub_d:1073; RV32IFD: # %bb.0:1074; RV32IFD-NEXT: fcvt.d.w fa5, zero1075; RV32IFD-NEXT: fadd.d fa5, fa0, fa51076; RV32IFD-NEXT: fnmsub.d fa0, fa5, fa1, fa21077; RV32IFD-NEXT: ret1078;1079; RV64IFD-LABEL: fnmsub_d:1080; RV64IFD: # %bb.0:1081; RV64IFD-NEXT: fmv.d.x fa5, zero1082; RV64IFD-NEXT: fadd.d fa5, fa0, fa51083; RV64IFD-NEXT: fnmsub.d fa0, fa5, fa1, fa21084; RV64IFD-NEXT: ret1085;1086; RV32IZFINXZDINX-LABEL: fnmsub_d:1087; RV32IZFINXZDINX: # %bb.0:1088; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, zero1089; RV32IZFINXZDINX-NEXT: fnmsub.d a0, a0, a2, a41090; RV32IZFINXZDINX-NEXT: ret1091;1092; RV64IZFINXZDINX-LABEL: fnmsub_d:1093; RV64IZFINXZDINX: # %bb.0:1094; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, zero1095; RV64IZFINXZDINX-NEXT: fnmsub.d a0, a0, a1, a21096; RV64IZFINXZDINX-NEXT: ret1097;1098; RV32I-LABEL: fnmsub_d:1099; RV32I: # %bb.0:1100; RV32I-NEXT: addi sp, sp, -321101; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill1102; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill1103; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill1104; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill1105; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill1106; RV32I-NEXT: mv s0, a51107; RV32I-NEXT: mv s1, a41108; RV32I-NEXT: mv s2, a31109; RV32I-NEXT: mv s3, a21110; RV32I-NEXT: li a2, 01111; RV32I-NEXT: li a3, 01112; RV32I-NEXT: call __adddf31113; RV32I-NEXT: lui a2, 5242881114; RV32I-NEXT: xor a1, a1, a21115; RV32I-NEXT: mv a2, s31116; RV32I-NEXT: mv a3, s21117; RV32I-NEXT: mv a4, s11118; RV32I-NEXT: mv a5, s01119; RV32I-NEXT: call fma1120; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload1121; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload1122; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload1123; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload1124; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload1125; RV32I-NEXT: addi sp, sp, 321126; RV32I-NEXT: ret1127;1128; RV64I-LABEL: fnmsub_d:1129; RV64I: # %bb.0:1130; RV64I-NEXT: addi sp, sp, -321131; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill1132; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill1133; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill1134; RV64I-NEXT: mv s0, a21135; RV64I-NEXT: mv s1, a11136; RV64I-NEXT: li a1, 01137; RV64I-NEXT: call __adddf31138; RV64I-NEXT: li a1, -11139; RV64I-NEXT: slli a1, a1, 631140; RV64I-NEXT: xor a0, a0, a11141; RV64I-NEXT: mv a1, s11142; RV64I-NEXT: mv a2, s01143; RV64I-NEXT: call fma1144; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload1145; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload1146; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload1147; RV64I-NEXT: addi sp, sp, 321148; RV64I-NEXT: ret1149 %a_ = fadd double 0.0, %a1150 %nega = fsub double -0.0, %a_1151 %1 = call double @llvm.fma.f64(double %nega, double %b, double %c)1152 ret double %11153}1154 1155define double @fnmsub_d_2(double %a, double %b, double %c) nounwind {1156; RV32IFD-LABEL: fnmsub_d_2:1157; RV32IFD: # %bb.0:1158; RV32IFD-NEXT: fcvt.d.w fa5, zero1159; RV32IFD-NEXT: fadd.d fa5, fa1, fa51160; RV32IFD-NEXT: fnmsub.d fa0, fa5, fa0, fa21161; RV32IFD-NEXT: ret1162;1163; RV64IFD-LABEL: fnmsub_d_2:1164; RV64IFD: # %bb.0:1165; RV64IFD-NEXT: fmv.d.x fa5, zero1166; RV64IFD-NEXT: fadd.d fa5, fa1, fa51167; RV64IFD-NEXT: fnmsub.d fa0, fa5, fa0, fa21168; RV64IFD-NEXT: ret1169;1170; RV32IZFINXZDINX-LABEL: fnmsub_d_2:1171; RV32IZFINXZDINX: # %bb.0:1172; RV32IZFINXZDINX-NEXT: fadd.d a2, a2, zero1173; RV32IZFINXZDINX-NEXT: fnmsub.d a0, a2, a0, a41174; RV32IZFINXZDINX-NEXT: ret1175;1176; RV64IZFINXZDINX-LABEL: fnmsub_d_2:1177; RV64IZFINXZDINX: # %bb.0:1178; RV64IZFINXZDINX-NEXT: fadd.d a1, a1, zero1179; RV64IZFINXZDINX-NEXT: fnmsub.d a0, a1, a0, a21180; RV64IZFINXZDINX-NEXT: ret1181;1182; RV32I-LABEL: fnmsub_d_2:1183; RV32I: # %bb.0:1184; RV32I-NEXT: addi sp, sp, -321185; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill1186; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill1187; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill1188; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill1189; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill1190; RV32I-NEXT: mv s0, a51191; RV32I-NEXT: mv s1, a41192; RV32I-NEXT: mv s2, a11193; RV32I-NEXT: mv s3, a01194; RV32I-NEXT: mv a0, a21195; RV32I-NEXT: mv a1, a31196; RV32I-NEXT: li a2, 01197; RV32I-NEXT: li a3, 01198; RV32I-NEXT: call __adddf31199; RV32I-NEXT: mv a2, a01200; RV32I-NEXT: lui a3, 5242881201; RV32I-NEXT: xor a3, a1, a31202; RV32I-NEXT: mv a0, s31203; RV32I-NEXT: mv a1, s21204; RV32I-NEXT: mv a4, s11205; RV32I-NEXT: mv a5, s01206; RV32I-NEXT: call fma1207; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload1208; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload1209; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload1210; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload1211; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload1212; RV32I-NEXT: addi sp, sp, 321213; RV32I-NEXT: ret1214;1215; RV64I-LABEL: fnmsub_d_2:1216; RV64I: # %bb.0:1217; RV64I-NEXT: addi sp, sp, -321218; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill1219; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill1220; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill1221; RV64I-NEXT: mv s0, a21222; RV64I-NEXT: mv s1, a01223; RV64I-NEXT: mv a0, a11224; RV64I-NEXT: li a1, 01225; RV64I-NEXT: call __adddf31226; RV64I-NEXT: li a1, -11227; RV64I-NEXT: slli a1, a1, 631228; RV64I-NEXT: xor a1, a0, a11229; RV64I-NEXT: mv a0, s11230; RV64I-NEXT: mv a2, s01231; RV64I-NEXT: call fma1232; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload1233; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload1234; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload1235; RV64I-NEXT: addi sp, sp, 321236; RV64I-NEXT: ret1237 %b_ = fadd double 0.0, %b1238 %negb = fsub double -0.0, %b_1239 %1 = call double @llvm.fma.f64(double %a, double %negb, double %c)1240 ret double %11241}1242 1243define double @fmadd_d_contract(double %a, double %b, double %c) nounwind {1244; CHECKIFD-LABEL: fmadd_d_contract:1245; CHECKIFD: # %bb.0:1246; CHECKIFD-NEXT: fmadd.d fa0, fa0, fa1, fa21247; CHECKIFD-NEXT: ret1248;1249; RV32IZFINXZDINX-LABEL: fmadd_d_contract:1250; RV32IZFINXZDINX: # %bb.0:1251; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a41252; RV32IZFINXZDINX-NEXT: ret1253;1254; RV64IZFINXZDINX-LABEL: fmadd_d_contract:1255; RV64IZFINXZDINX: # %bb.0:1256; RV64IZFINXZDINX-NEXT: fmadd.d a0, a0, a1, a21257; RV64IZFINXZDINX-NEXT: ret1258;1259; RV32I-LABEL: fmadd_d_contract:1260; RV32I: # %bb.0:1261; RV32I-NEXT: addi sp, sp, -161262; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill1263; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill1264; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill1265; RV32I-NEXT: mv s0, a51266; RV32I-NEXT: mv s1, a41267; RV32I-NEXT: call __muldf31268; RV32I-NEXT: mv a2, s11269; RV32I-NEXT: mv a3, s01270; RV32I-NEXT: call __adddf31271; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload1272; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload1273; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload1274; RV32I-NEXT: addi sp, sp, 161275; RV32I-NEXT: ret1276;1277; RV64I-LABEL: fmadd_d_contract:1278; RV64I: # %bb.0:1279; RV64I-NEXT: addi sp, sp, -161280; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill1281; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill1282; RV64I-NEXT: mv s0, a21283; RV64I-NEXT: call __muldf31284; RV64I-NEXT: mv a1, s01285; RV64I-NEXT: call __adddf31286; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload1287; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload1288; RV64I-NEXT: addi sp, sp, 161289; RV64I-NEXT: ret1290 %1 = fmul contract double %a, %b1291 %2 = fadd contract double %1, %c1292 ret double %21293}1294 1295define double @fmsub_d_contract(double %a, double %b, double %c) nounwind {1296; RV32IFD-LABEL: fmsub_d_contract:1297; RV32IFD: # %bb.0:1298; RV32IFD-NEXT: fcvt.d.w fa5, zero1299; RV32IFD-NEXT: fadd.d fa5, fa2, fa51300; RV32IFD-NEXT: fmsub.d fa0, fa0, fa1, fa51301; RV32IFD-NEXT: ret1302;1303; RV64IFD-LABEL: fmsub_d_contract:1304; RV64IFD: # %bb.0:1305; RV64IFD-NEXT: fmv.d.x fa5, zero1306; RV64IFD-NEXT: fadd.d fa5, fa2, fa51307; RV64IFD-NEXT: fmsub.d fa0, fa0, fa1, fa51308; RV64IFD-NEXT: ret1309;1310; RV32IZFINXZDINX-LABEL: fmsub_d_contract:1311; RV32IZFINXZDINX: # %bb.0:1312; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, zero1313; RV32IZFINXZDINX-NEXT: fmsub.d a0, a0, a2, a41314; RV32IZFINXZDINX-NEXT: ret1315;1316; RV64IZFINXZDINX-LABEL: fmsub_d_contract:1317; RV64IZFINXZDINX: # %bb.0:1318; RV64IZFINXZDINX-NEXT: fadd.d a2, a2, zero1319; RV64IZFINXZDINX-NEXT: fmsub.d a0, a0, a1, a21320; RV64IZFINXZDINX-NEXT: ret1321;1322; RV32I-LABEL: fmsub_d_contract:1323; RV32I: # %bb.0:1324; RV32I-NEXT: addi sp, sp, -321325; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill1326; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill1327; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill1328; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill1329; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill1330; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill1331; RV32I-NEXT: sw s5, 4(sp) # 4-byte Folded Spill1332; RV32I-NEXT: mv s0, a31333; RV32I-NEXT: mv s1, a21334; RV32I-NEXT: mv s2, a11335; RV32I-NEXT: mv s3, a01336; RV32I-NEXT: mv a0, a41337; RV32I-NEXT: mv a1, a51338; RV32I-NEXT: li a2, 01339; RV32I-NEXT: li a3, 01340; RV32I-NEXT: call __adddf31341; RV32I-NEXT: mv s4, a01342; RV32I-NEXT: mv s5, a11343; RV32I-NEXT: mv a0, s31344; RV32I-NEXT: mv a1, s21345; RV32I-NEXT: mv a2, s11346; RV32I-NEXT: mv a3, s01347; RV32I-NEXT: call __muldf31348; RV32I-NEXT: mv a2, s41349; RV32I-NEXT: mv a3, s51350; RV32I-NEXT: call __subdf31351; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload1352; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload1353; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload1354; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload1355; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload1356; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload1357; RV32I-NEXT: lw s5, 4(sp) # 4-byte Folded Reload1358; RV32I-NEXT: addi sp, sp, 321359; RV32I-NEXT: ret1360;1361; RV64I-LABEL: fmsub_d_contract:1362; RV64I: # %bb.0:1363; RV64I-NEXT: addi sp, sp, -321364; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill1365; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill1366; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill1367; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill1368; RV64I-NEXT: mv s0, a11369; RV64I-NEXT: mv s1, a01370; RV64I-NEXT: mv a0, a21371; RV64I-NEXT: li a1, 01372; RV64I-NEXT: call __adddf31373; RV64I-NEXT: mv s2, a01374; RV64I-NEXT: mv a0, s11375; RV64I-NEXT: mv a1, s01376; RV64I-NEXT: call __muldf31377; RV64I-NEXT: mv a1, s21378; RV64I-NEXT: call __subdf31379; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload1380; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload1381; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload1382; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload1383; RV64I-NEXT: addi sp, sp, 321384; RV64I-NEXT: ret1385 %c_ = fadd double 0.0, %c ; avoid negation using xor1386 %1 = fmul contract double %a, %b1387 %2 = fsub contract double %1, %c_1388 ret double %21389}1390 1391define double @fnmadd_d_contract(double %a, double %b, double %c) nounwind {1392; RV32IFD-LABEL: fnmadd_d_contract:1393; RV32IFD: # %bb.0:1394; RV32IFD-NEXT: fcvt.d.w fa5, zero1395; RV32IFD-NEXT: fadd.d fa4, fa0, fa51396; RV32IFD-NEXT: fadd.d fa3, fa1, fa51397; RV32IFD-NEXT: fadd.d fa5, fa2, fa51398; RV32IFD-NEXT: fnmadd.d fa0, fa4, fa3, fa51399; RV32IFD-NEXT: ret1400;1401; RV64IFD-LABEL: fnmadd_d_contract:1402; RV64IFD: # %bb.0:1403; RV64IFD-NEXT: fmv.d.x fa5, zero1404; RV64IFD-NEXT: fadd.d fa4, fa0, fa51405; RV64IFD-NEXT: fadd.d fa3, fa1, fa51406; RV64IFD-NEXT: fadd.d fa5, fa2, fa51407; RV64IFD-NEXT: fnmadd.d fa0, fa4, fa3, fa51408; RV64IFD-NEXT: ret1409;1410; RV32IZFINXZDINX-LABEL: fnmadd_d_contract:1411; RV32IZFINXZDINX: # %bb.0:1412; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, zero1413; RV32IZFINXZDINX-NEXT: fadd.d a2, a2, zero1414; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, zero1415; RV32IZFINXZDINX-NEXT: fnmadd.d a0, a0, a2, a41416; RV32IZFINXZDINX-NEXT: ret1417;1418; RV64IZFINXZDINX-LABEL: fnmadd_d_contract:1419; RV64IZFINXZDINX: # %bb.0:1420; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, zero1421; RV64IZFINXZDINX-NEXT: fadd.d a1, a1, zero1422; RV64IZFINXZDINX-NEXT: fadd.d a2, a2, zero1423; RV64IZFINXZDINX-NEXT: fnmadd.d a0, a0, a1, a21424; RV64IZFINXZDINX-NEXT: ret1425;1426; RV32I-LABEL: fnmadd_d_contract:1427; RV32I: # %bb.0:1428; RV32I-NEXT: addi sp, sp, -321429; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill1430; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill1431; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill1432; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill1433; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill1434; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill1435; RV32I-NEXT: sw s5, 4(sp) # 4-byte Folded Spill1436; RV32I-NEXT: mv s0, a51437; RV32I-NEXT: mv s1, a41438; RV32I-NEXT: mv s2, a31439; RV32I-NEXT: mv s3, a21440; RV32I-NEXT: li a2, 01441; RV32I-NEXT: li a3, 01442; RV32I-NEXT: call __adddf31443; RV32I-NEXT: mv s4, a01444; RV32I-NEXT: mv s5, a11445; RV32I-NEXT: mv a0, s31446; RV32I-NEXT: mv a1, s21447; RV32I-NEXT: li a2, 01448; RV32I-NEXT: li a3, 01449; RV32I-NEXT: call __adddf31450; RV32I-NEXT: mv s2, a01451; RV32I-NEXT: mv s3, a11452; RV32I-NEXT: mv a0, s11453; RV32I-NEXT: mv a1, s01454; RV32I-NEXT: li a2, 01455; RV32I-NEXT: li a3, 01456; RV32I-NEXT: call __adddf31457; RV32I-NEXT: mv s0, a01458; RV32I-NEXT: mv s1, a11459; RV32I-NEXT: mv a0, s41460; RV32I-NEXT: mv a1, s51461; RV32I-NEXT: mv a2, s21462; RV32I-NEXT: mv a3, s31463; RV32I-NEXT: call __muldf31464; RV32I-NEXT: lui a2, 5242881465; RV32I-NEXT: xor a1, a1, a21466; RV32I-NEXT: mv a2, s01467; RV32I-NEXT: mv a3, s11468; RV32I-NEXT: call __subdf31469; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload1470; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload1471; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload1472; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload1473; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload1474; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload1475; RV32I-NEXT: lw s5, 4(sp) # 4-byte Folded Reload1476; RV32I-NEXT: addi sp, sp, 321477; RV32I-NEXT: ret1478;1479; RV64I-LABEL: fnmadd_d_contract:1480; RV64I: # %bb.0:1481; RV64I-NEXT: addi sp, sp, -321482; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill1483; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill1484; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill1485; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill1486; RV64I-NEXT: mv s0, a21487; RV64I-NEXT: mv s1, a11488; RV64I-NEXT: li a1, 01489; RV64I-NEXT: call __adddf31490; RV64I-NEXT: mv s2, a01491; RV64I-NEXT: mv a0, s11492; RV64I-NEXT: li a1, 01493; RV64I-NEXT: call __adddf31494; RV64I-NEXT: mv s1, a01495; RV64I-NEXT: mv a0, s01496; RV64I-NEXT: li a1, 01497; RV64I-NEXT: call __adddf31498; RV64I-NEXT: mv s0, a01499; RV64I-NEXT: mv a0, s21500; RV64I-NEXT: mv a1, s11501; RV64I-NEXT: call __muldf31502; RV64I-NEXT: li a1, -11503; RV64I-NEXT: slli a1, a1, 631504; RV64I-NEXT: xor a0, a0, a11505; RV64I-NEXT: mv a1, s01506; RV64I-NEXT: call __subdf31507; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload1508; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload1509; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload1510; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload1511; RV64I-NEXT: addi sp, sp, 321512; RV64I-NEXT: ret1513 %a_ = fadd double 0.0, %a ; avoid negation using xor1514 %b_ = fadd double 0.0, %b ; avoid negation using xor1515 %c_ = fadd double 0.0, %c ; avoid negation using xor1516 %1 = fmul contract double %a_, %b_1517 %2 = fneg double %11518 %3 = fsub contract double %2, %c_1519 ret double %31520}1521 1522define double @fnmsub_d_contract(double %a, double %b, double %c) nounwind {1523; RV32IFD-LABEL: fnmsub_d_contract:1524; RV32IFD: # %bb.0:1525; RV32IFD-NEXT: fcvt.d.w fa5, zero1526; RV32IFD-NEXT: fadd.d fa4, fa0, fa51527; RV32IFD-NEXT: fadd.d fa5, fa1, fa51528; RV32IFD-NEXT: fnmsub.d fa0, fa4, fa5, fa21529; RV32IFD-NEXT: ret1530;1531; RV64IFD-LABEL: fnmsub_d_contract:1532; RV64IFD: # %bb.0:1533; RV64IFD-NEXT: fmv.d.x fa5, zero1534; RV64IFD-NEXT: fadd.d fa4, fa0, fa51535; RV64IFD-NEXT: fadd.d fa5, fa1, fa51536; RV64IFD-NEXT: fnmsub.d fa0, fa4, fa5, fa21537; RV64IFD-NEXT: ret1538;1539; RV32IZFINXZDINX-LABEL: fnmsub_d_contract:1540; RV32IZFINXZDINX: # %bb.0:1541; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, zero1542; RV32IZFINXZDINX-NEXT: fadd.d a2, a2, zero1543; RV32IZFINXZDINX-NEXT: fnmsub.d a0, a0, a2, a41544; RV32IZFINXZDINX-NEXT: ret1545;1546; RV64IZFINXZDINX-LABEL: fnmsub_d_contract:1547; RV64IZFINXZDINX: # %bb.0:1548; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, zero1549; RV64IZFINXZDINX-NEXT: fadd.d a1, a1, zero1550; RV64IZFINXZDINX-NEXT: fnmsub.d a0, a0, a1, a21551; RV64IZFINXZDINX-NEXT: ret1552;1553; RV32I-LABEL: fnmsub_d_contract:1554; RV32I: # %bb.0:1555; RV32I-NEXT: addi sp, sp, -321556; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill1557; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill1558; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill1559; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill1560; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill1561; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill1562; RV32I-NEXT: sw s5, 4(sp) # 4-byte Folded Spill1563; RV32I-NEXT: mv s0, a51564; RV32I-NEXT: mv s1, a41565; RV32I-NEXT: mv s2, a31566; RV32I-NEXT: mv s3, a21567; RV32I-NEXT: li a2, 01568; RV32I-NEXT: li a3, 01569; RV32I-NEXT: call __adddf31570; RV32I-NEXT: mv s4, a01571; RV32I-NEXT: mv s5, a11572; RV32I-NEXT: mv a0, s31573; RV32I-NEXT: mv a1, s21574; RV32I-NEXT: li a2, 01575; RV32I-NEXT: li a3, 01576; RV32I-NEXT: call __adddf31577; RV32I-NEXT: mv a2, a01578; RV32I-NEXT: mv a3, a11579; RV32I-NEXT: mv a0, s41580; RV32I-NEXT: mv a1, s51581; RV32I-NEXT: call __muldf31582; RV32I-NEXT: mv a2, a01583; RV32I-NEXT: mv a3, a11584; RV32I-NEXT: mv a0, s11585; RV32I-NEXT: mv a1, s01586; RV32I-NEXT: call __subdf31587; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload1588; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload1589; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload1590; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload1591; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload1592; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload1593; RV32I-NEXT: lw s5, 4(sp) # 4-byte Folded Reload1594; RV32I-NEXT: addi sp, sp, 321595; RV32I-NEXT: ret1596;1597; RV64I-LABEL: fnmsub_d_contract:1598; RV64I: # %bb.0:1599; RV64I-NEXT: addi sp, sp, -321600; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill1601; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill1602; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill1603; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill1604; RV64I-NEXT: mv s0, a21605; RV64I-NEXT: mv s1, a11606; RV64I-NEXT: li a1, 01607; RV64I-NEXT: call __adddf31608; RV64I-NEXT: mv s2, a01609; RV64I-NEXT: mv a0, s11610; RV64I-NEXT: li a1, 01611; RV64I-NEXT: call __adddf31612; RV64I-NEXT: mv a1, a01613; RV64I-NEXT: mv a0, s21614; RV64I-NEXT: call __muldf31615; RV64I-NEXT: mv a1, a01616; RV64I-NEXT: mv a0, s01617; RV64I-NEXT: call __subdf31618; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload1619; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload1620; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload1621; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload1622; RV64I-NEXT: addi sp, sp, 321623; RV64I-NEXT: ret1624 %a_ = fadd double 0.0, %a ; avoid negation using xor1625 %b_ = fadd double 0.0, %b ; avoid negation using xor1626 %1 = fmul contract double %a_, %b_1627 %2 = fsub contract double %c, %11628 ret double %21629}1630 1631define double @fsgnjx_f64(double %x, double %y) nounwind {1632; CHECKIFD-LABEL: fsgnjx_f64:1633; CHECKIFD: # %bb.0:1634; CHECKIFD-NEXT: fsgnjx.d fa0, fa1, fa01635; CHECKIFD-NEXT: ret1636;1637; RV32IZFINXZDINX-LABEL: fsgnjx_f64:1638; RV32IZFINXZDINX: # %bb.0:1639; RV32IZFINXZDINX-NEXT: fsgnjx.d a0, a2, a01640; RV32IZFINXZDINX-NEXT: ret1641;1642; RV64IZFINXZDINX-LABEL: fsgnjx_f64:1643; RV64IZFINXZDINX: # %bb.0:1644; RV64IZFINXZDINX-NEXT: fsgnjx.d a0, a1, a01645; RV64IZFINXZDINX-NEXT: ret1646;1647; RV32I-LABEL: fsgnjx_f64:1648; RV32I: # %bb.0:1649; RV32I-NEXT: addi sp, sp, -161650; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill1651; RV32I-NEXT: lui a0, 5242881652; RV32I-NEXT: and a0, a1, a01653; RV32I-NEXT: lui a1, 2618881654; RV32I-NEXT: or a1, a0, a11655; RV32I-NEXT: li a0, 01656; RV32I-NEXT: call __muldf31657; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload1658; RV32I-NEXT: addi sp, sp, 161659; RV32I-NEXT: ret1660;1661; RV64I-LABEL: fsgnjx_f64:1662; RV64I: # %bb.0:1663; RV64I-NEXT: addi sp, sp, -161664; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill1665; RV64I-NEXT: srli a0, a0, 631666; RV64I-NEXT: li a2, 10231667; RV64I-NEXT: slli a0, a0, 631668; RV64I-NEXT: slli a2, a2, 521669; RV64I-NEXT: or a0, a0, a21670; RV64I-NEXT: call __muldf31671; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload1672; RV64I-NEXT: addi sp, sp, 161673; RV64I-NEXT: ret1674 %z = call double @llvm.copysign.f64(double 1.0, double %x)1675 %mul = fmul double %z, %y1676 ret double %mul1677}1678