362 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck %s3 4; Test that basic 64-bit floating-point operations assemble as expected.5 6target triple = "wasm32-unknown-unknown"7 8declare double @llvm.fabs.f64(double)9declare double @llvm.copysign.f64(double, double)10declare double @llvm.sqrt.f64(double)11declare double @llvm.ceil.f64(double)12declare double @llvm.floor.f64(double)13declare double @llvm.trunc.f64(double)14declare double @llvm.nearbyint.f64(double)15declare double @llvm.rint.f64(double)16declare double @llvm.roundeven.f64(double)17declare double @llvm.fma.f64(double, double, double)18 19define double @fadd64(double %x, double %y) {20; CHECK-LABEL: fadd64:21; CHECK: .functype fadd64 (f64, f64) -> (f64)22; CHECK-NEXT: # %bb.0:23; CHECK-NEXT: local.get $push2=, 024; CHECK-NEXT: local.get $push1=, 125; CHECK-NEXT: f64.add $push0=, $pop2, $pop126; CHECK-NEXT: return $pop027 %a = fadd double %x, %y28 ret double %a29}30 31define double @fsub64(double %x, double %y) {32; CHECK-LABEL: fsub64:33; CHECK: .functype fsub64 (f64, f64) -> (f64)34; CHECK-NEXT: # %bb.0:35; CHECK-NEXT: local.get $push2=, 036; CHECK-NEXT: local.get $push1=, 137; CHECK-NEXT: f64.sub $push0=, $pop2, $pop138; CHECK-NEXT: return $pop039 %a = fsub double %x, %y40 ret double %a41}42 43define double @fmul64(double %x, double %y) {44; CHECK-LABEL: fmul64:45; CHECK: .functype fmul64 (f64, f64) -> (f64)46; CHECK-NEXT: # %bb.0:47; CHECK-NEXT: local.get $push2=, 048; CHECK-NEXT: local.get $push1=, 149; CHECK-NEXT: f64.mul $push0=, $pop2, $pop150; CHECK-NEXT: return $pop051 %a = fmul double %x, %y52 ret double %a53}54 55define double @fdiv64(double %x, double %y) {56; CHECK-LABEL: fdiv64:57; CHECK: .functype fdiv64 (f64, f64) -> (f64)58; CHECK-NEXT: # %bb.0:59; CHECK-NEXT: local.get $push2=, 060; CHECK-NEXT: local.get $push1=, 161; CHECK-NEXT: f64.div $push0=, $pop2, $pop162; CHECK-NEXT: return $pop063 %a = fdiv double %x, %y64 ret double %a65}66 67define double @fabs64(double %x) {68; CHECK-LABEL: fabs64:69; CHECK: .functype fabs64 (f64) -> (f64)70; CHECK-NEXT: # %bb.0:71; CHECK-NEXT: local.get $push1=, 072; CHECK-NEXT: f64.abs $push0=, $pop173; CHECK-NEXT: return $pop074 %a = call double @llvm.fabs.f64(double %x)75 ret double %a76}77 78define double @fneg64(double %x) {79; CHECK-LABEL: fneg64:80; CHECK: .functype fneg64 (f64) -> (f64)81; CHECK-NEXT: # %bb.0:82; CHECK-NEXT: local.get $push1=, 083; CHECK-NEXT: f64.neg $push0=, $pop184; CHECK-NEXT: return $pop085 %a = fsub double -0., %x86 ret double %a87}88 89define double @copysign64(double %x, double %y) {90; CHECK-LABEL: copysign64:91; CHECK: .functype copysign64 (f64, f64) -> (f64)92; CHECK-NEXT: # %bb.0:93; CHECK-NEXT: local.get $push2=, 094; CHECK-NEXT: local.get $push1=, 195; CHECK-NEXT: f64.copysign $push0=, $pop2, $pop196; CHECK-NEXT: return $pop097 %a = call double @llvm.copysign.f64(double %x, double %y)98 ret double %a99}100 101define double @sqrt64(double %x) {102; CHECK-LABEL: sqrt64:103; CHECK: .functype sqrt64 (f64) -> (f64)104; CHECK-NEXT: # %bb.0:105; CHECK-NEXT: local.get $push1=, 0106; CHECK-NEXT: f64.sqrt $push0=, $pop1107; CHECK-NEXT: return $pop0108 %a = call double @llvm.sqrt.f64(double %x)109 ret double %a110}111 112define double @ceil64(double %x) {113; CHECK-LABEL: ceil64:114; CHECK: .functype ceil64 (f64) -> (f64)115; CHECK-NEXT: # %bb.0:116; CHECK-NEXT: local.get $push1=, 0117; CHECK-NEXT: f64.ceil $push0=, $pop1118; CHECK-NEXT: return $pop0119 %a = call double @llvm.ceil.f64(double %x)120 ret double %a121}122 123define double @floor64(double %x) {124; CHECK-LABEL: floor64:125; CHECK: .functype floor64 (f64) -> (f64)126; CHECK-NEXT: # %bb.0:127; CHECK-NEXT: local.get $push1=, 0128; CHECK-NEXT: f64.floor $push0=, $pop1129; CHECK-NEXT: return $pop0130 %a = call double @llvm.floor.f64(double %x)131 ret double %a132}133 134define double @trunc64(double %x) {135; CHECK-LABEL: trunc64:136; CHECK: .functype trunc64 (f64) -> (f64)137; CHECK-NEXT: # %bb.0:138; CHECK-NEXT: local.get $push1=, 0139; CHECK-NEXT: f64.trunc $push0=, $pop1140; CHECK-NEXT: return $pop0141 %a = call double @llvm.trunc.f64(double %x)142 ret double %a143}144 145define double @nearest64(double %x) {146; CHECK-LABEL: nearest64:147; CHECK: .functype nearest64 (f64) -> (f64)148; CHECK-NEXT: # %bb.0:149; CHECK-NEXT: local.get $push1=, 0150; CHECK-NEXT: f64.nearest $push0=, $pop1151; CHECK-NEXT: return $pop0152 %a = call double @llvm.nearbyint.f64(double %x)153 ret double %a154}155 156define double @nearest64_via_rint(double %x) {157; CHECK-LABEL: nearest64_via_rint:158; CHECK: .functype nearest64_via_rint (f64) -> (f64)159; CHECK-NEXT: # %bb.0:160; CHECK-NEXT: local.get $push1=, 0161; CHECK-NEXT: f64.nearest $push0=, $pop1162; CHECK-NEXT: return $pop0163 %a = call double @llvm.rint.f64(double %x)164 ret double %a165}166 167define double @nearest64_via_roundeven(double %x) {168; CHECK-LABEL: nearest64_via_roundeven:169; CHECK: .functype nearest64_via_roundeven (f64) -> (f64)170; CHECK-NEXT: # %bb.0:171; CHECK-NEXT: local.get $push1=, 0172; CHECK-NEXT: f64.nearest $push0=, $pop1173; CHECK-NEXT: return $pop0174 %a = call double @llvm.roundeven.f64(double %x)175 ret double %a176}177 178; This is not "minimum" because a -0.0 input returns +0.0.179 180define double @fmin64(double %x) {181; CHECK-LABEL: fmin64:182; CHECK: .functype fmin64 (f64) -> (f64)183; CHECK-NEXT: # %bb.0:184; CHECK-NEXT: f64.const $push0=, 0x0p0185; CHECK-NEXT: local.get $push5=, 0186; CHECK-NEXT: local.get $push4=, 0187; CHECK-NEXT: f64.const $push3=, 0x0p0188; CHECK-NEXT: f64.ge $push1=, $pop4, $pop3189; CHECK-NEXT: f64.select $push2=, $pop0, $pop5, $pop1190; CHECK-NEXT: return $pop2191 %a = fcmp ult double %x, 0.0192 %b = select i1 %a, double %x, double 0.0193 ret double %b194}195 196; This is not "maximum" because a -0.0 input returns +0.0.197 198define double @fmax64(double %x) {199; CHECK-LABEL: fmax64:200; CHECK: .functype fmax64 (f64) -> (f64)201; CHECK-NEXT: # %bb.0:202; CHECK-NEXT: f64.const $push0=, 0x0p0203; CHECK-NEXT: local.get $push5=, 0204; CHECK-NEXT: local.get $push4=, 0205; CHECK-NEXT: f64.const $push3=, 0x0p0206; CHECK-NEXT: f64.le $push1=, $pop4, $pop3207; CHECK-NEXT: f64.select $push2=, $pop0, $pop5, $pop1208; CHECK-NEXT: return $pop2209 %a = fcmp ugt double %x, 0.0210 %b = select i1 %a, double %x, double 0.0211 ret double %b212}213 214declare double @llvm.minimum.f64(double, double)215define double @fmin64_intrinsic(double %x, double %y) {216; CHECK-LABEL: fmin64_intrinsic:217; CHECK: .functype fmin64_intrinsic (f64, f64) -> (f64)218; CHECK-NEXT: # %bb.0:219; CHECK-NEXT: local.get $push2=, 0220; CHECK-NEXT: local.get $push1=, 1221; CHECK-NEXT: f64.min $push0=, $pop2, $pop1222; CHECK-NEXT: return $pop0223 %a = call double @llvm.minimum.f64(double %x, double %y)224 ret double %a225}226 227declare double @llvm.minnum.f64(double, double)228define double @fminnum64_intrinsic(double %x, double %y) {229; CHECK-LABEL: fminnum64_intrinsic:230; CHECK: .functype fminnum64_intrinsic (f64, f64) -> (f64)231; CHECK-NEXT: # %bb.0:232; CHECK-NEXT: local.get $push5=, 0233; CHECK-NEXT: local.get $push4=, 1234; CHECK-NEXT: local.get $push3=, 0235; CHECK-NEXT: local.get $push2=, 1236; CHECK-NEXT: f64.lt $push0=, $pop3, $pop2237; CHECK-NEXT: f64.select $push1=, $pop5, $pop4, $pop0238; CHECK-NEXT: return $pop1239 %a = call nnan double @llvm.minnum.f64(double %x, double %y)240 ret double %a241}242 243define double @fminnum64_nsz_intrinsic(double %x, double %y) {244; CHECK-LABEL: fminnum64_nsz_intrinsic:245; CHECK: .functype fminnum64_nsz_intrinsic (f64, f64) -> (f64)246; CHECK-NEXT: # %bb.0:247; CHECK-NEXT: local.get $push2=, 0248; CHECK-NEXT: local.get $push1=, 1249; CHECK-NEXT: f64.min $push0=, $pop2, $pop1250; CHECK-NEXT: return $pop0251 %a = call nnan nsz double @llvm.minnum.f64(double %x, double %y)252 ret double %a253}254 255define double @fminnum64_zero_intrinsic(double %x) {256; CHECK-LABEL: fminnum64_zero_intrinsic:257; CHECK: .functype fminnum64_zero_intrinsic (f64) -> (f64)258; CHECK-NEXT: # %bb.0:259; CHECK-NEXT: local.get $push5=, 0260; CHECK-NEXT: f64.const $push0=, -0x0p0261; CHECK-NEXT: local.get $push4=, 0262; CHECK-NEXT: f64.const $push3=, -0x0p0263; CHECK-NEXT: f64.lt $push1=, $pop4, $pop3264; CHECK-NEXT: f64.select $push2=, $pop5, $pop0, $pop1265; CHECK-NEXT: return $pop2266 %a = call nnan double @llvm.minnum.f64(double %x, double -0.0)267 ret double %a268}269 270define double @fminnum64_non_zero_intrinsic(double %x) {271; CHECK-LABEL: fminnum64_non_zero_intrinsic:272; CHECK: .functype fminnum64_non_zero_intrinsic (f64) -> (f64)273; CHECK-NEXT: # %bb.0:274; CHECK-NEXT: local.get $push2=, 0275; CHECK-NEXT: f64.const $push0=, -0x1p0276; CHECK-NEXT: f64.min $push1=, $pop2, $pop0277; CHECK-NEXT: return $pop1278 %a = call nnan double @llvm.minnum.f64(double %x, double -1.0)279 ret double %a280}281 282declare double @llvm.maximum.f64(double, double)283define double @fmax64_intrinsic(double %x, double %y) {284; CHECK-LABEL: fmax64_intrinsic:285; CHECK: .functype fmax64_intrinsic (f64, f64) -> (f64)286; CHECK-NEXT: # %bb.0:287; CHECK-NEXT: local.get $push2=, 0288; CHECK-NEXT: local.get $push1=, 1289; CHECK-NEXT: f64.max $push0=, $pop2, $pop1290; CHECK-NEXT: return $pop0291 %a = call double @llvm.maximum.f64(double %x, double %y)292 ret double %a293}294 295declare double @llvm.maxnum.f64(double, double)296define double@fmaxnum64_intrinsic(double %x, double %y) {297; CHECK-LABEL: fmaxnum64_intrinsic:298; CHECK: .functype fmaxnum64_intrinsic (f64, f64) -> (f64)299; CHECK-NEXT: # %bb.0:300; CHECK-NEXT: local.get $push5=, 0301; CHECK-NEXT: local.get $push4=, 1302; CHECK-NEXT: local.get $push3=, 0303; CHECK-NEXT: local.get $push2=, 1304; CHECK-NEXT: f64.gt $push0=, $pop3, $pop2305; CHECK-NEXT: f64.select $push1=, $pop5, $pop4, $pop0306; CHECK-NEXT: return $pop1307 %a = call nnan double @llvm.maxnum.f64(double %x, double %y)308 ret double %a309}310 311define double@fmaxnum64_nsz_intrinsic(double %x, double %y) {312; CHECK-LABEL: fmaxnum64_nsz_intrinsic:313; CHECK: .functype fmaxnum64_nsz_intrinsic (f64, f64) -> (f64)314; CHECK-NEXT: # %bb.0:315; CHECK-NEXT: local.get $push2=, 0316; CHECK-NEXT: local.get $push1=, 1317; CHECK-NEXT: f64.max $push0=, $pop2, $pop1318; CHECK-NEXT: return $pop0319 %a = call nnan nsz double @llvm.maxnum.f64(double %x, double %y)320 ret double %a321}322 323define double @fmaxnum64_zero_intrinsic(double %x) {324; CHECK-LABEL: fmaxnum64_zero_intrinsic:325; CHECK: .functype fmaxnum64_zero_intrinsic (f64) -> (f64)326; CHECK-NEXT: # %bb.0:327; CHECK-NEXT: local.get $push5=, 0328; CHECK-NEXT: f64.const $push0=, 0x0p0329; CHECK-NEXT: local.get $push4=, 0330; CHECK-NEXT: f64.const $push3=, 0x0p0331; CHECK-NEXT: f64.gt $push1=, $pop4, $pop3332; CHECK-NEXT: f64.select $push2=, $pop5, $pop0, $pop1333; CHECK-NEXT: return $pop2334 %a = call nnan double @llvm.maxnum.f64(double %x, double 0.0)335 ret double %a336}337 338define double @fmaxnum64_non_zero_intrinsic(double %x) {339; CHECK-LABEL: fmaxnum64_non_zero_intrinsic:340; CHECK: .functype fmaxnum64_non_zero_intrinsic (f64) -> (f64)341; CHECK-NEXT: # %bb.0:342; CHECK-NEXT: local.get $push2=, 0343; CHECK-NEXT: f64.const $push0=, 0x1p0344; CHECK-NEXT: f64.max $push1=, $pop2, $pop0345; CHECK-NEXT: return $pop1346 %a = call nnan double @llvm.maxnum.f64(double %x, double 1.0)347 ret double %a348}349 350define double @fma64(double %a, double %b, double %c) {351; CHECK-LABEL: fma64:352; CHECK: .functype fma64 (f64, f64, f64) -> (f64)353; CHECK-NEXT: # %bb.0:354; CHECK-NEXT: local.get $push3=, 0355; CHECK-NEXT: local.get $push2=, 1356; CHECK-NEXT: local.get $push1=, 2357; CHECK-NEXT: call $push0=, fma, $pop3, $pop2, $pop1358; CHECK-NEXT: return $pop0359 %d = call double @llvm.fma.f64(double %a, double %b, double %c)360 ret double %d361}362