421 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv32 -target-abi ilp32d -mattr=+zfa,+d < %s \3; RUN: | FileCheck --check-prefixes=CHECK,RV32IDZFA %s4; RUN: llc -mtriple=riscv64 -target-abi lp64d -mattr=+zfa,+d < %s \5; RUN: | FileCheck --check-prefixes=CHECK,RV64DZFA %s6 7define double @loadfpimm1() {8; CHECK-LABEL: loadfpimm1:9; CHECK: # %bb.0:10; CHECK-NEXT: fli.d fa0, 0.062511; CHECK-NEXT: ret12 ret double 0.062513}14 15define double @loadfpimm2() {16; CHECK-LABEL: loadfpimm2:17; CHECK: # %bb.0:18; CHECK-NEXT: fli.d fa0, 0.7519; CHECK-NEXT: ret20 ret double 0.7521}22 23define double @loadfpimm3() {24; CHECK-LABEL: loadfpimm3:25; CHECK: # %bb.0:26; CHECK-NEXT: fli.d fa0, 1.2527; CHECK-NEXT: ret28 ret double 1.2529}30 31define double @loadfpimm4() {32; CHECK-LABEL: loadfpimm4:33; CHECK: # %bb.0:34; CHECK-NEXT: fli.d fa0, 3.035; CHECK-NEXT: ret36 ret double 3.037}38 39define double @loadfpimm5() {40; CHECK-LABEL: loadfpimm5:41; CHECK: # %bb.0:42; CHECK-NEXT: fli.d fa0, 256.043; CHECK-NEXT: ret44 ret double 256.045}46 47define double @loadfpimm6() {48; CHECK-LABEL: loadfpimm6:49; CHECK: # %bb.0:50; CHECK-NEXT: fli.d fa0, inf51; CHECK-NEXT: ret52 ret double 0x7FF000000000000053}54 55define double @loadfpimm7() {56; CHECK-LABEL: loadfpimm7:57; CHECK: # %bb.0:58; CHECK-NEXT: fli.d fa0, nan59; CHECK-NEXT: ret60 ret double 0x7FF800000000000061}62 63define double @loadfpimm8() {64; CHECK-LABEL: loadfpimm8:65; CHECK: # %bb.0:66; CHECK-NEXT: fli.d fa0, min67; CHECK-NEXT: ret68 ret double 0x001000000000000069}70 71define double @loadfpimm9() {72; RV32IDZFA-LABEL: loadfpimm9:73; RV32IDZFA: # %bb.0:74; RV32IDZFA-NEXT: lui a0, %hi(.LCPI8_0)75; RV32IDZFA-NEXT: fld fa0, %lo(.LCPI8_0)(a0)76; RV32IDZFA-NEXT: ret77;78; RV64DZFA-LABEL: loadfpimm9:79; RV64DZFA: # %bb.0:80; RV64DZFA-NEXT: lui a0, 13196781; RV64DZFA-NEXT: slli a0, a0, 3382; RV64DZFA-NEXT: fmv.d.x fa0, a083; RV64DZFA-NEXT: ret84 ret double 255.085}86 87; Negative test. This is 1 * 2^256.88define double @loadfpimm10() {89; RV32IDZFA-LABEL: loadfpimm10:90; RV32IDZFA: # %bb.0:91; RV32IDZFA-NEXT: lui a0, %hi(.LCPI9_0)92; RV32IDZFA-NEXT: fld fa0, %lo(.LCPI9_0)(a0)93; RV32IDZFA-NEXT: ret94;95; RV64DZFA-LABEL: loadfpimm10:96; RV64DZFA: # %bb.0:97; RV64DZFA-NEXT: li a0, 198; RV64DZFA-NEXT: slli a0, a0, 6099; RV64DZFA-NEXT: fmv.d.x fa0, a0100; RV64DZFA-NEXT: ret101 ret double 0x1000000000000000102}103 104; Negative test. This is a qnan with payload of 1.105define double @loadfpimm11() {106; CHECK-LABEL: loadfpimm11:107; CHECK: # %bb.0:108; CHECK-NEXT: lui a0, %hi(.LCPI10_0)109; CHECK-NEXT: fld fa0, %lo(.LCPI10_0)(a0)110; CHECK-NEXT: ret111 ret double 0x7ff8000000000001112}113 114; Negative test. This is an snan with payload of 1.115define double @loadfpimm12() {116; CHECK-LABEL: loadfpimm12:117; CHECK: # %bb.0:118; CHECK-NEXT: lui a0, %hi(.LCPI11_0)119; CHECK-NEXT: fld fa0, %lo(.LCPI11_0)(a0)120; CHECK-NEXT: ret121 ret double 0x7ff0000000000001122}123 124; Negative test. This is the smallest denormal.125define double @loadfpimm13() {126; RV32IDZFA-LABEL: loadfpimm13:127; RV32IDZFA: # %bb.0:128; RV32IDZFA-NEXT: lui a0, %hi(.LCPI12_0)129; RV32IDZFA-NEXT: fld fa0, %lo(.LCPI12_0)(a0)130; RV32IDZFA-NEXT: ret131;132; RV64DZFA-LABEL: loadfpimm13:133; RV64DZFA: # %bb.0:134; RV64DZFA-NEXT: li a0, 1135; RV64DZFA-NEXT: fmv.d.x fa0, a0136; RV64DZFA-NEXT: ret137 ret double 0x0000000000000001138}139 140; Negative test. This is 2^-1023, a denormal.141define double @loadfpimm15() {142; RV32IDZFA-LABEL: loadfpimm15:143; RV32IDZFA: # %bb.0:144; RV32IDZFA-NEXT: lui a0, %hi(.LCPI13_0)145; RV32IDZFA-NEXT: fld fa0, %lo(.LCPI13_0)(a0)146; RV32IDZFA-NEXT: ret147;148; RV64DZFA-LABEL: loadfpimm15:149; RV64DZFA: # %bb.0:150; RV64DZFA-NEXT: li a0, 1151; RV64DZFA-NEXT: slli a0, a0, 51152; RV64DZFA-NEXT: fmv.d.x fa0, a0153; RV64DZFA-NEXT: ret154 ret double 0x0008000000000000155}156 157define double @loadfpimm16() {158; CHECK-LABEL: loadfpimm16:159; CHECK: # %bb.0:160; CHECK-NEXT: fli.d fa0, -1.0161; CHECK-NEXT: ret162 ret double -1.0163}164 165; Ensure fli isn't directly used for negated versions of numbers in the fli166; table.167define double @loadfpimm17() {168; CHECK-LABEL: loadfpimm17:169; CHECK: # %bb.0:170; CHECK-NEXT: fli.d fa5, 2.0171; CHECK-NEXT: fneg.d fa0, fa5172; CHECK-NEXT: ret173 ret double -2.0174}175 176; Ensure fli isn't directly used for negative min normal value.177define double @loadfpimm18() {178; CHECK-LABEL: loadfpimm18:179; CHECK: # %bb.0:180; CHECK-NEXT: fli.d fa5, min181; CHECK-NEXT: fneg.d fa0, fa5182; CHECK-NEXT: ret183 ret double 0x8010000000000000184}185 186define double @fminm_d(double %a, double %b) nounwind {187; CHECK-LABEL: fminm_d:188; CHECK: # %bb.0:189; CHECK-NEXT: fminm.d fa0, fa0, fa1190; CHECK-NEXT: ret191 %1 = call double @llvm.minimum.f64(double %a, double %b)192 ret double %1193}194 195define double @fmaxm_d(double %a, double %b) nounwind {196; CHECK-LABEL: fmaxm_d:197; CHECK: # %bb.0:198; CHECK-NEXT: fmaxm.d fa0, fa0, fa1199; CHECK-NEXT: ret200 %1 = call double @llvm.maximum.f64(double %a, double %b)201 ret double %1202}203 204define double @fround_d_1(double %a) nounwind {205; CHECK-LABEL: fround_d_1:206; CHECK: # %bb.0:207; CHECK-NEXT: fround.d fa0, fa0, rmm208; CHECK-NEXT: ret209 %call = tail call double @round(double %a) nounwind readnone210 ret double %call211}212 213declare double @round(double) nounwind readnone214 215define double @fround_d_2(double %a) nounwind {216; CHECK-LABEL: fround_d_2:217; CHECK: # %bb.0:218; CHECK-NEXT: fround.d fa0, fa0, rdn219; CHECK-NEXT: ret220 %call = tail call double @floor(double %a) nounwind readnone221 ret double %call222}223 224declare double @floor(double) nounwind readnone225 226define double @fround_d_3(double %a) nounwind {227; CHECK-LABEL: fround_d_3:228; CHECK: # %bb.0:229; CHECK-NEXT: fround.d fa0, fa0, rup230; CHECK-NEXT: ret231 %call = tail call double @ceil(double %a) nounwind readnone232 ret double %call233}234 235declare double @ceil(double) nounwind readnone236 237define double @fround_d_4(double %a) nounwind {238; CHECK-LABEL: fround_d_4:239; CHECK: # %bb.0:240; CHECK-NEXT: fround.d fa0, fa0, rtz241; CHECK-NEXT: ret242 %call = tail call double @trunc(double %a) nounwind readnone243 ret double %call244}245 246declare double @trunc(double) nounwind readnone247 248define double @fround_d_5(double %a) nounwind {249; CHECK-LABEL: fround_d_5:250; CHECK: # %bb.0:251; CHECK-NEXT: fround.d fa0, fa0252; CHECK-NEXT: ret253 %call = tail call double @nearbyint(double %a) nounwind readnone254 ret double %call255}256 257declare double @nearbyint(double) nounwind readnone258 259define double @fround_d_6(double %a) nounwind {260; CHECK-LABEL: fround_d_6:261; CHECK: # %bb.0:262; CHECK-NEXT: fround.d fa0, fa0, rne263; CHECK-NEXT: ret264 %call = tail call double @llvm.roundeven.f64(double %a) nounwind readnone265 ret double %call266}267 268define double @froundnx_d(double %a) nounwind {269; CHECK-LABEL: froundnx_d:270; CHECK: # %bb.0:271; CHECK-NEXT: froundnx.d fa0, fa0272; CHECK-NEXT: ret273 %call = tail call double @rint(double %a) nounwind readnone274 ret double %call275}276 277declare double @rint(double) nounwind readnone278 279define i32 @fcmp_olt_q(double %a, double %b) nounwind strictfp {280; CHECK-LABEL: fcmp_olt_q:281; CHECK: # %bb.0:282; CHECK-NEXT: fltq.d a0, fa0, fa1283; CHECK-NEXT: ret284 %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"olt", metadata !"fpexcept.strict") strictfp285 %2 = zext i1 %1 to i32286 ret i32 %2287}288 289define i32 @fcmp_ole_q(double %a, double %b) nounwind strictfp {290; CHECK-LABEL: fcmp_ole_q:291; CHECK: # %bb.0:292; CHECK-NEXT: fleq.d a0, fa0, fa1293; CHECK-NEXT: ret294 %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ole", metadata !"fpexcept.strict") strictfp295 %2 = zext i1 %1 to i32296 ret i32 %2297}298 299define i32 @fcmp_one_q(double %a, double %b) nounwind strictfp {300; CHECK-LABEL: fcmp_one_q:301; CHECK: # %bb.0:302; CHECK-NEXT: fltq.d a0, fa0, fa1303; CHECK-NEXT: fltq.d a1, fa1, fa0304; CHECK-NEXT: or a0, a1, a0305; CHECK-NEXT: ret306 %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"one", metadata !"fpexcept.strict") strictfp307 %2 = zext i1 %1 to i32308 ret i32 %2309}310 311define i32 @fcmp_ueq_q(double %a, double %b) nounwind strictfp {312; CHECK-LABEL: fcmp_ueq_q:313; CHECK: # %bb.0:314; CHECK-NEXT: fltq.d a0, fa0, fa1315; CHECK-NEXT: fltq.d a1, fa1, fa0316; CHECK-NEXT: or a0, a1, a0317; CHECK-NEXT: xori a0, a0, 1318; CHECK-NEXT: ret319 %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ueq", metadata !"fpexcept.strict") strictfp320 %2 = zext i1 %1 to i32321 ret i32 %2322}323 324define i64 @fmvh_x_d(double %fa) {325; RV32IDZFA-LABEL: fmvh_x_d:326; RV32IDZFA: # %bb.0:327; RV32IDZFA-NEXT: fmv.x.w a0, fa0328; RV32IDZFA-NEXT: fmvh.x.d a1, fa0329; RV32IDZFA-NEXT: ret330;331; RV64DZFA-LABEL: fmvh_x_d:332; RV64DZFA: # %bb.0:333; RV64DZFA-NEXT: fmv.x.d a0, fa0334; RV64DZFA-NEXT: ret335 %i = bitcast double %fa to i64336 ret i64 %i337}338 339define double @fmvp_d_x(i64 %a) {340; RV32IDZFA-LABEL: fmvp_d_x:341; RV32IDZFA: # %bb.0:342; RV32IDZFA-NEXT: fmvp.d.x fa0, a0, a1343; RV32IDZFA-NEXT: ret344;345; RV64DZFA-LABEL: fmvp_d_x:346; RV64DZFA: # %bb.0:347; RV64DZFA-NEXT: fmv.d.x fa0, a0348; RV64DZFA-NEXT: ret349 %or = bitcast i64 %a to double350 ret double %or351}352 353define double @fadd_neg_0p5(double %x) {354; CHECK-LABEL: fadd_neg_0p5:355; CHECK: # %bb.0:356; CHECK-NEXT: fli.d fa5, 0.5357; CHECK-NEXT: fsub.d fa0, fa0, fa5358; CHECK-NEXT: ret359 %a = fadd double %x, -0.5360 ret double %a361}362 363define double @fma_neg_addend(double %x, double %y) nounwind {364; CHECK-LABEL: fma_neg_addend:365; CHECK: # %bb.0:366; CHECK-NEXT: fli.d fa5, 0.5367; CHECK-NEXT: fmsub.d fa0, fa0, fa1, fa5368; CHECK-NEXT: ret369 %a = call double @llvm.fma.f32(double %x, double %y, double -0.5)370 ret double %a371}372 373define double @fma_neg_multiplicand(double %x, double %y) nounwind {374; CHECK-LABEL: fma_neg_multiplicand:375; CHECK: # %bb.0:376; CHECK-NEXT: fli.d fa5, 0.125377; CHECK-NEXT: fnmsub.d fa0, fa5, fa0, fa1378; CHECK-NEXT: ret379 %a = call double @llvm.fma.f32(double %x, double -0.125, double %y)380 ret double %a381}382 383define double @fma_neg_addend_multiplicand(double %x) nounwind {384; CHECK-LABEL: fma_neg_addend_multiplicand:385; CHECK: # %bb.0:386; CHECK-NEXT: fli.d fa5, 0.25387; CHECK-NEXT: fli.d fa4, 0.5388; CHECK-NEXT: fnmadd.d fa0, fa4, fa0, fa5389; CHECK-NEXT: ret390 %a = call double @llvm.fma.f32(double %x, double -0.5, double -0.25)391 ret double %a392}393 394define double @select_loadfpimm(double %x) nounwind {395; RV32IDZFA-LABEL: select_loadfpimm:396; RV32IDZFA: # %bb.0: # %entry397; RV32IDZFA-NEXT: fcvt.d.w fa5, zero398; RV32IDZFA-NEXT: fle.d a0, fa5, fa0399; RV32IDZFA-NEXT: fli.d fa0, 0.5400; RV32IDZFA-NEXT: bnez a0, .LBB36_2401; RV32IDZFA-NEXT: # %bb.1:402; RV32IDZFA-NEXT: fneg.d fa0, fa0403; RV32IDZFA-NEXT: .LBB36_2: # %entry404; RV32IDZFA-NEXT: ret405;406; RV64DZFA-LABEL: select_loadfpimm:407; RV64DZFA: # %bb.0: # %entry408; RV64DZFA-NEXT: fmv.d.x fa5, zero409; RV64DZFA-NEXT: fle.d a0, fa5, fa0410; RV64DZFA-NEXT: fli.d fa0, 0.5411; RV64DZFA-NEXT: bnez a0, .LBB36_2412; RV64DZFA-NEXT: # %bb.1:413; RV64DZFA-NEXT: fneg.d fa0, fa0414; RV64DZFA-NEXT: .LBB36_2: # %entry415; RV64DZFA-NEXT: ret416entry:417 %cmp = fcmp ult double %x, 0.000000e+00418 %sel = select i1 %cmp, double -5.000000e-01, double 5.000000e-01419 ret double %sel420}421