347 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 32-bit floating-point operations assemble as expected.5 6target triple = "wasm32-unknown-unknown"7 8declare float @llvm.fabs.f32(float)9declare float @llvm.copysign.f32(float, float)10declare float @llvm.sqrt.f32(float)11declare float @llvm.ceil.f32(float)12declare float @llvm.floor.f32(float)13declare float @llvm.trunc.f32(float)14declare float @llvm.nearbyint.f32(float)15declare float @llvm.rint.f32(float)16declare float @llvm.roundeven.f32(float)17declare float @llvm.fma.f32(float, float, float)18 19define float @fadd32(float %x, float %y) {20; CHECK-LABEL: fadd32:21; CHECK: .functype fadd32 (f32, f32) -> (f32)22; CHECK-NEXT: # %bb.0:23; CHECK-NEXT: local.get $push2=, 024; CHECK-NEXT: local.get $push1=, 125; CHECK-NEXT: f32.add $push0=, $pop2, $pop126; CHECK-NEXT: return $pop027 %a = fadd float %x, %y28 ret float %a29}30 31define float @fsub32(float %x, float %y) {32; CHECK-LABEL: fsub32:33; CHECK: .functype fsub32 (f32, f32) -> (f32)34; CHECK-NEXT: # %bb.0:35; CHECK-NEXT: local.get $push2=, 036; CHECK-NEXT: local.get $push1=, 137; CHECK-NEXT: f32.sub $push0=, $pop2, $pop138; CHECK-NEXT: return $pop039 %a = fsub float %x, %y40 ret float %a41}42 43define float @fmul32(float %x, float %y) {44; CHECK-LABEL: fmul32:45; CHECK: .functype fmul32 (f32, f32) -> (f32)46; CHECK-NEXT: # %bb.0:47; CHECK-NEXT: local.get $push2=, 048; CHECK-NEXT: local.get $push1=, 149; CHECK-NEXT: f32.mul $push0=, $pop2, $pop150; CHECK-NEXT: return $pop051 %a = fmul float %x, %y52 ret float %a53}54 55define float @fdiv32(float %x, float %y) {56; CHECK-LABEL: fdiv32:57; CHECK: .functype fdiv32 (f32, f32) -> (f32)58; CHECK-NEXT: # %bb.0:59; CHECK-NEXT: local.get $push2=, 060; CHECK-NEXT: local.get $push1=, 161; CHECK-NEXT: f32.div $push0=, $pop2, $pop162; CHECK-NEXT: return $pop063 %a = fdiv float %x, %y64 ret float %a65}66 67define float @fabs32(float %x) {68; CHECK-LABEL: fabs32:69; CHECK: .functype fabs32 (f32) -> (f32)70; CHECK-NEXT: # %bb.0:71; CHECK-NEXT: local.get $push1=, 072; CHECK-NEXT: f32.abs $push0=, $pop173; CHECK-NEXT: return $pop074 %a = call float @llvm.fabs.f32(float %x)75 ret float %a76}77 78define float @fneg32(float %x) {79; CHECK-LABEL: fneg32:80; CHECK: .functype fneg32 (f32) -> (f32)81; CHECK-NEXT: # %bb.0:82; CHECK-NEXT: local.get $push1=, 083; CHECK-NEXT: f32.neg $push0=, $pop184; CHECK-NEXT: return $pop085 %a = fsub float -0., %x86 ret float %a87}88 89define float @copysign32(float %x, float %y) {90; CHECK-LABEL: copysign32:91; CHECK: .functype copysign32 (f32, f32) -> (f32)92; CHECK-NEXT: # %bb.0:93; CHECK-NEXT: local.get $push2=, 094; CHECK-NEXT: local.get $push1=, 195; CHECK-NEXT: f32.copysign $push0=, $pop2, $pop196; CHECK-NEXT: return $pop097 %a = call float @llvm.copysign.f32(float %x, float %y)98 ret float %a99}100 101define float @sqrt32(float %x) {102; CHECK-LABEL: sqrt32:103; CHECK: .functype sqrt32 (f32) -> (f32)104; CHECK-NEXT: # %bb.0:105; CHECK-NEXT: local.get $push1=, 0106; CHECK-NEXT: f32.sqrt $push0=, $pop1107; CHECK-NEXT: return $pop0108 %a = call float @llvm.sqrt.f32(float %x)109 ret float %a110}111 112define float @ceil32(float %x) {113; CHECK-LABEL: ceil32:114; CHECK: .functype ceil32 (f32) -> (f32)115; CHECK-NEXT: # %bb.0:116; CHECK-NEXT: local.get $push1=, 0117; CHECK-NEXT: f32.ceil $push0=, $pop1118; CHECK-NEXT: return $pop0119 %a = call float @llvm.ceil.f32(float %x)120 ret float %a121}122 123define float @floor32(float %x) {124; CHECK-LABEL: floor32:125; CHECK: .functype floor32 (f32) -> (f32)126; CHECK-NEXT: # %bb.0:127; CHECK-NEXT: local.get $push1=, 0128; CHECK-NEXT: f32.floor $push0=, $pop1129; CHECK-NEXT: return $pop0130 %a = call float @llvm.floor.f32(float %x)131 ret float %a132}133 134define float @trunc32(float %x) {135; CHECK-LABEL: trunc32:136; CHECK: .functype trunc32 (f32) -> (f32)137; CHECK-NEXT: # %bb.0:138; CHECK-NEXT: local.get $push1=, 0139; CHECK-NEXT: f32.trunc $push0=, $pop1140; CHECK-NEXT: return $pop0141 %a = call float @llvm.trunc.f32(float %x)142 ret float %a143}144 145define float @nearest32(float %x) {146; CHECK-LABEL: nearest32:147; CHECK: .functype nearest32 (f32) -> (f32)148; CHECK-NEXT: # %bb.0:149; CHECK-NEXT: local.get $push1=, 0150; CHECK-NEXT: f32.nearest $push0=, $pop1151; CHECK-NEXT: return $pop0152 %a = call float @llvm.nearbyint.f32(float %x)153 ret float %a154}155 156define float @nearest32_via_rint(float %x) {157; CHECK-LABEL: nearest32_via_rint:158; CHECK: .functype nearest32_via_rint (f32) -> (f32)159; CHECK-NEXT: # %bb.0:160; CHECK-NEXT: local.get $push1=, 0161; CHECK-NEXT: f32.nearest $push0=, $pop1162; CHECK-NEXT: return $pop0163 %a = call float @llvm.rint.f32(float %x)164 ret float %a165}166 167define float @nearest32_via_roundeven(float %x) {168; CHECK-LABEL: nearest32_via_roundeven:169; CHECK: .functype nearest32_via_roundeven (f32) -> (f32)170; CHECK-NEXT: # %bb.0:171; CHECK-NEXT: local.get $push1=, 0172; CHECK-NEXT: f32.nearest $push0=, $pop1173; CHECK-NEXT: return $pop0174 %a = call float @llvm.roundeven.f32(float %x)175 ret float %a176}177 178; This is not "minimum" because a -0.0 input returns +0.0.179 180define float @fmin32(float %x) {181; CHECK-LABEL: fmin32:182; CHECK: .functype fmin32 (f32) -> (f32)183; CHECK-NEXT: # %bb.0:184; CHECK-NEXT: f32.const $push0=, 0x0p0185; CHECK-NEXT: local.get $push5=, 0186; CHECK-NEXT: local.get $push4=, 0187; CHECK-NEXT: f32.const $push3=, 0x0p0188; CHECK-NEXT: f32.ge $push1=, $pop4, $pop3189; CHECK-NEXT: f32.select $push2=, $pop0, $pop5, $pop1190; CHECK-NEXT: return $pop2191 %a = fcmp ult float %x, 0.0192 %b = select i1 %a, float %x, float 0.0193 ret float %b194}195 196; This is not "maximum" because a -0.0 input returns +0.0.197 198define float @fmax32(float %x) {199; CHECK-LABEL: fmax32:200; CHECK: .functype fmax32 (f32) -> (f32)201; CHECK-NEXT: # %bb.0:202; CHECK-NEXT: f32.const $push0=, 0x0p0203; CHECK-NEXT: local.get $push5=, 0204; CHECK-NEXT: local.get $push4=, 0205; CHECK-NEXT: f32.const $push3=, 0x0p0206; CHECK-NEXT: f32.le $push1=, $pop4, $pop3207; CHECK-NEXT: f32.select $push2=, $pop0, $pop5, $pop1208; CHECK-NEXT: return $pop2209 %a = fcmp ugt float %x, 0.0210 %b = select i1 %a, float %x, float 0.0211 ret float %b212}213 214declare float @llvm.minimum.f32(float, float)215define float @fmin32_intrinsic(float %x, float %y) {216; CHECK-LABEL: fmin32_intrinsic:217; CHECK: .functype fmin32_intrinsic (f32, f32) -> (f32)218; CHECK-NEXT: # %bb.0:219; CHECK-NEXT: local.get $push2=, 0220; CHECK-NEXT: local.get $push1=, 1221; CHECK-NEXT: f32.min $push0=, $pop2, $pop1222; CHECK-NEXT: return $pop0223 %a = call float @llvm.minimum.f32(float %x, float %y)224 ret float %a225}226 227declare float @llvm.minnum.f32(float, float)228define float @fminnum32_intrinsic(float %x, float %y) {229; CHECK-LABEL: fminnum32_intrinsic:230; CHECK: .functype fminnum32_intrinsic (f32, f32) -> (f32)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: f32.lt $push0=, $pop3, $pop2237; CHECK-NEXT: f32.select $push1=, $pop5, $pop4, $pop0238; CHECK-NEXT: return $pop1239 %a = call nnan float @llvm.minnum.f32(float %x, float %y)240 ret float %a241}242 243define float @fminnum32_non_zero_intrinsic(float %x) {244; CHECK-LABEL: fminnum32_non_zero_intrinsic:245; CHECK: .functype fminnum32_non_zero_intrinsic (f32) -> (f32)246; CHECK-NEXT: # %bb.0:247; CHECK-NEXT: local.get $push2=, 0248; CHECK-NEXT: f32.const $push0=, -0x1p0249; CHECK-NEXT: f32.min $push1=, $pop2, $pop0250; CHECK-NEXT: return $pop1251 %a = call nnan float @llvm.minnum.f32(float %x, float -1.0)252 ret float %a253}254 255define float @fminnum32_nsz_intrinsic(float %x, float %y) {256; CHECK-LABEL: fminnum32_nsz_intrinsic:257; CHECK: .functype fminnum32_nsz_intrinsic (f32, f32) -> (f32)258; CHECK-NEXT: # %bb.0:259; CHECK-NEXT: local.get $push2=, 0260; CHECK-NEXT: local.get $push1=, 1261; CHECK-NEXT: f32.min $push0=, $pop2, $pop1262; CHECK-NEXT: return $pop0263 %a = call nnan nsz float @llvm.minnum.f32(float %x, float %y)264 ret float %a265}266 267declare float @llvm.maximum.f32(float, float)268define float @fmax32_intrinsic(float %x, float %y) {269; CHECK-LABEL: fmax32_intrinsic:270; CHECK: .functype fmax32_intrinsic (f32, f32) -> (f32)271; CHECK-NEXT: # %bb.0:272; CHECK-NEXT: local.get $push2=, 0273; CHECK-NEXT: local.get $push1=, 1274; CHECK-NEXT: f32.max $push0=, $pop2, $pop1275; CHECK-NEXT: return $pop0276 %a = call float @llvm.maximum.f32(float %x, float %y)277 ret float %a278}279 280declare float @llvm.maxnum.f32(float, float)281define float @fmaxnum32_intrinsic(float %x, float %y) {282; CHECK-LABEL: fmaxnum32_intrinsic:283; CHECK: .functype fmaxnum32_intrinsic (f32, f32) -> (f32)284; CHECK-NEXT: # %bb.0:285; CHECK-NEXT: local.get $push5=, 0286; CHECK-NEXT: local.get $push4=, 1287; CHECK-NEXT: local.get $push3=, 0288; CHECK-NEXT: local.get $push2=, 1289; CHECK-NEXT: f32.gt $push0=, $pop3, $pop2290; CHECK-NEXT: f32.select $push1=, $pop5, $pop4, $pop0291; CHECK-NEXT: return $pop1292 %a = call nnan float @llvm.maxnum.f32(float %x, float %y)293 ret float %a294}295 296define float @fmaxnum32_nsz_intrinsic(float %x, float %y) {297; CHECK-LABEL: fmaxnum32_nsz_intrinsic:298; CHECK: .functype fmaxnum32_nsz_intrinsic (f32, f32) -> (f32)299; CHECK-NEXT: # %bb.0:300; CHECK-NEXT: local.get $push2=, 0301; CHECK-NEXT: local.get $push1=, 1302; CHECK-NEXT: f32.max $push0=, $pop2, $pop1303; CHECK-NEXT: return $pop0304 %a = call nnan nsz float @llvm.maxnum.f32(float %x, float %y)305 ret float %a306}307 308define float @fmaxnum32_zero_intrinsic(float %x) {309; CHECK-LABEL: fmaxnum32_zero_intrinsic:310; CHECK: .functype fmaxnum32_zero_intrinsic (f32) -> (f32)311; CHECK-NEXT: # %bb.0:312; CHECK-NEXT: local.get $push5=, 0313; CHECK-NEXT: f32.const $push0=, 0x0p0314; CHECK-NEXT: local.get $push4=, 0315; CHECK-NEXT: f32.const $push3=, 0x0p0316; CHECK-NEXT: f32.gt $push1=, $pop4, $pop3317; CHECK-NEXT: f32.select $push2=, $pop5, $pop0, $pop1318; CHECK-NEXT: return $pop2319 %a = call nnan float @llvm.maxnum.f32(float %x, float 0.0)320 ret float %a321}322 323define float @fmaxnum32_non_zero_intrinsic(float %x) {324; CHECK-LABEL: fmaxnum32_non_zero_intrinsic:325; CHECK: .functype fmaxnum32_non_zero_intrinsic (f32) -> (f32)326; CHECK-NEXT: # %bb.0:327; CHECK-NEXT: local.get $push2=, 0328; CHECK-NEXT: f32.const $push0=, 0x1p0329; CHECK-NEXT: f32.max $push1=, $pop2, $pop0330; CHECK-NEXT: return $pop1331 %a = call nnan float @llvm.maxnum.f32(float %x, float 1.0)332 ret float %a333}334 335define float @fma32(float %a, float %b, float %c) {336; CHECK-LABEL: fma32:337; CHECK: .functype fma32 (f32, f32, f32) -> (f32)338; CHECK-NEXT: # %bb.0:339; CHECK-NEXT: local.get $push3=, 0340; CHECK-NEXT: local.get $push2=, 1341; CHECK-NEXT: local.get $push1=, 2342; CHECK-NEXT: call $push0=, fmaf, $pop3, $pop2, $pop1343; CHECK-NEXT: return $pop0344 %d = call float @llvm.fma.f32(float %a, float %b, float %c)345 ret float %d346}347