472 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -verify-machineinstrs -mcpu=mvp -mattr=+simd128 | FileCheck %s3 4; Test that vector float-to-int and int-to-float instructions lower correctly5 6target triple = "wasm32-unknown-unknown"7 8define <4 x float> @convert_s_v4f32(<4 x i32> %x) {9; CHECK-LABEL: convert_s_v4f32:10; CHECK: .functype convert_s_v4f32 (v128) -> (v128)11; CHECK-NEXT: # %bb.0:12; CHECK-NEXT: local.get 013; CHECK-NEXT: f32x4.convert_i32x4_s14; CHECK-NEXT: # fallthrough-return15 %a = sitofp <4 x i32> %x to <4 x float>16 ret <4 x float> %a17}18 19define <4 x float> @convert_u_v4f32(<4 x i32> %x) {20; CHECK-LABEL: convert_u_v4f32:21; CHECK: .functype convert_u_v4f32 (v128) -> (v128)22; CHECK-NEXT: # %bb.0:23; CHECK-NEXT: local.get 024; CHECK-NEXT: f32x4.convert_i32x4_u25; CHECK-NEXT: # fallthrough-return26 %a = uitofp <4 x i32> %x to <4 x float>27 ret <4 x float> %a28}29 30define <2 x double> @convert_s_v2f64(<2 x i64> %x) {31; CHECK-LABEL: convert_s_v2f64:32; CHECK: .functype convert_s_v2f64 (v128) -> (v128)33; CHECK-NEXT: # %bb.0:34; CHECK-NEXT: local.get 035; CHECK-NEXT: i64x2.extract_lane 036; CHECK-NEXT: f64.convert_i64_s37; CHECK-NEXT: f64x2.splat38; CHECK-NEXT: local.get 039; CHECK-NEXT: i64x2.extract_lane 140; CHECK-NEXT: f64.convert_i64_s41; CHECK-NEXT: f64x2.replace_lane 142; CHECK-NEXT: # fallthrough-return43 %a = sitofp <2 x i64> %x to <2 x double>44 ret <2 x double> %a45}46 47define <2 x double> @convert_u_v2f64(<2 x i64> %x) {48; CHECK-LABEL: convert_u_v2f64:49; CHECK: .functype convert_u_v2f64 (v128) -> (v128)50; CHECK-NEXT: # %bb.0:51; CHECK-NEXT: local.get 052; CHECK-NEXT: v128.const 4294967295, 429496729553; CHECK-NEXT: v128.and54; CHECK-NEXT: v128.const 4841369599423283200, 484136959942328320055; CHECK-NEXT: v128.or56; CHECK-NEXT: local.get 057; CHECK-NEXT: i32.const 3258; CHECK-NEXT: i64x2.shr_u59; CHECK-NEXT: v128.const 4985484787499139072, 498548478749913907260; CHECK-NEXT: v128.or61; CHECK-NEXT: v128.const 0x1.00000001p84, 0x1.00000001p8462; CHECK-NEXT: f64x2.sub63; CHECK-NEXT: f64x2.add64; CHECK-NEXT: # fallthrough-return65 %a = uitofp <2 x i64> %x to <2 x double>66 ret <2 x double> %a67}68 69define <4 x i32> @trunc_sat_s_v4i32(<4 x float> %x) {70; CHECK-LABEL: trunc_sat_s_v4i32:71; CHECK: .functype trunc_sat_s_v4i32 (v128) -> (v128)72; CHECK-NEXT: # %bb.0:73; CHECK-NEXT: local.get 074; CHECK-NEXT: i32x4.trunc_sat_f32x4_s75; CHECK-NEXT: # fallthrough-return76 %a = fptosi <4 x float> %x to <4 x i32>77 ret <4 x i32> %a78}79 80define <4 x i32> @trunc_sat_u_v4i32(<4 x float> %x) {81; CHECK-LABEL: trunc_sat_u_v4i32:82; CHECK: .functype trunc_sat_u_v4i32 (v128) -> (v128)83; CHECK-NEXT: # %bb.0:84; CHECK-NEXT: local.get 085; CHECK-NEXT: i32x4.trunc_sat_f32x4_u86; CHECK-NEXT: # fallthrough-return87 %a = fptoui <4 x float> %x to <4 x i32>88 ret <4 x i32> %a89}90 91define <2 x i64> @trunc_sat_s_v2i64(<2 x double> %x) {92; CHECK-LABEL: trunc_sat_s_v2i64:93; CHECK: .functype trunc_sat_s_v2i64 (v128) -> (v128)94; CHECK-NEXT: .local f64, i64, i6495; CHECK-NEXT: # %bb.0:96; CHECK-NEXT: block97; CHECK-NEXT: block98; CHECK-NEXT: local.get 099; CHECK-NEXT: f64x2.extract_lane 1100; CHECK-NEXT: local.tee 1101; CHECK-NEXT: f64.abs102; CHECK-NEXT: f64.const 0x1p63103; CHECK-NEXT: f64.lt104; CHECK-NEXT: i32.eqz105; CHECK-NEXT: br_if 0 # 0: down to label1106; CHECK-NEXT: # %bb.1:107; CHECK-NEXT: local.get 1108; CHECK-NEXT: i64.trunc_f64_s109; CHECK-NEXT: local.set 2110; CHECK-NEXT: br 1 # 1: down to label0111; CHECK-NEXT: .LBB6_2:112; CHECK-NEXT: end_block # label1:113; CHECK-NEXT: i64.const -9223372036854775808114; CHECK-NEXT: local.set 2115; CHECK-NEXT: .LBB6_3:116; CHECK-NEXT: end_block # label0:117; CHECK-NEXT: block118; CHECK-NEXT: block119; CHECK-NEXT: local.get 0120; CHECK-NEXT: f64x2.extract_lane 0121; CHECK-NEXT: local.tee 1122; CHECK-NEXT: f64.abs123; CHECK-NEXT: f64.const 0x1p63124; CHECK-NEXT: f64.lt125; CHECK-NEXT: i32.eqz126; CHECK-NEXT: br_if 0 # 0: down to label3127; CHECK-NEXT: # %bb.4:128; CHECK-NEXT: local.get 1129; CHECK-NEXT: i64.trunc_f64_s130; CHECK-NEXT: local.set 3131; CHECK-NEXT: br 1 # 1: down to label2132; CHECK-NEXT: .LBB6_5:133; CHECK-NEXT: end_block # label3:134; CHECK-NEXT: i64.const -9223372036854775808135; CHECK-NEXT: local.set 3136; CHECK-NEXT: .LBB6_6:137; CHECK-NEXT: end_block # label2:138; CHECK-NEXT: local.get 3139; CHECK-NEXT: i64x2.splat140; CHECK-NEXT: local.get 2141; CHECK-NEXT: i64x2.replace_lane 1142; CHECK-NEXT: # fallthrough-return143 %a = fptosi <2 x double> %x to <2 x i64>144 ret <2 x i64> %a145}146 147define <2 x i64> @trunc_sat_u_v2i64(<2 x double> %x) {148; CHECK-LABEL: trunc_sat_u_v2i64:149; CHECK: .functype trunc_sat_u_v2i64 (v128) -> (v128)150; CHECK-NEXT: .local f64, i64, i64151; CHECK-NEXT: # %bb.0:152; CHECK-NEXT: block153; CHECK-NEXT: block154; CHECK-NEXT: local.get 0155; CHECK-NEXT: f64x2.extract_lane 1156; CHECK-NEXT: local.tee 1157; CHECK-NEXT: f64.const 0x1p64158; CHECK-NEXT: f64.lt159; CHECK-NEXT: local.get 1160; CHECK-NEXT: f64.const 0x0p0161; CHECK-NEXT: f64.ge162; CHECK-NEXT: i32.and163; CHECK-NEXT: i32.eqz164; CHECK-NEXT: br_if 0 # 0: down to label5165; CHECK-NEXT: # %bb.1:166; CHECK-NEXT: local.get 1167; CHECK-NEXT: i64.trunc_f64_u168; CHECK-NEXT: local.set 2169; CHECK-NEXT: br 1 # 1: down to label4170; CHECK-NEXT: .LBB7_2:171; CHECK-NEXT: end_block # label5:172; CHECK-NEXT: i64.const 0173; CHECK-NEXT: local.set 2174; CHECK-NEXT: .LBB7_3:175; CHECK-NEXT: end_block # label4:176; CHECK-NEXT: block177; CHECK-NEXT: block178; CHECK-NEXT: local.get 0179; CHECK-NEXT: f64x2.extract_lane 0180; CHECK-NEXT: local.tee 1181; CHECK-NEXT: f64.const 0x1p64182; CHECK-NEXT: f64.lt183; CHECK-NEXT: local.get 1184; CHECK-NEXT: f64.const 0x0p0185; CHECK-NEXT: f64.ge186; CHECK-NEXT: i32.and187; CHECK-NEXT: i32.eqz188; CHECK-NEXT: br_if 0 # 0: down to label7189; CHECK-NEXT: # %bb.4:190; CHECK-NEXT: local.get 1191; CHECK-NEXT: i64.trunc_f64_u192; CHECK-NEXT: local.set 3193; CHECK-NEXT: br 1 # 1: down to label6194; CHECK-NEXT: .LBB7_5:195; CHECK-NEXT: end_block # label7:196; CHECK-NEXT: i64.const 0197; CHECK-NEXT: local.set 3198; CHECK-NEXT: .LBB7_6:199; CHECK-NEXT: end_block # label6:200; CHECK-NEXT: local.get 3201; CHECK-NEXT: i64x2.splat202; CHECK-NEXT: local.get 2203; CHECK-NEXT: i64x2.replace_lane 1204; CHECK-NEXT: # fallthrough-return205 %a = fptoui <2 x double> %x to <2 x i64>206 ret <2 x i64> %a207}208 209define <4 x float> @demote_zero_v4f32(<2 x double> %x) {210; CHECK-LABEL: demote_zero_v4f32:211; CHECK: .functype demote_zero_v4f32 (v128) -> (v128)212; CHECK-NEXT: # %bb.0:213; CHECK-NEXT: local.get 0214; CHECK-NEXT: f32x4.demote_f64x2_zero215; CHECK-NEXT: # fallthrough-return216 %v = shufflevector <2 x double> %x, <2 x double> zeroinitializer,217 <4 x i32> <i32 0, i32 1, i32 2, i32 3>218 %a = fptrunc <4 x double> %v to <4 x float>219 ret <4 x float> %a220}221 222define <4 x float> @demote_zero_v4f32_2(<2 x double> %x) {223; CHECK-LABEL: demote_zero_v4f32_2:224; CHECK: .functype demote_zero_v4f32_2 (v128) -> (v128)225; CHECK-NEXT: # %bb.0:226; CHECK-NEXT: local.get 0227; CHECK-NEXT: f32x4.demote_f64x2_zero228; CHECK-NEXT: # fallthrough-return229 %v = fptrunc <2 x double> %x to <2 x float>230 %a = shufflevector <2 x float> %v, <2 x float> zeroinitializer,231 <4 x i32> <i32 0, i32 1, i32 2, i32 3>232 ret <4 x float> %a233}234 235define <2 x double> @convert_low_s_v2f64(<4 x i32> %x) {236; CHECK-LABEL: convert_low_s_v2f64:237; CHECK: .functype convert_low_s_v2f64 (v128) -> (v128)238; CHECK-NEXT: # %bb.0:239; CHECK-NEXT: local.get 0240; CHECK-NEXT: f64x2.convert_low_i32x4_s241; CHECK-NEXT: # fallthrough-return242 %v = shufflevector <4 x i32> %x, <4 x i32> undef, <2 x i32> <i32 0, i32 1>243 %a = sitofp <2 x i32> %v to <2 x double>244 ret <2 x double> %a245}246 247define <2 x double> @convert_low_u_v2f64(<4 x i32> %x) {248; CHECK-LABEL: convert_low_u_v2f64:249; CHECK: .functype convert_low_u_v2f64 (v128) -> (v128)250; CHECK-NEXT: # %bb.0:251; CHECK-NEXT: local.get 0252; CHECK-NEXT: f64x2.convert_low_i32x4_u253; CHECK-NEXT: # fallthrough-return254 %v = shufflevector <4 x i32> %x, <4 x i32> undef, <2 x i32> <i32 0, i32 1>255 %a = uitofp <2 x i32> %v to <2 x double>256 ret <2 x double> %a257}258 259 260define <2 x double> @convert_low_s_v2f64_2(<4 x i32> %x) {261; CHECK-LABEL: convert_low_s_v2f64_2:262; CHECK: .functype convert_low_s_v2f64_2 (v128) -> (v128)263; CHECK-NEXT: # %bb.0:264; CHECK-NEXT: local.get 0265; CHECK-NEXT: f64x2.convert_low_i32x4_s266; CHECK-NEXT: # fallthrough-return267 %v = sitofp <4 x i32> %x to <4 x double>268 %a = shufflevector <4 x double> %v, <4 x double> undef, <2 x i32> <i32 0, i32 1>269 ret <2 x double> %a270}271 272define <2 x double> @convert_low_u_v2f64_2(<4 x i32> %x) {273; CHECK-LABEL: convert_low_u_v2f64_2:274; CHECK: .functype convert_low_u_v2f64_2 (v128) -> (v128)275; CHECK-NEXT: # %bb.0:276; CHECK-NEXT: local.get 0277; CHECK-NEXT: f64x2.convert_low_i32x4_u278; CHECK-NEXT: # fallthrough-return279 %v = uitofp <4 x i32> %x to <4 x double>280 %a = shufflevector <4 x double> %v, <4 x double> undef, <2 x i32> <i32 0, i32 1>281 ret <2 x double> %a282}283 284define <2 x double> @promote_low_v2f64(<4 x float> %x) {285; CHECK-LABEL: promote_low_v2f64:286; CHECK: .functype promote_low_v2f64 (v128) -> (v128)287; CHECK-NEXT: # %bb.0:288; CHECK-NEXT: local.get 0289; CHECK-NEXT: f64x2.promote_low_f32x4290; CHECK-NEXT: # fallthrough-return291 %v = shufflevector <4 x float> %x, <4 x float> undef, <2 x i32> <i32 0, i32 1>292 %a = fpext <2 x float> %v to <2 x double>293 ret <2 x double> %a294}295 296define <2 x double> @promote_low_v2f64_2(<4 x float> %x) {297; CHECK-LABEL: promote_low_v2f64_2:298; CHECK: .functype promote_low_v2f64_2 (v128) -> (v128)299; CHECK-NEXT: # %bb.0:300; CHECK-NEXT: local.get 0301; CHECK-NEXT: f64x2.promote_low_f32x4302; CHECK-NEXT: # fallthrough-return303 %v = fpext <4 x float> %x to <4 x double>304 %a = shufflevector <4 x double> %v, <4 x double> undef, <2 x i32> <i32 0, i32 1>305 ret <2 x double> %a306}307 308;; Also check with illegally wide vectors309 310define <4 x double> @convert_low_s_v4f64(<8 x i32> %x) {311; CHECK-LABEL: convert_low_s_v4f64:312; CHECK: .functype convert_low_s_v4f64 (i32, v128, v128) -> ()313; CHECK-NEXT: # %bb.0:314; CHECK-NEXT: local.get 0315; CHECK-NEXT: local.get 1316; CHECK-NEXT: local.get 1317; CHECK-NEXT: i8x16.shuffle 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3318; CHECK-NEXT: f64x2.convert_low_i32x4_s319; CHECK-NEXT: v128.store 16320; CHECK-NEXT: local.get 0321; CHECK-NEXT: local.get 1322; CHECK-NEXT: f64x2.convert_low_i32x4_s323; CHECK-NEXT: v128.store 0324; CHECK-NEXT: # fallthrough-return325 %v = shufflevector <8 x i32> %x, <8 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>326 %a = sitofp <4 x i32> %v to <4 x double>327 ret <4 x double> %a328}329 330define <4 x double> @convert_low_u_v4f64(<8 x i32> %x) {331; CHECK-LABEL: convert_low_u_v4f64:332; CHECK: .functype convert_low_u_v4f64 (i32, v128, v128) -> ()333; CHECK-NEXT: # %bb.0:334; CHECK-NEXT: local.get 0335; CHECK-NEXT: local.get 1336; CHECK-NEXT: local.get 1337; CHECK-NEXT: i8x16.shuffle 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3338; CHECK-NEXT: f64x2.convert_low_i32x4_u339; CHECK-NEXT: v128.store 16340; CHECK-NEXT: local.get 0341; CHECK-NEXT: local.get 1342; CHECK-NEXT: f64x2.convert_low_i32x4_u343; CHECK-NEXT: v128.store 0344; CHECK-NEXT: # fallthrough-return345 %v = shufflevector <8 x i32> %x, <8 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>346 %a = uitofp <4 x i32> %v to <4 x double>347 ret <4 x double> %a348}349 350 351define <4 x double> @convert_low_s_v4f64_2(<8 x i32> %x) {352; CHECK-LABEL: convert_low_s_v4f64_2:353; CHECK: .functype convert_low_s_v4f64_2 (i32, v128, v128) -> ()354; CHECK-NEXT: # %bb.0:355; CHECK-NEXT: local.get 0356; CHECK-NEXT: local.get 1357; CHECK-NEXT: local.get 1358; CHECK-NEXT: i8x16.shuffle 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3359; CHECK-NEXT: f64x2.convert_low_i32x4_s360; CHECK-NEXT: v128.store 16361; CHECK-NEXT: local.get 0362; CHECK-NEXT: local.get 1363; CHECK-NEXT: f64x2.convert_low_i32x4_s364; CHECK-NEXT: v128.store 0365; CHECK-NEXT: # fallthrough-return366 %v = sitofp <8 x i32> %x to <8 x double>367 %a = shufflevector <8 x double> %v, <8 x double> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>368 ret <4 x double> %a369}370 371define <4 x double> @convert_low_u_v4f64_2(<8 x i32> %x) {372; CHECK-LABEL: convert_low_u_v4f64_2:373; CHECK: .functype convert_low_u_v4f64_2 (i32, v128, v128) -> ()374; CHECK-NEXT: # %bb.0:375; CHECK-NEXT: local.get 0376; CHECK-NEXT: local.get 1377; CHECK-NEXT: local.get 1378; CHECK-NEXT: i8x16.shuffle 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3379; CHECK-NEXT: f64x2.convert_low_i32x4_u380; CHECK-NEXT: v128.store 16381; CHECK-NEXT: local.get 0382; CHECK-NEXT: local.get 1383; CHECK-NEXT: f64x2.convert_low_i32x4_u384; CHECK-NEXT: v128.store 0385; CHECK-NEXT: # fallthrough-return386 %v = uitofp <8 x i32> %x to <8 x double>387 %a = shufflevector <8 x double> %v, <8 x double> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>388 ret <4 x double> %a389}390 391define <4 x double> @promote_low_v4f64(<8 x float> %x) {392; CHECK-LABEL: promote_low_v4f64:393; CHECK: .functype promote_low_v4f64 (i32, v128, v128) -> ()394; CHECK-NEXT: # %bb.0:395; CHECK-NEXT: local.get 0396; CHECK-NEXT: local.get 1397; CHECK-NEXT: local.get 1398; CHECK-NEXT: i8x16.shuffle 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3399; CHECK-NEXT: f64x2.promote_low_f32x4400; CHECK-NEXT: v128.store 16401; CHECK-NEXT: local.get 0402; CHECK-NEXT: local.get 1403; CHECK-NEXT: f64x2.promote_low_f32x4404; CHECK-NEXT: v128.store 0405; CHECK-NEXT: # fallthrough-return406 %v = shufflevector <8 x float> %x, <8 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>407 %a = fpext <4 x float> %v to <4 x double>408 ret <4 x double> %a409}410 411define <4 x double> @promote_low_v4f64_2(<8 x float> %x) {412; CHECK-LABEL: promote_low_v4f64_2:413; CHECK: .functype promote_low_v4f64_2 (i32, v128, v128) -> ()414; CHECK-NEXT: # %bb.0:415; CHECK-NEXT: local.get 0416; CHECK-NEXT: local.get 1417; CHECK-NEXT: local.get 1418; CHECK-NEXT: i8x16.shuffle 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3419; CHECK-NEXT: f64x2.promote_low_f32x4420; CHECK-NEXT: v128.store 16421; CHECK-NEXT: local.get 0422; CHECK-NEXT: local.get 1423; CHECK-NEXT: f64x2.promote_low_f32x4424; CHECK-NEXT: v128.store 0425; CHECK-NEXT: # fallthrough-return426 %v = fpext <8 x float> %x to <8 x double>427 %a = shufflevector <8 x double> %v, <8 x double> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>428 ret <4 x double> %a429}430 431define <2 x double> @promote_mixed_v2f64(<4 x float> %x, <4 x float> %y) {432; CHECK-LABEL: promote_mixed_v2f64:433; CHECK: .functype promote_mixed_v2f64 (v128, v128) -> (v128)434; CHECK-NEXT: # %bb.0:435; CHECK-NEXT: local.get 0436; CHECK-NEXT: local.get 1437; CHECK-NEXT: i8x16.shuffle 8, 9, 10, 11, 28, 29, 30, 31, 0, 1, 2, 3, 0, 1, 2, 3438; CHECK-NEXT: f64x2.promote_low_f32x4439; CHECK-NEXT: # fallthrough-return440 %v = shufflevector <4 x float> %x, <4 x float> %y, <2 x i32> <i32 2, i32 7>441 %a = fpext <2 x float> %v to <2 x double>442 ret <2 x double> %a443}444 445define <4 x float> @convert_u_v4f32_maybeneg(<4 x i32> %x) {446; CHECK-LABEL: convert_u_v4f32_maybeneg:447; CHECK: .functype convert_u_v4f32_maybeneg (v128) -> (v128)448; CHECK-NEXT: # %bb.0:449; CHECK-NEXT: local.get 0450; CHECK-NEXT: i32.const 1451; CHECK-NEXT: i32x4.shr_s452; CHECK-NEXT: f32x4.convert_i32x4_u453; CHECK-NEXT: # fallthrough-return454 %a = ashr <4 x i32> %x, <i32 1, i32 1, i32 1, i32 1>455 %b = uitofp <4 x i32> %a to <4 x float>456 ret <4 x float> %b457}458 459define <4 x float> @convert_u_v4f32_nonneg(<4 x i32> %x) {460; CHECK-LABEL: convert_u_v4f32_nonneg:461; CHECK: .functype convert_u_v4f32_nonneg (v128) -> (v128)462; CHECK-NEXT: # %bb.0:463; CHECK-NEXT: local.get 0464; CHECK-NEXT: i32.const 1465; CHECK-NEXT: i32x4.shr_u466; CHECK-NEXT: f32x4.convert_i32x4_s467; CHECK-NEXT: # fallthrough-return468 %a = lshr <4 x i32> %x, <i32 1, i32 1, i32 1, i32 1>469 %b = uitofp <4 x i32> %a to <4 x float>470 ret <4 x float> %b471}472