1799 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -aarch64-sve-vector-bits-min=256 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_2563; RUN: llc -aarch64-sve-vector-bits-min=512 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_5124; RUN: llc -aarch64-sve-vector-bits-min=2048 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_5125 6target triple = "aarch64-unknown-linux-gnu"7 8;9; FCVTZU H -> H10;11 12; Don't use SVE for 64-bit vectors.13define <4 x i16> @fcvtzu_v4f16_v4i16(<4 x half> %op1) vscale_range(2,0) #0 {14; CHECK-LABEL: fcvtzu_v4f16_v4i16:15; CHECK: // %bb.0:16; CHECK-NEXT: fcvtzu v0.4h, v0.4h17; CHECK-NEXT: ret18 %res = fptoui <4 x half> %op1 to <4 x i16>19 ret <4 x i16> %res20}21 22; Don't use SVE for 128-bit vectors.23define void @fcvtzu_v8f16_v8i16(ptr %a, ptr %b) vscale_range(2,0) #0 {24; CHECK-LABEL: fcvtzu_v8f16_v8i16:25; CHECK: // %bb.0:26; CHECK-NEXT: ldr q0, [x0]27; CHECK-NEXT: fcvtzu v0.8h, v0.8h28; CHECK-NEXT: str q0, [x1]29; CHECK-NEXT: ret30 %op1 = load <8 x half>, ptr %a31 %res = fptoui <8 x half> %op1 to <8 x i16>32 store <8 x i16> %res, ptr %b33 ret void34}35 36define void @fcvtzu_v16f16_v16i16(ptr %a, ptr %b) vscale_range(2,0) #0 {37; CHECK-LABEL: fcvtzu_v16f16_v16i16:38; CHECK: // %bb.0:39; CHECK-NEXT: ptrue p0.h, vl1640; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0]41; CHECK-NEXT: fcvtzu z0.h, p0/m, z0.h42; CHECK-NEXT: st1h { z0.h }, p0, [x1]43; CHECK-NEXT: ret44 %op1 = load <16 x half>, ptr %a45 %res = fptoui <16 x half> %op1 to <16 x i16>46 store <16 x i16> %res, ptr %b47 ret void48}49 50define void @fcvtzu_v32f16_v32i16(ptr %a, ptr %b) #0 {51; VBITS_GE_256-LABEL: fcvtzu_v32f16_v32i16:52; VBITS_GE_256: // %bb.0:53; VBITS_GE_256-NEXT: ptrue p0.h, vl1654; VBITS_GE_256-NEXT: mov x8, #16 // =0x1055; VBITS_GE_256-NEXT: ld1h { z0.h }, p0/z, [x0, x8, lsl #1]56; VBITS_GE_256-NEXT: ld1h { z1.h }, p0/z, [x0]57; VBITS_GE_256-NEXT: fcvtzu z0.h, p0/m, z0.h58; VBITS_GE_256-NEXT: fcvtzu z1.h, p0/m, z1.h59; VBITS_GE_256-NEXT: st1h { z0.h }, p0, [x1, x8, lsl #1]60; VBITS_GE_256-NEXT: st1h { z1.h }, p0, [x1]61; VBITS_GE_256-NEXT: ret62;63; VBITS_GE_512-LABEL: fcvtzu_v32f16_v32i16:64; VBITS_GE_512: // %bb.0:65; VBITS_GE_512-NEXT: ptrue p0.h, vl3266; VBITS_GE_512-NEXT: ld1h { z0.h }, p0/z, [x0]67; VBITS_GE_512-NEXT: fcvtzu z0.h, p0/m, z0.h68; VBITS_GE_512-NEXT: st1h { z0.h }, p0, [x1]69; VBITS_GE_512-NEXT: ret70 %op1 = load <32 x half>, ptr %a71 %res = fptoui <32 x half> %op1 to <32 x i16>72 store <32 x i16> %res, ptr %b73 ret void74}75 76define void @fcvtzu_v64f16_v64i16(ptr %a, ptr %b) vscale_range(8,0) #0 {77; CHECK-LABEL: fcvtzu_v64f16_v64i16:78; CHECK: // %bb.0:79; CHECK-NEXT: ptrue p0.h, vl6480; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0]81; CHECK-NEXT: fcvtzu z0.h, p0/m, z0.h82; CHECK-NEXT: st1h { z0.h }, p0, [x1]83; CHECK-NEXT: ret84 %op1 = load <64 x half>, ptr %a85 %res = fptoui <64 x half> %op1 to <64 x i16>86 store <64 x i16> %res, ptr %b87 ret void88}89 90define void @fcvtzu_v128f16_v128i16(ptr %a, ptr %b) vscale_range(16,0) #0 {91; CHECK-LABEL: fcvtzu_v128f16_v128i16:92; CHECK: // %bb.0:93; CHECK-NEXT: ptrue p0.h, vl12894; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0]95; CHECK-NEXT: fcvtzu z0.h, p0/m, z0.h96; CHECK-NEXT: st1h { z0.h }, p0, [x1]97; CHECK-NEXT: ret98 %op1 = load <128 x half>, ptr %a99 %res = fptoui <128 x half> %op1 to <128 x i16>100 store <128 x i16> %res, ptr %b101 ret void102}103 104;105; FCVTZU H -> S106;107 108; Don't use SVE for 64-bit vectors.109define <2 x i32> @fcvtzu_v2f16_v2i32(<2 x half> %op1) vscale_range(2,0) #0 {110; CHECK-LABEL: fcvtzu_v2f16_v2i32:111; CHECK: // %bb.0:112; CHECK-NEXT: fcvtl v0.4s, v0.4h113; CHECK-NEXT: fcvtzu v0.4s, v0.4s114; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0115; CHECK-NEXT: ret116 %res = fptoui <2 x half> %op1 to <2 x i32>117 ret <2 x i32> %res118}119 120; Don't use SVE for 128-bit vectors.121define <4 x i32> @fcvtzu_v4f16_v4i32(<4 x half> %op1) vscale_range(2,0) #0 {122; CHECK-LABEL: fcvtzu_v4f16_v4i32:123; CHECK: // %bb.0:124; CHECK-NEXT: fcvtl v0.4s, v0.4h125; CHECK-NEXT: fcvtzu v0.4s, v0.4s126; CHECK-NEXT: ret127 %res = fptoui <4 x half> %op1 to <4 x i32>128 ret <4 x i32> %res129}130 131define void @fcvtzu_v8f16_v8i32(ptr %a, ptr %b) vscale_range(2,0) #0 {132; CHECK-LABEL: fcvtzu_v8f16_v8i32:133; CHECK: // %bb.0:134; CHECK-NEXT: ldr q0, [x0]135; CHECK-NEXT: ptrue p0.s, vl8136; CHECK-NEXT: uunpklo z0.s, z0.h137; CHECK-NEXT: fcvtzu z0.s, p0/m, z0.h138; CHECK-NEXT: st1w { z0.s }, p0, [x1]139; CHECK-NEXT: ret140 %op1 = load <8 x half>, ptr %a141 %res = fptoui <8 x half> %op1 to <8 x i32>142 store <8 x i32> %res, ptr %b143 ret void144}145 146define void @fcvtzu_v16f16_v16i32(ptr %a, ptr %b) #0 {147; VBITS_GE_256-LABEL: fcvtzu_v16f16_v16i32:148; VBITS_GE_256: // %bb.0:149; VBITS_GE_256-NEXT: ptrue p0.h, vl16150; VBITS_GE_256-NEXT: mov x8, #8 // =0x8151; VBITS_GE_256-NEXT: ld1h { z0.h }, p0/z, [x0]152; VBITS_GE_256-NEXT: ptrue p0.s, vl8153; VBITS_GE_256-NEXT: movprfx z1, z0154; VBITS_GE_256-NEXT: ext z1.b, z1.b, z0.b, #16155; VBITS_GE_256-NEXT: uunpklo z0.s, z0.h156; VBITS_GE_256-NEXT: uunpklo z1.s, z1.h157; VBITS_GE_256-NEXT: fcvtzu z0.s, p0/m, z0.h158; VBITS_GE_256-NEXT: fcvtzu z1.s, p0/m, z1.h159; VBITS_GE_256-NEXT: st1w { z0.s }, p0, [x1]160; VBITS_GE_256-NEXT: st1w { z1.s }, p0, [x1, x8, lsl #2]161; VBITS_GE_256-NEXT: ret162;163; VBITS_GE_512-LABEL: fcvtzu_v16f16_v16i32:164; VBITS_GE_512: // %bb.0:165; VBITS_GE_512-NEXT: ptrue p0.s, vl16166; VBITS_GE_512-NEXT: ld1h { z0.s }, p0/z, [x0]167; VBITS_GE_512-NEXT: fcvtzu z0.s, p0/m, z0.h168; VBITS_GE_512-NEXT: st1w { z0.s }, p0, [x1]169; VBITS_GE_512-NEXT: ret170 %op1 = load <16 x half>, ptr %a171 %res = fptoui <16 x half> %op1 to <16 x i32>172 store <16 x i32> %res, ptr %b173 ret void174}175 176define void @fcvtzu_v32f16_v32i32(ptr %a, ptr %b) vscale_range(8,0) #0 {177; CHECK-LABEL: fcvtzu_v32f16_v32i32:178; CHECK: // %bb.0:179; CHECK-NEXT: ptrue p0.s, vl32180; CHECK-NEXT: ld1h { z0.s }, p0/z, [x0]181; CHECK-NEXT: fcvtzu z0.s, p0/m, z0.h182; CHECK-NEXT: st1w { z0.s }, p0, [x1]183; CHECK-NEXT: ret184 %op1 = load <32 x half>, ptr %a185 %res = fptoui <32 x half> %op1 to <32 x i32>186 store <32 x i32> %res, ptr %b187 ret void188}189 190define void @fcvtzu_v64f16_v64i32(ptr %a, ptr %b) vscale_range(16,0) #0 {191; CHECK-LABEL: fcvtzu_v64f16_v64i32:192; CHECK: // %bb.0:193; CHECK-NEXT: ptrue p0.s, vl64194; CHECK-NEXT: ld1h { z0.s }, p0/z, [x0]195; CHECK-NEXT: fcvtzu z0.s, p0/m, z0.h196; CHECK-NEXT: st1w { z0.s }, p0, [x1]197; CHECK-NEXT: ret198 %op1 = load <64 x half>, ptr %a199 %res = fptoui <64 x half> %op1 to <64 x i32>200 store <64 x i32> %res, ptr %b201 ret void202}203 204;205; FCVTZU H -> D206;207 208; Don't use SVE for 64-bit vectors.209define <1 x i64> @fcvtzu_v1f16_v1i64(<1 x half> %op1) vscale_range(2,0) #0 {210; CHECK-LABEL: fcvtzu_v1f16_v1i64:211; CHECK: // %bb.0:212; CHECK-NEXT: fcvtzu x8, h0213; CHECK-NEXT: fmov d0, x8214; CHECK-NEXT: ret215 %res = fptoui <1 x half> %op1 to <1 x i64>216 ret <1 x i64> %res217}218 219; v2f16 is not legal for NEON, so use SVE220define <2 x i64> @fcvtzu_v2f16_v2i64(<2 x half> %op1) vscale_range(2,0) #0 {221; CHECK-LABEL: fcvtzu_v2f16_v2i64:222; CHECK: // %bb.0:223; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0224; CHECK-NEXT: ptrue p0.d, vl4225; CHECK-NEXT: uunpklo z0.s, z0.h226; CHECK-NEXT: uunpklo z0.d, z0.s227; CHECK-NEXT: fcvtzu z0.d, p0/m, z0.h228; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0229; CHECK-NEXT: ret230 %res = fptoui <2 x half> %op1 to <2 x i64>231 ret <2 x i64> %res232}233 234define void @fcvtzu_v4f16_v4i64(ptr %a, ptr %b) vscale_range(2,0) #0 {235; CHECK-LABEL: fcvtzu_v4f16_v4i64:236; CHECK: // %bb.0:237; CHECK-NEXT: ldr d0, [x0]238; CHECK-NEXT: ptrue p0.d, vl4239; CHECK-NEXT: uunpklo z0.s, z0.h240; CHECK-NEXT: uunpklo z0.d, z0.s241; CHECK-NEXT: fcvtzu z0.d, p0/m, z0.h242; CHECK-NEXT: st1d { z0.d }, p0, [x1]243; CHECK-NEXT: ret244 %op1 = load <4 x half>, ptr %a245 %res = fptoui <4 x half> %op1 to <4 x i64>246 store <4 x i64> %res, ptr %b247 ret void248}249 250define void @fcvtzu_v8f16_v8i64(ptr %a, ptr %b) #0 {251; VBITS_GE_256-LABEL: fcvtzu_v8f16_v8i64:252; VBITS_GE_256: // %bb.0:253; VBITS_GE_256-NEXT: ldr q0, [x0]254; VBITS_GE_256-NEXT: ptrue p0.d, vl4255; VBITS_GE_256-NEXT: mov x8, #4 // =0x4256; VBITS_GE_256-NEXT: ext v1.16b, v0.16b, v0.16b, #8257; VBITS_GE_256-NEXT: uunpklo z0.s, z0.h258; VBITS_GE_256-NEXT: uunpklo z1.s, z1.h259; VBITS_GE_256-NEXT: uunpklo z0.d, z0.s260; VBITS_GE_256-NEXT: uunpklo z1.d, z1.s261; VBITS_GE_256-NEXT: fcvtzu z0.d, p0/m, z0.h262; VBITS_GE_256-NEXT: fcvtzu z1.d, p0/m, z1.h263; VBITS_GE_256-NEXT: st1d { z0.d }, p0, [x1]264; VBITS_GE_256-NEXT: st1d { z1.d }, p0, [x1, x8, lsl #3]265; VBITS_GE_256-NEXT: ret266;267; VBITS_GE_512-LABEL: fcvtzu_v8f16_v8i64:268; VBITS_GE_512: // %bb.0:269; VBITS_GE_512-NEXT: ldr q0, [x0]270; VBITS_GE_512-NEXT: ptrue p0.d, vl8271; VBITS_GE_512-NEXT: uunpklo z0.s, z0.h272; VBITS_GE_512-NEXT: uunpklo z0.d, z0.s273; VBITS_GE_512-NEXT: fcvtzu z0.d, p0/m, z0.h274; VBITS_GE_512-NEXT: st1d { z0.d }, p0, [x1]275; VBITS_GE_512-NEXT: ret276 %op1 = load <8 x half>, ptr %a277 %res = fptoui <8 x half> %op1 to <8 x i64>278 store <8 x i64> %res, ptr %b279 ret void280}281 282define void @fcvtzu_v16f16_v16i64(ptr %a, ptr %b) vscale_range(8,0) #0 {283; CHECK-LABEL: fcvtzu_v16f16_v16i64:284; CHECK: // %bb.0:285; CHECK-NEXT: ptrue p0.d, vl16286; CHECK-NEXT: ld1h { z0.d }, p0/z, [x0]287; CHECK-NEXT: fcvtzu z0.d, p0/m, z0.h288; CHECK-NEXT: st1d { z0.d }, p0, [x1]289; CHECK-NEXT: ret290 %op1 = load <16 x half>, ptr %a291 %res = fptoui <16 x half> %op1 to <16 x i64>292 store <16 x i64> %res, ptr %b293 ret void294}295 296define void @fcvtzu_v32f16_v32i64(ptr %a, ptr %b) vscale_range(16,0) #0 {297; CHECK-LABEL: fcvtzu_v32f16_v32i64:298; CHECK: // %bb.0:299; CHECK-NEXT: ptrue p0.d, vl32300; CHECK-NEXT: ld1h { z0.d }, p0/z, [x0]301; CHECK-NEXT: fcvtzu z0.d, p0/m, z0.h302; CHECK-NEXT: st1d { z0.d }, p0, [x1]303; CHECK-NEXT: ret304 %op1 = load <32 x half>, ptr %a305 %res = fptoui <32 x half> %op1 to <32 x i64>306 store <32 x i64> %res, ptr %b307 ret void308}309 310;311; FCVTZU S -> H312;313 314; Don't use SVE for 64-bit vectors.315define <2 x i16> @fcvtzu_v2f32_v2i16(<2 x float> %op1) vscale_range(2,0) #0 {316; CHECK-LABEL: fcvtzu_v2f32_v2i16:317; CHECK: // %bb.0:318; CHECK-NEXT: fcvtzs v0.2s, v0.2s319; CHECK-NEXT: ret320 %res = fptoui <2 x float> %op1 to <2 x i16>321 ret <2 x i16> %res322}323 324; Don't use SVE for 128-bit vectors.325define <4 x i16> @fcvtzu_v4f32_v4i16(<4 x float> %op1) vscale_range(2,0) #0 {326; CHECK-LABEL: fcvtzu_v4f32_v4i16:327; CHECK: // %bb.0:328; CHECK-NEXT: fcvtzu v1.4s, v0.4s329; CHECK-NEXT: mov w8, v1.s[1]330; CHECK-NEXT: mov v0.16b, v1.16b331; CHECK-NEXT: mov w9, v1.s[2]332; CHECK-NEXT: mov v0.h[1], w8333; CHECK-NEXT: mov w8, v1.s[3]334; CHECK-NEXT: mov v0.h[2], w9335; CHECK-NEXT: mov v0.h[3], w8336; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0337; CHECK-NEXT: ret338 %res = fptoui <4 x float> %op1 to <4 x i16>339 ret <4 x i16> %res340}341 342define <8 x i16> @fcvtzu_v8f32_v8i16(ptr %a) vscale_range(2,0) #0 {343; CHECK-LABEL: fcvtzu_v8f32_v8i16:344; CHECK: // %bb.0:345; CHECK-NEXT: ptrue p0.s, vl8346; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]347; CHECK-NEXT: fcvtzu z0.s, p0/m, z0.s348; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h349; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0350; CHECK-NEXT: ret351 %op1 = load <8 x float>, ptr %a352 %res = fptoui <8 x float> %op1 to <8 x i16>353 ret <8 x i16> %res354}355 356define void @fcvtzu_v16f32_v16i16(ptr %a, ptr %b) #0 {357; VBITS_GE_256-LABEL: fcvtzu_v16f32_v16i16:358; VBITS_GE_256: // %bb.0:359; VBITS_GE_256-NEXT: ptrue p0.s, vl8360; VBITS_GE_256-NEXT: mov x8, #8 // =0x8361; VBITS_GE_256-NEXT: ld1w { z0.s }, p0/z, [x0, x8, lsl #2]362; VBITS_GE_256-NEXT: ld1w { z1.s }, p0/z, [x0]363; VBITS_GE_256-NEXT: fcvtzu z0.s, p0/m, z0.s364; VBITS_GE_256-NEXT: fcvtzu z1.s, p0/m, z1.s365; VBITS_GE_256-NEXT: ptrue p0.h, vl8366; VBITS_GE_256-NEXT: uzp1 z0.h, z0.h, z0.h367; VBITS_GE_256-NEXT: uzp1 z1.h, z1.h, z1.h368; VBITS_GE_256-NEXT: splice z1.h, p0, z1.h, z0.h369; VBITS_GE_256-NEXT: ptrue p0.h, vl16370; VBITS_GE_256-NEXT: st1h { z1.h }, p0, [x1]371; VBITS_GE_256-NEXT: ret372;373; VBITS_GE_512-LABEL: fcvtzu_v16f32_v16i16:374; VBITS_GE_512: // %bb.0:375; VBITS_GE_512-NEXT: ptrue p0.s, vl16376; VBITS_GE_512-NEXT: ld1w { z0.s }, p0/z, [x0]377; VBITS_GE_512-NEXT: fcvtzu z0.s, p0/m, z0.s378; VBITS_GE_512-NEXT: st1h { z0.s }, p0, [x1]379; VBITS_GE_512-NEXT: ret380 %op1 = load <16 x float>, ptr %a381 %res = fptoui <16 x float> %op1 to <16 x i16>382 store <16 x i16> %res, ptr %b383 ret void384}385 386define void @fcvtzu_v32f32_v32i16(ptr %a, ptr %b) vscale_range(8,0) #0 {387; CHECK-LABEL: fcvtzu_v32f32_v32i16:388; CHECK: // %bb.0:389; CHECK-NEXT: ptrue p0.s, vl32390; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]391; CHECK-NEXT: fcvtzu z0.s, p0/m, z0.s392; CHECK-NEXT: st1h { z0.s }, p0, [x1]393; CHECK-NEXT: ret394 %op1 = load <32 x float>, ptr %a395 %res = fptoui <32 x float> %op1 to <32 x i16>396 store <32 x i16> %res, ptr %b397 ret void398}399 400define void @fcvtzu_v64f32_v64i16(ptr %a, ptr %b) vscale_range(16,0) #0 {401; CHECK-LABEL: fcvtzu_v64f32_v64i16:402; CHECK: // %bb.0:403; CHECK-NEXT: ptrue p0.s, vl64404; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]405; CHECK-NEXT: fcvtzu z0.s, p0/m, z0.s406; CHECK-NEXT: st1h { z0.s }, p0, [x1]407; CHECK-NEXT: ret408 %op1 = load <64 x float>, ptr %a409 %res = fptoui <64 x float> %op1 to <64 x i16>410 store <64 x i16> %res, ptr %b411 ret void412}413 414;415; FCVTZU S -> S416;417 418; Don't use SVE for 64-bit vectors.419define <2 x i32> @fcvtzu_v2f32_v2i32(<2 x float> %op1) vscale_range(2,0) #0 {420; CHECK-LABEL: fcvtzu_v2f32_v2i32:421; CHECK: // %bb.0:422; CHECK-NEXT: fcvtzu v0.2s, v0.2s423; CHECK-NEXT: ret424 %res = fptoui <2 x float> %op1 to <2 x i32>425 ret <2 x i32> %res426}427 428; Don't use SVE for 128-bit vectors.429define <4 x i32> @fcvtzu_v4f32_v4i32(<4 x float> %op1) vscale_range(2,0) #0 {430; CHECK-LABEL: fcvtzu_v4f32_v4i32:431; CHECK: // %bb.0:432; CHECK-NEXT: fcvtzu v0.4s, v0.4s433; CHECK-NEXT: ret434 %res = fptoui <4 x float> %op1 to <4 x i32>435 ret <4 x i32> %res436}437 438define void @fcvtzu_v8f32_v8i32(ptr %a, ptr %b) vscale_range(2,0) #0 {439; CHECK-LABEL: fcvtzu_v8f32_v8i32:440; CHECK: // %bb.0:441; CHECK-NEXT: ptrue p0.s, vl8442; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]443; CHECK-NEXT: fcvtzu z0.s, p0/m, z0.s444; CHECK-NEXT: st1w { z0.s }, p0, [x1]445; CHECK-NEXT: ret446 %op1 = load <8 x float>, ptr %a447 %res = fptoui <8 x float> %op1 to <8 x i32>448 store <8 x i32> %res, ptr %b449 ret void450}451 452define void @fcvtzu_v16f32_v16i32(ptr %a, ptr %b) #0 {453; VBITS_GE_256-LABEL: fcvtzu_v16f32_v16i32:454; VBITS_GE_256: // %bb.0:455; VBITS_GE_256-NEXT: ptrue p0.s, vl8456; VBITS_GE_256-NEXT: mov x8, #8 // =0x8457; VBITS_GE_256-NEXT: ld1w { z0.s }, p0/z, [x0, x8, lsl #2]458; VBITS_GE_256-NEXT: ld1w { z1.s }, p0/z, [x0]459; VBITS_GE_256-NEXT: fcvtzu z0.s, p0/m, z0.s460; VBITS_GE_256-NEXT: fcvtzu z1.s, p0/m, z1.s461; VBITS_GE_256-NEXT: st1w { z0.s }, p0, [x1, x8, lsl #2]462; VBITS_GE_256-NEXT: st1w { z1.s }, p0, [x1]463; VBITS_GE_256-NEXT: ret464;465; VBITS_GE_512-LABEL: fcvtzu_v16f32_v16i32:466; VBITS_GE_512: // %bb.0:467; VBITS_GE_512-NEXT: ptrue p0.s, vl16468; VBITS_GE_512-NEXT: ld1w { z0.s }, p0/z, [x0]469; VBITS_GE_512-NEXT: fcvtzu z0.s, p0/m, z0.s470; VBITS_GE_512-NEXT: st1w { z0.s }, p0, [x1]471; VBITS_GE_512-NEXT: ret472 %op1 = load <16 x float>, ptr %a473 %res = fptoui <16 x float> %op1 to <16 x i32>474 store <16 x i32> %res, ptr %b475 ret void476}477 478define void @fcvtzu_v32f32_v32i32(ptr %a, ptr %b) vscale_range(8,0) #0 {479; CHECK-LABEL: fcvtzu_v32f32_v32i32:480; CHECK: // %bb.0:481; CHECK-NEXT: ptrue p0.s, vl32482; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]483; CHECK-NEXT: fcvtzu z0.s, p0/m, z0.s484; CHECK-NEXT: st1w { z0.s }, p0, [x1]485; CHECK-NEXT: ret486 %op1 = load <32 x float>, ptr %a487 %res = fptoui <32 x float> %op1 to <32 x i32>488 store <32 x i32> %res, ptr %b489 ret void490}491 492define void @fcvtzu_v64f32_v64i32(ptr %a, ptr %b) vscale_range(16,0) #0 {493; CHECK-LABEL: fcvtzu_v64f32_v64i32:494; CHECK: // %bb.0:495; CHECK-NEXT: ptrue p0.s, vl64496; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]497; CHECK-NEXT: fcvtzu z0.s, p0/m, z0.s498; CHECK-NEXT: st1w { z0.s }, p0, [x1]499; CHECK-NEXT: ret500 %op1 = load <64 x float>, ptr %a501 %res = fptoui <64 x float> %op1 to <64 x i32>502 store <64 x i32> %res, ptr %b503 ret void504}505 506;507; FCVTZU S -> D508;509 510; Don't use SVE for 64-bit vectors.511define <1 x i64> @fcvtzu_v1f32_v1i64(<1 x float> %op1) vscale_range(2,0) #0 {512; CHECK-LABEL: fcvtzu_v1f32_v1i64:513; CHECK: // %bb.0:514; CHECK-NEXT: fcvtl v0.2d, v0.2s515; CHECK-NEXT: fcvtzu v0.2d, v0.2d516; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0517; CHECK-NEXT: ret518 %res = fptoui <1 x float> %op1 to <1 x i64>519 ret <1 x i64> %res520}521 522; Don't use SVE for 128-bit vectors.523define <2 x i64> @fcvtzu_v2f32_v2i64(<2 x float> %op1) vscale_range(2,0) #0 {524; CHECK-LABEL: fcvtzu_v2f32_v2i64:525; CHECK: // %bb.0:526; CHECK-NEXT: fcvtl v0.2d, v0.2s527; CHECK-NEXT: fcvtzu v0.2d, v0.2d528; CHECK-NEXT: ret529 %res = fptoui <2 x float> %op1 to <2 x i64>530 ret <2 x i64> %res531}532 533define void @fcvtzu_v4f32_v4i64(ptr %a, ptr %b) vscale_range(2,0) #0 {534; CHECK-LABEL: fcvtzu_v4f32_v4i64:535; CHECK: // %bb.0:536; CHECK-NEXT: ldr q0, [x0]537; CHECK-NEXT: ptrue p0.d, vl4538; CHECK-NEXT: uunpklo z0.d, z0.s539; CHECK-NEXT: fcvtzu z0.d, p0/m, z0.s540; CHECK-NEXT: st1d { z0.d }, p0, [x1]541; CHECK-NEXT: ret542 %op1 = load <4 x float>, ptr %a543 %res = fptoui <4 x float> %op1 to <4 x i64>544 store <4 x i64> %res, ptr %b545 ret void546}547 548define void @fcvtzu_v8f32_v8i64(ptr %a, ptr %b) #0 {549; VBITS_GE_256-LABEL: fcvtzu_v8f32_v8i64:550; VBITS_GE_256: // %bb.0:551; VBITS_GE_256-NEXT: ptrue p0.s, vl8552; VBITS_GE_256-NEXT: mov x8, #4 // =0x4553; VBITS_GE_256-NEXT: ld1w { z0.s }, p0/z, [x0]554; VBITS_GE_256-NEXT: ptrue p0.d, vl4555; VBITS_GE_256-NEXT: movprfx z1, z0556; VBITS_GE_256-NEXT: ext z1.b, z1.b, z0.b, #16557; VBITS_GE_256-NEXT: uunpklo z0.d, z0.s558; VBITS_GE_256-NEXT: uunpklo z1.d, z1.s559; VBITS_GE_256-NEXT: fcvtzu z0.d, p0/m, z0.s560; VBITS_GE_256-NEXT: fcvtzu z1.d, p0/m, z1.s561; VBITS_GE_256-NEXT: st1d { z0.d }, p0, [x1]562; VBITS_GE_256-NEXT: st1d { z1.d }, p0, [x1, x8, lsl #3]563; VBITS_GE_256-NEXT: ret564;565; VBITS_GE_512-LABEL: fcvtzu_v8f32_v8i64:566; VBITS_GE_512: // %bb.0:567; VBITS_GE_512-NEXT: ptrue p0.d, vl8568; VBITS_GE_512-NEXT: ld1w { z0.d }, p0/z, [x0]569; VBITS_GE_512-NEXT: fcvtzu z0.d, p0/m, z0.s570; VBITS_GE_512-NEXT: st1d { z0.d }, p0, [x1]571; VBITS_GE_512-NEXT: ret572 %op1 = load <8 x float>, ptr %a573 %res = fptoui <8 x float> %op1 to <8 x i64>574 store <8 x i64> %res, ptr %b575 ret void576}577 578define void @fcvtzu_v16f32_v16i64(ptr %a, ptr %b) vscale_range(8,0) #0 {579; CHECK-LABEL: fcvtzu_v16f32_v16i64:580; CHECK: // %bb.0:581; CHECK-NEXT: ptrue p0.d, vl16582; CHECK-NEXT: ld1w { z0.d }, p0/z, [x0]583; CHECK-NEXT: fcvtzu z0.d, p0/m, z0.s584; CHECK-NEXT: st1d { z0.d }, p0, [x1]585; CHECK-NEXT: ret586 %op1 = load <16 x float>, ptr %a587 %res = fptoui <16 x float> %op1 to <16 x i64>588 store <16 x i64> %res, ptr %b589 ret void590}591 592define void @fcvtzu_v32f32_v32i64(ptr %a, ptr %b) vscale_range(16,0) #0 {593; CHECK-LABEL: fcvtzu_v32f32_v32i64:594; CHECK: // %bb.0:595; CHECK-NEXT: ptrue p0.d, vl32596; CHECK-NEXT: ld1w { z0.d }, p0/z, [x0]597; CHECK-NEXT: fcvtzu z0.d, p0/m, z0.s598; CHECK-NEXT: st1d { z0.d }, p0, [x1]599; CHECK-NEXT: ret600 %op1 = load <32 x float>, ptr %a601 %res = fptoui <32 x float> %op1 to <32 x i64>602 store <32 x i64> %res, ptr %b603 ret void604}605 606 607;608; FCVTZU D -> H609;610 611; v1f64 is perfered to be widened to v4f64, so use SVE612define <1 x i16> @fcvtzu_v1f64_v1i16(<1 x double> %op1) vscale_range(2,0) #0 {613; CHECK-LABEL: fcvtzu_v1f64_v1i16:614; CHECK: // %bb.0:615; CHECK-NEXT: ptrue p0.d, vl4616; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0617; CHECK-NEXT: fcvtzu z0.d, p0/m, z0.d618; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s619; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h620; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0621; CHECK-NEXT: ret622 %res = fptoui <1 x double> %op1 to <1 x i16>623 ret <1 x i16> %res624}625 626; Don't use SVE for 128-bit vectors.627define <2 x i16> @fcvtzu_v2f64_v2i16(<2 x double> %op1) vscale_range(2,0) #0 {628; CHECK-LABEL: fcvtzu_v2f64_v2i16:629; CHECK: // %bb.0:630; CHECK-NEXT: fcvtzs v0.2d, v0.2d631; CHECK-NEXT: xtn v0.2s, v0.2d632; CHECK-NEXT: ret633 %res = fptoui <2 x double> %op1 to <2 x i16>634 ret <2 x i16> %res635}636 637define <4 x i16> @fcvtzu_v4f64_v4i16(ptr %a) vscale_range(2,0) #0 {638; CHECK-LABEL: fcvtzu_v4f64_v4i16:639; CHECK: // %bb.0:640; CHECK-NEXT: ptrue p0.d, vl4641; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]642; CHECK-NEXT: fcvtzu z0.d, p0/m, z0.d643; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s644; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h645; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0646; CHECK-NEXT: ret647 %op1 = load <4 x double>, ptr %a648 %res = fptoui <4 x double> %op1 to <4 x i16>649 ret <4 x i16> %res650}651 652define <8 x i16> @fcvtzu_v8f64_v8i16(ptr %a) #0 {653; VBITS_GE_256-LABEL: fcvtzu_v8f64_v8i16:654; VBITS_GE_256: // %bb.0:655; VBITS_GE_256-NEXT: ptrue p0.d, vl4656; VBITS_GE_256-NEXT: mov x8, #4 // =0x4657; VBITS_GE_256-NEXT: ld1d { z0.d }, p0/z, [x0, x8, lsl #3]658; VBITS_GE_256-NEXT: ld1d { z1.d }, p0/z, [x0]659; VBITS_GE_256-NEXT: fcvtzu z0.d, p0/m, z0.d660; VBITS_GE_256-NEXT: fcvtzu z1.d, p0/m, z1.d661; VBITS_GE_256-NEXT: uzp1 z0.s, z0.s, z0.s662; VBITS_GE_256-NEXT: uzp1 z1.s, z1.s, z1.s663; VBITS_GE_256-NEXT: uzp1 z2.h, z0.h, z0.h664; VBITS_GE_256-NEXT: uzp1 z0.h, z1.h, z1.h665; VBITS_GE_256-NEXT: mov v0.d[1], v2.d[0]666; VBITS_GE_256-NEXT: // kill: def $q0 killed $q0 killed $z0667; VBITS_GE_256-NEXT: ret668;669; VBITS_GE_512-LABEL: fcvtzu_v8f64_v8i16:670; VBITS_GE_512: // %bb.0:671; VBITS_GE_512-NEXT: ptrue p0.d, vl8672; VBITS_GE_512-NEXT: ld1d { z0.d }, p0/z, [x0]673; VBITS_GE_512-NEXT: fcvtzu z0.d, p0/m, z0.d674; VBITS_GE_512-NEXT: uzp1 z0.s, z0.s, z0.s675; VBITS_GE_512-NEXT: uzp1 z0.h, z0.h, z0.h676; VBITS_GE_512-NEXT: // kill: def $q0 killed $q0 killed $z0677; VBITS_GE_512-NEXT: ret678 %op1 = load <8 x double>, ptr %a679 %res = fptoui <8 x double> %op1 to <8 x i16>680 ret <8 x i16> %res681}682 683define void @fcvtzu_v16f64_v16i16(ptr %a, ptr %b) vscale_range(8,0) #0 {684; CHECK-LABEL: fcvtzu_v16f64_v16i16:685; CHECK: // %bb.0:686; CHECK-NEXT: ptrue p0.d, vl16687; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]688; CHECK-NEXT: fcvtzu z0.d, p0/m, z0.d689; CHECK-NEXT: st1h { z0.d }, p0, [x1]690; CHECK-NEXT: ret691 %op1 = load <16 x double>, ptr %a692 %res = fptoui <16 x double> %op1 to <16 x i16>693 store <16 x i16> %res, ptr %b694 ret void695}696 697define void @fcvtzu_v32f64_v32i16(ptr %a, ptr %b) vscale_range(16,0) #0 {698; CHECK-LABEL: fcvtzu_v32f64_v32i16:699; CHECK: // %bb.0:700; CHECK-NEXT: ptrue p0.d, vl32701; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]702; CHECK-NEXT: fcvtzu z0.d, p0/m, z0.d703; CHECK-NEXT: st1h { z0.d }, p0, [x1]704; CHECK-NEXT: ret705 %op1 = load <32 x double>, ptr %a706 %res = fptoui <32 x double> %op1 to <32 x i16>707 store <32 x i16> %res, ptr %b708 ret void709}710 711;712; FCVTZU D -> S713;714 715; Don't use SVE for 64-bit vectors.716define <1 x i32> @fcvtzu_v1f64_v1i32(<1 x double> %op1) vscale_range(2,0) #0 {717; CHECK-LABEL: fcvtzu_v1f64_v1i32:718; CHECK: // %bb.0:719; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0720; CHECK-NEXT: fcvtzu v0.2d, v0.2d721; CHECK-NEXT: xtn v0.2s, v0.2d722; CHECK-NEXT: ret723 %res = fptoui <1 x double> %op1 to <1 x i32>724 ret <1 x i32> %res725}726 727; Don't use SVE for 128-bit vectors.728define <2 x i32> @fcvtzu_v2f64_v2i32(<2 x double> %op1) vscale_range(2,0) #0 {729; CHECK-LABEL: fcvtzu_v2f64_v2i32:730; CHECK: // %bb.0:731; CHECK-NEXT: fcvtzu v0.2d, v0.2d732; CHECK-NEXT: xtn v0.2s, v0.2d733; CHECK-NEXT: ret734 %res = fptoui <2 x double> %op1 to <2 x i32>735 ret <2 x i32> %res736}737 738define <4 x i32> @fcvtzu_v4f64_v4i32(ptr %a) vscale_range(2,0) #0 {739; CHECK-LABEL: fcvtzu_v4f64_v4i32:740; CHECK: // %bb.0:741; CHECK-NEXT: ptrue p0.d, vl4742; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]743; CHECK-NEXT: fcvtzu z0.d, p0/m, z0.d744; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s745; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0746; CHECK-NEXT: ret747 %op1 = load <4 x double>, ptr %a748 %res = fptoui <4 x double> %op1 to <4 x i32>749 ret <4 x i32> %res750}751 752define void @fcvtzu_v8f64_v8i32(ptr %a, ptr %b) #0 {753; VBITS_GE_256-LABEL: fcvtzu_v8f64_v8i32:754; VBITS_GE_256: // %bb.0:755; VBITS_GE_256-NEXT: ptrue p0.d, vl4756; VBITS_GE_256-NEXT: mov x8, #4 // =0x4757; VBITS_GE_256-NEXT: ld1d { z0.d }, p0/z, [x0, x8, lsl #3]758; VBITS_GE_256-NEXT: ld1d { z1.d }, p0/z, [x0]759; VBITS_GE_256-NEXT: fcvtzu z0.d, p0/m, z0.d760; VBITS_GE_256-NEXT: fcvtzu z1.d, p0/m, z1.d761; VBITS_GE_256-NEXT: ptrue p0.s, vl4762; VBITS_GE_256-NEXT: uzp1 z0.s, z0.s, z0.s763; VBITS_GE_256-NEXT: uzp1 z1.s, z1.s, z1.s764; VBITS_GE_256-NEXT: splice z1.s, p0, z1.s, z0.s765; VBITS_GE_256-NEXT: ptrue p0.s, vl8766; VBITS_GE_256-NEXT: st1w { z1.s }, p0, [x1]767; VBITS_GE_256-NEXT: ret768;769; VBITS_GE_512-LABEL: fcvtzu_v8f64_v8i32:770; VBITS_GE_512: // %bb.0:771; VBITS_GE_512-NEXT: ptrue p0.d, vl8772; VBITS_GE_512-NEXT: ld1d { z0.d }, p0/z, [x0]773; VBITS_GE_512-NEXT: fcvtzu z0.d, p0/m, z0.d774; VBITS_GE_512-NEXT: st1w { z0.d }, p0, [x1]775; VBITS_GE_512-NEXT: ret776 %op1 = load <8 x double>, ptr %a777 %res = fptoui <8 x double> %op1 to <8 x i32>778 store <8 x i32> %res, ptr %b779 ret void780}781 782define void @fcvtzu_v16f64_v16i32(ptr %a, ptr %b) vscale_range(8,0) #0 {783; CHECK-LABEL: fcvtzu_v16f64_v16i32:784; CHECK: // %bb.0:785; CHECK-NEXT: ptrue p0.d, vl16786; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]787; CHECK-NEXT: fcvtzu z0.d, p0/m, z0.d788; CHECK-NEXT: st1w { z0.d }, p0, [x1]789; CHECK-NEXT: ret790 %op1 = load <16 x double>, ptr %a791 %res = fptoui <16 x double> %op1 to <16 x i32>792 store <16 x i32> %res, ptr %b793 ret void794}795 796define void @fcvtzu_v32f64_v32i32(ptr %a, ptr %b) vscale_range(16,0) #0 {797; CHECK-LABEL: fcvtzu_v32f64_v32i32:798; CHECK: // %bb.0:799; CHECK-NEXT: ptrue p0.d, vl32800; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]801; CHECK-NEXT: fcvtzu z0.d, p0/m, z0.d802; CHECK-NEXT: st1w { z0.d }, p0, [x1]803; CHECK-NEXT: ret804 %op1 = load <32 x double>, ptr %a805 %res = fptoui <32 x double> %op1 to <32 x i32>806 store <32 x i32> %res, ptr %b807 ret void808}809 810;811; FCVTZU D -> D812;813 814; Don't use SVE for 64-bit vectors.815define <1 x i64> @fcvtzu_v1f64_v1i64(<1 x double> %op1) vscale_range(2,0) #0 {816; CHECK-LABEL: fcvtzu_v1f64_v1i64:817; CHECK: // %bb.0:818; CHECK-NEXT: fcvtzu x8, d0819; CHECK-NEXT: fmov d0, x8820; CHECK-NEXT: ret821 %res = fptoui <1 x double> %op1 to <1 x i64>822 ret <1 x i64> %res823}824 825; Don't use SVE for 128-bit vectors.826define <2 x i64> @fcvtzu_v2f64_v2i64(<2 x double> %op1) vscale_range(2,0) #0 {827; CHECK-LABEL: fcvtzu_v2f64_v2i64:828; CHECK: // %bb.0:829; CHECK-NEXT: fcvtzu v0.2d, v0.2d830; CHECK-NEXT: ret831 %res = fptoui <2 x double> %op1 to <2 x i64>832 ret <2 x i64> %res833}834 835define void @fcvtzu_v4f64_v4i64(ptr %a, ptr %b) vscale_range(2,0) #0 {836; CHECK-LABEL: fcvtzu_v4f64_v4i64:837; CHECK: // %bb.0:838; CHECK-NEXT: ptrue p0.d, vl4839; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]840; CHECK-NEXT: fcvtzu z0.d, p0/m, z0.d841; CHECK-NEXT: st1d { z0.d }, p0, [x1]842; CHECK-NEXT: ret843 %op1 = load <4 x double>, ptr %a844 %res = fptoui <4 x double> %op1 to <4 x i64>845 store <4 x i64> %res, ptr %b846 ret void847}848 849define void @fcvtzu_v8f64_v8i64(ptr %a, ptr %b) #0 {850; VBITS_GE_256-LABEL: fcvtzu_v8f64_v8i64:851; VBITS_GE_256: // %bb.0:852; VBITS_GE_256-NEXT: ptrue p0.d, vl4853; VBITS_GE_256-NEXT: mov x8, #4 // =0x4854; VBITS_GE_256-NEXT: ld1d { z0.d }, p0/z, [x0, x8, lsl #3]855; VBITS_GE_256-NEXT: ld1d { z1.d }, p0/z, [x0]856; VBITS_GE_256-NEXT: fcvtzu z0.d, p0/m, z0.d857; VBITS_GE_256-NEXT: fcvtzu z1.d, p0/m, z1.d858; VBITS_GE_256-NEXT: st1d { z0.d }, p0, [x1, x8, lsl #3]859; VBITS_GE_256-NEXT: st1d { z1.d }, p0, [x1]860; VBITS_GE_256-NEXT: ret861;862; VBITS_GE_512-LABEL: fcvtzu_v8f64_v8i64:863; VBITS_GE_512: // %bb.0:864; VBITS_GE_512-NEXT: ptrue p0.d, vl8865; VBITS_GE_512-NEXT: ld1d { z0.d }, p0/z, [x0]866; VBITS_GE_512-NEXT: fcvtzu z0.d, p0/m, z0.d867; VBITS_GE_512-NEXT: st1d { z0.d }, p0, [x1]868; VBITS_GE_512-NEXT: ret869 %op1 = load <8 x double>, ptr %a870 %res = fptoui <8 x double> %op1 to <8 x i64>871 store <8 x i64> %res, ptr %b872 ret void873}874 875define void @fcvtzu_v16f64_v16i64(ptr %a, ptr %b) vscale_range(8,0) #0 {876; CHECK-LABEL: fcvtzu_v16f64_v16i64:877; CHECK: // %bb.0:878; CHECK-NEXT: ptrue p0.d, vl16879; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]880; CHECK-NEXT: fcvtzu z0.d, p0/m, z0.d881; CHECK-NEXT: st1d { z0.d }, p0, [x1]882; CHECK-NEXT: ret883 %op1 = load <16 x double>, ptr %a884 %res = fptoui <16 x double> %op1 to <16 x i64>885 store <16 x i64> %res, ptr %b886 ret void887}888 889define void @fcvtzu_v32f64_v32i64(ptr %a, ptr %b) vscale_range(16,0) #0 {890; CHECK-LABEL: fcvtzu_v32f64_v32i64:891; CHECK: // %bb.0:892; CHECK-NEXT: ptrue p0.d, vl32893; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]894; CHECK-NEXT: fcvtzu z0.d, p0/m, z0.d895; CHECK-NEXT: st1d { z0.d }, p0, [x1]896; CHECK-NEXT: ret897 %op1 = load <32 x double>, ptr %a898 %res = fptoui <32 x double> %op1 to <32 x i64>899 store <32 x i64> %res, ptr %b900 ret void901}902 903;904; FCVTZS H -> H905;906 907; Don't use SVE for 64-bit vectors.908define <4 x i16> @fcvtzs_v4f16_v4i16(<4 x half> %op1) vscale_range(2,0) #0 {909; CHECK-LABEL: fcvtzs_v4f16_v4i16:910; CHECK: // %bb.0:911; CHECK-NEXT: fcvtzs v0.4h, v0.4h912; CHECK-NEXT: ret913 %res = fptosi <4 x half> %op1 to <4 x i16>914 ret <4 x i16> %res915}916 917; Don't use SVE for 128-bit vectors.918define void @fcvtzs_v8f16_v8i16(ptr %a, ptr %b) vscale_range(2,0) #0 {919; CHECK-LABEL: fcvtzs_v8f16_v8i16:920; CHECK: // %bb.0:921; CHECK-NEXT: ldr q0, [x0]922; CHECK-NEXT: fcvtzs v0.8h, v0.8h923; CHECK-NEXT: str q0, [x1]924; CHECK-NEXT: ret925 %op1 = load <8 x half>, ptr %a926 %res = fptosi <8 x half> %op1 to <8 x i16>927 store <8 x i16> %res, ptr %b928 ret void929}930 931define void @fcvtzs_v16f16_v16i16(ptr %a, ptr %b) vscale_range(2,0) #0 {932; CHECK-LABEL: fcvtzs_v16f16_v16i16:933; CHECK: // %bb.0:934; CHECK-NEXT: ptrue p0.h, vl16935; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0]936; CHECK-NEXT: fcvtzs z0.h, p0/m, z0.h937; CHECK-NEXT: st1h { z0.h }, p0, [x1]938; CHECK-NEXT: ret939 %op1 = load <16 x half>, ptr %a940 %res = fptosi <16 x half> %op1 to <16 x i16>941 store <16 x i16> %res, ptr %b942 ret void943}944 945define void @fcvtzs_v32f16_v32i16(ptr %a, ptr %b) #0 {946; VBITS_GE_256-LABEL: fcvtzs_v32f16_v32i16:947; VBITS_GE_256: // %bb.0:948; VBITS_GE_256-NEXT: ptrue p0.h, vl16949; VBITS_GE_256-NEXT: mov x8, #16 // =0x10950; VBITS_GE_256-NEXT: ld1h { z0.h }, p0/z, [x0, x8, lsl #1]951; VBITS_GE_256-NEXT: ld1h { z1.h }, p0/z, [x0]952; VBITS_GE_256-NEXT: fcvtzs z0.h, p0/m, z0.h953; VBITS_GE_256-NEXT: fcvtzs z1.h, p0/m, z1.h954; VBITS_GE_256-NEXT: st1h { z0.h }, p0, [x1, x8, lsl #1]955; VBITS_GE_256-NEXT: st1h { z1.h }, p0, [x1]956; VBITS_GE_256-NEXT: ret957;958; VBITS_GE_512-LABEL: fcvtzs_v32f16_v32i16:959; VBITS_GE_512: // %bb.0:960; VBITS_GE_512-NEXT: ptrue p0.h, vl32961; VBITS_GE_512-NEXT: ld1h { z0.h }, p0/z, [x0]962; VBITS_GE_512-NEXT: fcvtzs z0.h, p0/m, z0.h963; VBITS_GE_512-NEXT: st1h { z0.h }, p0, [x1]964; VBITS_GE_512-NEXT: ret965 %op1 = load <32 x half>, ptr %a966 %res = fptosi <32 x half> %op1 to <32 x i16>967 store <32 x i16> %res, ptr %b968 ret void969}970 971define void @fcvtzs_v64f16_v64i16(ptr %a, ptr %b) vscale_range(8,0) #0 {972; CHECK-LABEL: fcvtzs_v64f16_v64i16:973; CHECK: // %bb.0:974; CHECK-NEXT: ptrue p0.h, vl64975; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0]976; CHECK-NEXT: fcvtzs z0.h, p0/m, z0.h977; CHECK-NEXT: st1h { z0.h }, p0, [x1]978; CHECK-NEXT: ret979 %op1 = load <64 x half>, ptr %a980 %res = fptosi <64 x half> %op1 to <64 x i16>981 store <64 x i16> %res, ptr %b982 ret void983}984 985define void @fcvtzs_v128f16_v128i16(ptr %a, ptr %b) vscale_range(16,0) #0 {986; CHECK-LABEL: fcvtzs_v128f16_v128i16:987; CHECK: // %bb.0:988; CHECK-NEXT: ptrue p0.h, vl128989; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0]990; CHECK-NEXT: fcvtzs z0.h, p0/m, z0.h991; CHECK-NEXT: st1h { z0.h }, p0, [x1]992; CHECK-NEXT: ret993 %op1 = load <128 x half>, ptr %a994 %res = fptosi <128 x half> %op1 to <128 x i16>995 store <128 x i16> %res, ptr %b996 ret void997}998 999;1000; FCVTZS H -> S1001;1002 1003; Don't use SVE for 64-bit vectors.1004define <2 x i32> @fcvtzs_v2f16_v2i32(<2 x half> %op1) vscale_range(2,0) #0 {1005; CHECK-LABEL: fcvtzs_v2f16_v2i32:1006; CHECK: // %bb.0:1007; CHECK-NEXT: fcvtl v0.4s, v0.4h1008; CHECK-NEXT: fcvtzs v0.4s, v0.4s1009; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q01010; CHECK-NEXT: ret1011 %res = fptosi <2 x half> %op1 to <2 x i32>1012 ret <2 x i32> %res1013}1014 1015; Don't use SVE for 128-bit vectors.1016define <4 x i32> @fcvtzs_v4f16_v4i32(<4 x half> %op1) vscale_range(2,0) #0 {1017; CHECK-LABEL: fcvtzs_v4f16_v4i32:1018; CHECK: // %bb.0:1019; CHECK-NEXT: fcvtl v0.4s, v0.4h1020; CHECK-NEXT: fcvtzs v0.4s, v0.4s1021; CHECK-NEXT: ret1022 %res = fptosi <4 x half> %op1 to <4 x i32>1023 ret <4 x i32> %res1024}1025 1026define void @fcvtzs_v8f16_v8i32(ptr %a, ptr %b) vscale_range(2,0) #0 {1027; CHECK-LABEL: fcvtzs_v8f16_v8i32:1028; CHECK: // %bb.0:1029; CHECK-NEXT: ldr q0, [x0]1030; CHECK-NEXT: ptrue p0.s, vl81031; CHECK-NEXT: uunpklo z0.s, z0.h1032; CHECK-NEXT: fcvtzs z0.s, p0/m, z0.h1033; CHECK-NEXT: st1w { z0.s }, p0, [x1]1034; CHECK-NEXT: ret1035 %op1 = load <8 x half>, ptr %a1036 %res = fptosi <8 x half> %op1 to <8 x i32>1037 store <8 x i32> %res, ptr %b1038 ret void1039}1040 1041define void @fcvtzs_v16f16_v16i32(ptr %a, ptr %b) #0 {1042; VBITS_GE_256-LABEL: fcvtzs_v16f16_v16i32:1043; VBITS_GE_256: // %bb.0:1044; VBITS_GE_256-NEXT: ptrue p0.h, vl161045; VBITS_GE_256-NEXT: mov x8, #8 // =0x81046; VBITS_GE_256-NEXT: ld1h { z0.h }, p0/z, [x0]1047; VBITS_GE_256-NEXT: ptrue p0.s, vl81048; VBITS_GE_256-NEXT: movprfx z1, z01049; VBITS_GE_256-NEXT: ext z1.b, z1.b, z0.b, #161050; VBITS_GE_256-NEXT: uunpklo z0.s, z0.h1051; VBITS_GE_256-NEXT: uunpklo z1.s, z1.h1052; VBITS_GE_256-NEXT: fcvtzs z0.s, p0/m, z0.h1053; VBITS_GE_256-NEXT: fcvtzs z1.s, p0/m, z1.h1054; VBITS_GE_256-NEXT: st1w { z0.s }, p0, [x1]1055; VBITS_GE_256-NEXT: st1w { z1.s }, p0, [x1, x8, lsl #2]1056; VBITS_GE_256-NEXT: ret1057;1058; VBITS_GE_512-LABEL: fcvtzs_v16f16_v16i32:1059; VBITS_GE_512: // %bb.0:1060; VBITS_GE_512-NEXT: ptrue p0.s, vl161061; VBITS_GE_512-NEXT: ld1h { z0.s }, p0/z, [x0]1062; VBITS_GE_512-NEXT: fcvtzs z0.s, p0/m, z0.h1063; VBITS_GE_512-NEXT: st1w { z0.s }, p0, [x1]1064; VBITS_GE_512-NEXT: ret1065 %op1 = load <16 x half>, ptr %a1066 %res = fptosi <16 x half> %op1 to <16 x i32>1067 store <16 x i32> %res, ptr %b1068 ret void1069}1070 1071define void @fcvtzs_v32f16_v32i32(ptr %a, ptr %b) vscale_range(8,0) #0 {1072; CHECK-LABEL: fcvtzs_v32f16_v32i32:1073; CHECK: // %bb.0:1074; CHECK-NEXT: ptrue p0.s, vl321075; CHECK-NEXT: ld1h { z0.s }, p0/z, [x0]1076; CHECK-NEXT: fcvtzs z0.s, p0/m, z0.h1077; CHECK-NEXT: st1w { z0.s }, p0, [x1]1078; CHECK-NEXT: ret1079 %op1 = load <32 x half>, ptr %a1080 %res = fptosi <32 x half> %op1 to <32 x i32>1081 store <32 x i32> %res, ptr %b1082 ret void1083}1084 1085define void @fcvtzs_v64f16_v64i32(ptr %a, ptr %b) vscale_range(16,0) #0 {1086; CHECK-LABEL: fcvtzs_v64f16_v64i32:1087; CHECK: // %bb.0:1088; CHECK-NEXT: ptrue p0.s, vl641089; CHECK-NEXT: ld1h { z0.s }, p0/z, [x0]1090; CHECK-NEXT: fcvtzs z0.s, p0/m, z0.h1091; CHECK-NEXT: st1w { z0.s }, p0, [x1]1092; CHECK-NEXT: ret1093 %op1 = load <64 x half>, ptr %a1094 %res = fptosi <64 x half> %op1 to <64 x i32>1095 store <64 x i32> %res, ptr %b1096 ret void1097}1098 1099;1100; FCVTZS H -> D1101;1102 1103; Don't use SVE for 64-bit vectors.1104define <1 x i64> @fcvtzs_v1f16_v1i64(<1 x half> %op1) vscale_range(2,0) #0 {1105; CHECK-LABEL: fcvtzs_v1f16_v1i64:1106; CHECK: // %bb.0:1107; CHECK-NEXT: fcvtzs x8, h01108; CHECK-NEXT: fmov d0, x81109; CHECK-NEXT: ret1110 %res = fptosi <1 x half> %op1 to <1 x i64>1111 ret <1 x i64> %res1112}1113 1114; v2f16 is not legal for NEON, so use SVE1115define <2 x i64> @fcvtzs_v2f16_v2i64(<2 x half> %op1) vscale_range(2,0) #0 {1116; CHECK-LABEL: fcvtzs_v2f16_v2i64:1117; CHECK: // %bb.0:1118; CHECK-NEXT: // kill: def $d0 killed $d0 def $z01119; CHECK-NEXT: ptrue p0.d, vl41120; CHECK-NEXT: uunpklo z0.s, z0.h1121; CHECK-NEXT: uunpklo z0.d, z0.s1122; CHECK-NEXT: fcvtzs z0.d, p0/m, z0.h1123; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z01124; CHECK-NEXT: ret1125 %res = fptosi <2 x half> %op1 to <2 x i64>1126 ret <2 x i64> %res1127}1128 1129define void @fcvtzs_v4f16_v4i64(ptr %a, ptr %b) vscale_range(2,0) #0 {1130; CHECK-LABEL: fcvtzs_v4f16_v4i64:1131; CHECK: // %bb.0:1132; CHECK-NEXT: ldr d0, [x0]1133; CHECK-NEXT: ptrue p0.d, vl41134; CHECK-NEXT: uunpklo z0.s, z0.h1135; CHECK-NEXT: uunpklo z0.d, z0.s1136; CHECK-NEXT: fcvtzs z0.d, p0/m, z0.h1137; CHECK-NEXT: st1d { z0.d }, p0, [x1]1138; CHECK-NEXT: ret1139 %op1 = load <4 x half>, ptr %a1140 %res = fptosi <4 x half> %op1 to <4 x i64>1141 store <4 x i64> %res, ptr %b1142 ret void1143}1144 1145define void @fcvtzs_v8f16_v8i64(ptr %a, ptr %b) #0 {1146; VBITS_GE_256-LABEL: fcvtzs_v8f16_v8i64:1147; VBITS_GE_256: // %bb.0:1148; VBITS_GE_256-NEXT: ldr q0, [x0]1149; VBITS_GE_256-NEXT: ptrue p0.d, vl41150; VBITS_GE_256-NEXT: mov x8, #4 // =0x41151; VBITS_GE_256-NEXT: ext v1.16b, v0.16b, v0.16b, #81152; VBITS_GE_256-NEXT: uunpklo z0.s, z0.h1153; VBITS_GE_256-NEXT: uunpklo z1.s, z1.h1154; VBITS_GE_256-NEXT: uunpklo z0.d, z0.s1155; VBITS_GE_256-NEXT: uunpklo z1.d, z1.s1156; VBITS_GE_256-NEXT: fcvtzs z0.d, p0/m, z0.h1157; VBITS_GE_256-NEXT: fcvtzs z1.d, p0/m, z1.h1158; VBITS_GE_256-NEXT: st1d { z0.d }, p0, [x1]1159; VBITS_GE_256-NEXT: st1d { z1.d }, p0, [x1, x8, lsl #3]1160; VBITS_GE_256-NEXT: ret1161;1162; VBITS_GE_512-LABEL: fcvtzs_v8f16_v8i64:1163; VBITS_GE_512: // %bb.0:1164; VBITS_GE_512-NEXT: ldr q0, [x0]1165; VBITS_GE_512-NEXT: ptrue p0.d, vl81166; VBITS_GE_512-NEXT: uunpklo z0.s, z0.h1167; VBITS_GE_512-NEXT: uunpklo z0.d, z0.s1168; VBITS_GE_512-NEXT: fcvtzs z0.d, p0/m, z0.h1169; VBITS_GE_512-NEXT: st1d { z0.d }, p0, [x1]1170; VBITS_GE_512-NEXT: ret1171 %op1 = load <8 x half>, ptr %a1172 %res = fptosi <8 x half> %op1 to <8 x i64>1173 store <8 x i64> %res, ptr %b1174 ret void1175}1176 1177define void @fcvtzs_v16f16_v16i64(ptr %a, ptr %b) vscale_range(8,0) #0 {1178; CHECK-LABEL: fcvtzs_v16f16_v16i64:1179; CHECK: // %bb.0:1180; CHECK-NEXT: ptrue p0.d, vl161181; CHECK-NEXT: ld1h { z0.d }, p0/z, [x0]1182; CHECK-NEXT: fcvtzs z0.d, p0/m, z0.h1183; CHECK-NEXT: st1d { z0.d }, p0, [x1]1184; CHECK-NEXT: ret1185 %op1 = load <16 x half>, ptr %a1186 %res = fptosi <16 x half> %op1 to <16 x i64>1187 store <16 x i64> %res, ptr %b1188 ret void1189}1190 1191define void @fcvtzs_v32f16_v32i64(ptr %a, ptr %b) vscale_range(16,0) #0 {1192; CHECK-LABEL: fcvtzs_v32f16_v32i64:1193; CHECK: // %bb.0:1194; CHECK-NEXT: ptrue p0.d, vl321195; CHECK-NEXT: ld1h { z0.d }, p0/z, [x0]1196; CHECK-NEXT: fcvtzs z0.d, p0/m, z0.h1197; CHECK-NEXT: st1d { z0.d }, p0, [x1]1198; CHECK-NEXT: ret1199 %op1 = load <32 x half>, ptr %a1200 %res = fptosi <32 x half> %op1 to <32 x i64>1201 store <32 x i64> %res, ptr %b1202 ret void1203}1204 1205;1206; FCVTZS S -> H1207;1208 1209; Don't use SVE for 64-bit vectors.1210define <2 x i16> @fcvtzs_v2f32_v2i16(<2 x float> %op1) vscale_range(2,0) #0 {1211; CHECK-LABEL: fcvtzs_v2f32_v2i16:1212; CHECK: // %bb.0:1213; CHECK-NEXT: fcvtzs v0.2s, v0.2s1214; CHECK-NEXT: ret1215 %res = fptosi <2 x float> %op1 to <2 x i16>1216 ret <2 x i16> %res1217}1218 1219; Don't use SVE for 128-bit vectors.1220define <4 x i16> @fcvtzs_v4f32_v4i16(<4 x float> %op1) vscale_range(2,0) #0 {1221; CHECK-LABEL: fcvtzs_v4f32_v4i16:1222; CHECK: // %bb.0:1223; CHECK-NEXT: fcvtzs v1.4s, v0.4s1224; CHECK-NEXT: mov w8, v1.s[1]1225; CHECK-NEXT: mov v0.16b, v1.16b1226; CHECK-NEXT: mov w9, v1.s[2]1227; CHECK-NEXT: mov v0.h[1], w81228; CHECK-NEXT: mov w8, v1.s[3]1229; CHECK-NEXT: mov v0.h[2], w91230; CHECK-NEXT: mov v0.h[3], w81231; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q01232; CHECK-NEXT: ret1233 %res = fptosi <4 x float> %op1 to <4 x i16>1234 ret <4 x i16> %res1235}1236 1237define <8 x i16> @fcvtzs_v8f32_v8i16(ptr %a) vscale_range(2,0) #0 {1238; CHECK-LABEL: fcvtzs_v8f32_v8i16:1239; CHECK: // %bb.0:1240; CHECK-NEXT: ptrue p0.s, vl81241; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]1242; CHECK-NEXT: fcvtzs z0.s, p0/m, z0.s1243; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h1244; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z01245; CHECK-NEXT: ret1246 %op1 = load <8 x float>, ptr %a1247 %res = fptosi <8 x float> %op1 to <8 x i16>1248 ret <8 x i16> %res1249}1250 1251define void @fcvtzs_v16f32_v16i16(ptr %a, ptr %b) #0 {1252; VBITS_GE_256-LABEL: fcvtzs_v16f32_v16i16:1253; VBITS_GE_256: // %bb.0:1254; VBITS_GE_256-NEXT: ptrue p0.s, vl81255; VBITS_GE_256-NEXT: mov x8, #8 // =0x81256; VBITS_GE_256-NEXT: ld1w { z0.s }, p0/z, [x0, x8, lsl #2]1257; VBITS_GE_256-NEXT: ld1w { z1.s }, p0/z, [x0]1258; VBITS_GE_256-NEXT: fcvtzs z0.s, p0/m, z0.s1259; VBITS_GE_256-NEXT: fcvtzs z1.s, p0/m, z1.s1260; VBITS_GE_256-NEXT: ptrue p0.h, vl81261; VBITS_GE_256-NEXT: uzp1 z0.h, z0.h, z0.h1262; VBITS_GE_256-NEXT: uzp1 z1.h, z1.h, z1.h1263; VBITS_GE_256-NEXT: splice z1.h, p0, z1.h, z0.h1264; VBITS_GE_256-NEXT: ptrue p0.h, vl161265; VBITS_GE_256-NEXT: st1h { z1.h }, p0, [x1]1266; VBITS_GE_256-NEXT: ret1267;1268; VBITS_GE_512-LABEL: fcvtzs_v16f32_v16i16:1269; VBITS_GE_512: // %bb.0:1270; VBITS_GE_512-NEXT: ptrue p0.s, vl161271; VBITS_GE_512-NEXT: ld1w { z0.s }, p0/z, [x0]1272; VBITS_GE_512-NEXT: fcvtzs z0.s, p0/m, z0.s1273; VBITS_GE_512-NEXT: st1h { z0.s }, p0, [x1]1274; VBITS_GE_512-NEXT: ret1275 %op1 = load <16 x float>, ptr %a1276 %res = fptosi <16 x float> %op1 to <16 x i16>1277 store <16 x i16> %res, ptr %b1278 ret void1279}1280 1281define void @fcvtzs_v32f32_v32i16(ptr %a, ptr %b) vscale_range(8,0) #0 {1282; CHECK-LABEL: fcvtzs_v32f32_v32i16:1283; CHECK: // %bb.0:1284; CHECK-NEXT: ptrue p0.s, vl321285; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]1286; CHECK-NEXT: fcvtzs z0.s, p0/m, z0.s1287; CHECK-NEXT: st1h { z0.s }, p0, [x1]1288; CHECK-NEXT: ret1289 %op1 = load <32 x float>, ptr %a1290 %res = fptosi <32 x float> %op1 to <32 x i16>1291 store <32 x i16> %res, ptr %b1292 ret void1293}1294 1295define void @fcvtzs_v64f32_v64i16(ptr %a, ptr %b) vscale_range(16,0) #0 {1296; CHECK-LABEL: fcvtzs_v64f32_v64i16:1297; CHECK: // %bb.0:1298; CHECK-NEXT: ptrue p0.s, vl641299; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]1300; CHECK-NEXT: fcvtzs z0.s, p0/m, z0.s1301; CHECK-NEXT: st1h { z0.s }, p0, [x1]1302; CHECK-NEXT: ret1303 %op1 = load <64 x float>, ptr %a1304 %res = fptosi <64 x float> %op1 to <64 x i16>1305 store <64 x i16> %res, ptr %b1306 ret void1307}1308 1309;1310; FCVTZS S -> S1311;1312 1313; Don't use SVE for 64-bit vectors.1314define <2 x i32> @fcvtzs_v2f32_v2i32(<2 x float> %op1) vscale_range(2,0) #0 {1315; CHECK-LABEL: fcvtzs_v2f32_v2i32:1316; CHECK: // %bb.0:1317; CHECK-NEXT: fcvtzs v0.2s, v0.2s1318; CHECK-NEXT: ret1319 %res = fptosi <2 x float> %op1 to <2 x i32>1320 ret <2 x i32> %res1321}1322 1323; Don't use SVE for 128-bit vectors.1324define <4 x i32> @fcvtzs_v4f32_v4i32(<4 x float> %op1) vscale_range(2,0) #0 {1325; CHECK-LABEL: fcvtzs_v4f32_v4i32:1326; CHECK: // %bb.0:1327; CHECK-NEXT: fcvtzs v0.4s, v0.4s1328; CHECK-NEXT: ret1329 %res = fptosi <4 x float> %op1 to <4 x i32>1330 ret <4 x i32> %res1331}1332 1333define void @fcvtzs_v8f32_v8i32(ptr %a, ptr %b) vscale_range(2,0) #0 {1334; CHECK-LABEL: fcvtzs_v8f32_v8i32:1335; CHECK: // %bb.0:1336; CHECK-NEXT: ptrue p0.s, vl81337; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]1338; CHECK-NEXT: fcvtzs z0.s, p0/m, z0.s1339; CHECK-NEXT: st1w { z0.s }, p0, [x1]1340; CHECK-NEXT: ret1341 %op1 = load <8 x float>, ptr %a1342 %res = fptosi <8 x float> %op1 to <8 x i32>1343 store <8 x i32> %res, ptr %b1344 ret void1345}1346 1347define void @fcvtzs_v16f32_v16i32(ptr %a, ptr %b) #0 {1348; VBITS_GE_256-LABEL: fcvtzs_v16f32_v16i32:1349; VBITS_GE_256: // %bb.0:1350; VBITS_GE_256-NEXT: ptrue p0.s, vl81351; VBITS_GE_256-NEXT: mov x8, #8 // =0x81352; VBITS_GE_256-NEXT: ld1w { z0.s }, p0/z, [x0, x8, lsl #2]1353; VBITS_GE_256-NEXT: ld1w { z1.s }, p0/z, [x0]1354; VBITS_GE_256-NEXT: fcvtzs z0.s, p0/m, z0.s1355; VBITS_GE_256-NEXT: fcvtzs z1.s, p0/m, z1.s1356; VBITS_GE_256-NEXT: st1w { z0.s }, p0, [x1, x8, lsl #2]1357; VBITS_GE_256-NEXT: st1w { z1.s }, p0, [x1]1358; VBITS_GE_256-NEXT: ret1359;1360; VBITS_GE_512-LABEL: fcvtzs_v16f32_v16i32:1361; VBITS_GE_512: // %bb.0:1362; VBITS_GE_512-NEXT: ptrue p0.s, vl161363; VBITS_GE_512-NEXT: ld1w { z0.s }, p0/z, [x0]1364; VBITS_GE_512-NEXT: fcvtzs z0.s, p0/m, z0.s1365; VBITS_GE_512-NEXT: st1w { z0.s }, p0, [x1]1366; VBITS_GE_512-NEXT: ret1367 %op1 = load <16 x float>, ptr %a1368 %res = fptosi <16 x float> %op1 to <16 x i32>1369 store <16 x i32> %res, ptr %b1370 ret void1371}1372 1373define void @fcvtzs_v32f32_v32i32(ptr %a, ptr %b) vscale_range(8,0) #0 {1374; CHECK-LABEL: fcvtzs_v32f32_v32i32:1375; CHECK: // %bb.0:1376; CHECK-NEXT: ptrue p0.s, vl321377; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]1378; CHECK-NEXT: fcvtzs z0.s, p0/m, z0.s1379; CHECK-NEXT: st1w { z0.s }, p0, [x1]1380; CHECK-NEXT: ret1381 %op1 = load <32 x float>, ptr %a1382 %res = fptosi <32 x float> %op1 to <32 x i32>1383 store <32 x i32> %res, ptr %b1384 ret void1385}1386 1387define void @fcvtzs_v64f32_v64i32(ptr %a, ptr %b) vscale_range(16,0) #0 {1388; CHECK-LABEL: fcvtzs_v64f32_v64i32:1389; CHECK: // %bb.0:1390; CHECK-NEXT: ptrue p0.s, vl641391; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]1392; CHECK-NEXT: fcvtzs z0.s, p0/m, z0.s1393; CHECK-NEXT: st1w { z0.s }, p0, [x1]1394; CHECK-NEXT: ret1395 %op1 = load <64 x float>, ptr %a1396 %res = fptosi <64 x float> %op1 to <64 x i32>1397 store <64 x i32> %res, ptr %b1398 ret void1399}1400 1401;1402; FCVTZS S -> D1403;1404 1405; Don't use SVE for 64-bit vectors.1406define <1 x i64> @fcvtzs_v1f32_v1i64(<1 x float> %op1) vscale_range(2,0) #0 {1407; CHECK-LABEL: fcvtzs_v1f32_v1i64:1408; CHECK: // %bb.0:1409; CHECK-NEXT: fcvtl v0.2d, v0.2s1410; CHECK-NEXT: fcvtzs v0.2d, v0.2d1411; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q01412; CHECK-NEXT: ret1413 %res = fptosi <1 x float> %op1 to <1 x i64>1414 ret <1 x i64> %res1415}1416 1417; Don't use SVE for 128-bit vectors.1418define <2 x i64> @fcvtzs_v2f32_v2i64(<2 x float> %op1) vscale_range(2,0) #0 {1419; CHECK-LABEL: fcvtzs_v2f32_v2i64:1420; CHECK: // %bb.0:1421; CHECK-NEXT: fcvtl v0.2d, v0.2s1422; CHECK-NEXT: fcvtzs v0.2d, v0.2d1423; CHECK-NEXT: ret1424 %res = fptosi <2 x float> %op1 to <2 x i64>1425 ret <2 x i64> %res1426}1427 1428define void @fcvtzs_v4f32_v4i64(ptr %a, ptr %b) vscale_range(2,0) #0 {1429; CHECK-LABEL: fcvtzs_v4f32_v4i64:1430; CHECK: // %bb.0:1431; CHECK-NEXT: ldr q0, [x0]1432; CHECK-NEXT: ptrue p0.d, vl41433; CHECK-NEXT: uunpklo z0.d, z0.s1434; CHECK-NEXT: fcvtzs z0.d, p0/m, z0.s1435; CHECK-NEXT: st1d { z0.d }, p0, [x1]1436; CHECK-NEXT: ret1437 %op1 = load <4 x float>, ptr %a1438 %res = fptosi <4 x float> %op1 to <4 x i64>1439 store <4 x i64> %res, ptr %b1440 ret void1441}1442 1443define void @fcvtzs_v8f32_v8i64(ptr %a, ptr %b) #0 {1444; VBITS_GE_256-LABEL: fcvtzs_v8f32_v8i64:1445; VBITS_GE_256: // %bb.0:1446; VBITS_GE_256-NEXT: ptrue p0.s, vl81447; VBITS_GE_256-NEXT: mov x8, #4 // =0x41448; VBITS_GE_256-NEXT: ld1w { z0.s }, p0/z, [x0]1449; VBITS_GE_256-NEXT: ptrue p0.d, vl41450; VBITS_GE_256-NEXT: movprfx z1, z01451; VBITS_GE_256-NEXT: ext z1.b, z1.b, z0.b, #161452; VBITS_GE_256-NEXT: uunpklo z0.d, z0.s1453; VBITS_GE_256-NEXT: uunpklo z1.d, z1.s1454; VBITS_GE_256-NEXT: fcvtzs z0.d, p0/m, z0.s1455; VBITS_GE_256-NEXT: fcvtzs z1.d, p0/m, z1.s1456; VBITS_GE_256-NEXT: st1d { z0.d }, p0, [x1]1457; VBITS_GE_256-NEXT: st1d { z1.d }, p0, [x1, x8, lsl #3]1458; VBITS_GE_256-NEXT: ret1459;1460; VBITS_GE_512-LABEL: fcvtzs_v8f32_v8i64:1461; VBITS_GE_512: // %bb.0:1462; VBITS_GE_512-NEXT: ptrue p0.d, vl81463; VBITS_GE_512-NEXT: ld1w { z0.d }, p0/z, [x0]1464; VBITS_GE_512-NEXT: fcvtzs z0.d, p0/m, z0.s1465; VBITS_GE_512-NEXT: st1d { z0.d }, p0, [x1]1466; VBITS_GE_512-NEXT: ret1467 %op1 = load <8 x float>, ptr %a1468 %res = fptosi <8 x float> %op1 to <8 x i64>1469 store <8 x i64> %res, ptr %b1470 ret void1471}1472 1473define void @fcvtzs_v16f32_v16i64(ptr %a, ptr %b) vscale_range(8,0) #0 {1474; CHECK-LABEL: fcvtzs_v16f32_v16i64:1475; CHECK: // %bb.0:1476; CHECK-NEXT: ptrue p0.d, vl161477; CHECK-NEXT: ld1w { z0.d }, p0/z, [x0]1478; CHECK-NEXT: fcvtzs z0.d, p0/m, z0.s1479; CHECK-NEXT: st1d { z0.d }, p0, [x1]1480; CHECK-NEXT: ret1481 %op1 = load <16 x float>, ptr %a1482 %res = fptosi <16 x float> %op1 to <16 x i64>1483 store <16 x i64> %res, ptr %b1484 ret void1485}1486 1487define void @fcvtzs_v32f32_v32i64(ptr %a, ptr %b) vscale_range(16,0) #0 {1488; CHECK-LABEL: fcvtzs_v32f32_v32i64:1489; CHECK: // %bb.0:1490; CHECK-NEXT: ptrue p0.d, vl321491; CHECK-NEXT: ld1w { z0.d }, p0/z, [x0]1492; CHECK-NEXT: fcvtzs z0.d, p0/m, z0.s1493; CHECK-NEXT: st1d { z0.d }, p0, [x1]1494; CHECK-NEXT: ret1495 %op1 = load <32 x float>, ptr %a1496 %res = fptosi <32 x float> %op1 to <32 x i64>1497 store <32 x i64> %res, ptr %b1498 ret void1499}1500 1501 1502;1503; FCVTZS D -> H1504;1505 1506; v1f64 is perfered to be widened to v4f64, so use SVE1507define <1 x i16> @fcvtzs_v1f64_v1i16(<1 x double> %op1) vscale_range(2,0) #0 {1508; CHECK-LABEL: fcvtzs_v1f64_v1i16:1509; CHECK: // %bb.0:1510; CHECK-NEXT: ptrue p0.d, vl41511; CHECK-NEXT: // kill: def $d0 killed $d0 def $z01512; CHECK-NEXT: fcvtzs z0.d, p0/m, z0.d1513; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s1514; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h1515; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z01516; CHECK-NEXT: ret1517 %res = fptosi <1 x double> %op1 to <1 x i16>1518 ret <1 x i16> %res1519}1520 1521; Don't use SVE for 128-bit vectors.1522define <2 x i16> @fcvtzs_v2f64_v2i16(<2 x double> %op1) vscale_range(2,0) #0 {1523; CHECK-LABEL: fcvtzs_v2f64_v2i16:1524; CHECK: // %bb.0:1525; CHECK-NEXT: fcvtzs v0.2d, v0.2d1526; CHECK-NEXT: xtn v0.2s, v0.2d1527; CHECK-NEXT: ret1528 %res = fptosi <2 x double> %op1 to <2 x i16>1529 ret <2 x i16> %res1530}1531 1532define <4 x i16> @fcvtzs_v4f64_v4i16(ptr %a) vscale_range(2,0) #0 {1533; CHECK-LABEL: fcvtzs_v4f64_v4i16:1534; CHECK: // %bb.0:1535; CHECK-NEXT: ptrue p0.d, vl41536; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]1537; CHECK-NEXT: fcvtzs z0.d, p0/m, z0.d1538; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s1539; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h1540; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z01541; CHECK-NEXT: ret1542 %op1 = load <4 x double>, ptr %a1543 %res = fptosi <4 x double> %op1 to <4 x i16>1544 ret <4 x i16> %res1545}1546 1547define <8 x i16> @fcvtzs_v8f64_v8i16(ptr %a) #0 {1548; VBITS_GE_256-LABEL: fcvtzs_v8f64_v8i16:1549; VBITS_GE_256: // %bb.0:1550; VBITS_GE_256-NEXT: ptrue p0.d, vl41551; VBITS_GE_256-NEXT: mov x8, #4 // =0x41552; VBITS_GE_256-NEXT: ld1d { z0.d }, p0/z, [x0, x8, lsl #3]1553; VBITS_GE_256-NEXT: ld1d { z1.d }, p0/z, [x0]1554; VBITS_GE_256-NEXT: fcvtzs z0.d, p0/m, z0.d1555; VBITS_GE_256-NEXT: fcvtzs z1.d, p0/m, z1.d1556; VBITS_GE_256-NEXT: uzp1 z0.s, z0.s, z0.s1557; VBITS_GE_256-NEXT: uzp1 z1.s, z1.s, z1.s1558; VBITS_GE_256-NEXT: uzp1 z2.h, z0.h, z0.h1559; VBITS_GE_256-NEXT: uzp1 z0.h, z1.h, z1.h1560; VBITS_GE_256-NEXT: mov v0.d[1], v2.d[0]1561; VBITS_GE_256-NEXT: // kill: def $q0 killed $q0 killed $z01562; VBITS_GE_256-NEXT: ret1563;1564; VBITS_GE_512-LABEL: fcvtzs_v8f64_v8i16:1565; VBITS_GE_512: // %bb.0:1566; VBITS_GE_512-NEXT: ptrue p0.d, vl81567; VBITS_GE_512-NEXT: ld1d { z0.d }, p0/z, [x0]1568; VBITS_GE_512-NEXT: fcvtzs z0.d, p0/m, z0.d1569; VBITS_GE_512-NEXT: uzp1 z0.s, z0.s, z0.s1570; VBITS_GE_512-NEXT: uzp1 z0.h, z0.h, z0.h1571; VBITS_GE_512-NEXT: // kill: def $q0 killed $q0 killed $z01572; VBITS_GE_512-NEXT: ret1573 %op1 = load <8 x double>, ptr %a1574 %res = fptosi <8 x double> %op1 to <8 x i16>1575 ret <8 x i16> %res1576}1577 1578define void @fcvtzs_v16f64_v16i16(ptr %a, ptr %b) vscale_range(8,0) #0 {1579; CHECK-LABEL: fcvtzs_v16f64_v16i16:1580; CHECK: // %bb.0:1581; CHECK-NEXT: ptrue p0.d, vl161582; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]1583; CHECK-NEXT: fcvtzs z0.d, p0/m, z0.d1584; CHECK-NEXT: st1h { z0.d }, p0, [x1]1585; CHECK-NEXT: ret1586 %op1 = load <16 x double>, ptr %a1587 %res = fptosi <16 x double> %op1 to <16 x i16>1588 store <16 x i16> %res, ptr %b1589 ret void1590}1591 1592define void @fcvtzs_v32f64_v32i16(ptr %a, ptr %b) vscale_range(16,0) #0 {1593; CHECK-LABEL: fcvtzs_v32f64_v32i16:1594; CHECK: // %bb.0:1595; CHECK-NEXT: ptrue p0.d, vl321596; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]1597; CHECK-NEXT: fcvtzs z0.d, p0/m, z0.d1598; CHECK-NEXT: st1h { z0.d }, p0, [x1]1599; CHECK-NEXT: ret1600 %op1 = load <32 x double>, ptr %a1601 %res = fptosi <32 x double> %op1 to <32 x i16>1602 store <32 x i16> %res, ptr %b1603 ret void1604}1605 1606;1607; FCVTZS D -> S1608;1609 1610; Don't use SVE for 64-bit vectors.1611define <1 x i32> @fcvtzs_v1f64_v1i32(<1 x double> %op1) vscale_range(2,0) #0 {1612; CHECK-LABEL: fcvtzs_v1f64_v1i32:1613; CHECK: // %bb.0:1614; CHECK-NEXT: // kill: def $d0 killed $d0 def $q01615; CHECK-NEXT: fcvtzs v0.2d, v0.2d1616; CHECK-NEXT: xtn v0.2s, v0.2d1617; CHECK-NEXT: ret1618 %res = fptosi <1 x double> %op1 to <1 x i32>1619 ret <1 x i32> %res1620}1621 1622; Don't use SVE for 128-bit vectors.1623define <2 x i32> @fcvtzs_v2f64_v2i32(<2 x double> %op1) vscale_range(2,0) #0 {1624; CHECK-LABEL: fcvtzs_v2f64_v2i32:1625; CHECK: // %bb.0:1626; CHECK-NEXT: fcvtzs v0.2d, v0.2d1627; CHECK-NEXT: xtn v0.2s, v0.2d1628; CHECK-NEXT: ret1629 %res = fptosi <2 x double> %op1 to <2 x i32>1630 ret <2 x i32> %res1631}1632 1633define <4 x i32> @fcvtzs_v4f64_v4i32(ptr %a) vscale_range(2,0) #0 {1634; CHECK-LABEL: fcvtzs_v4f64_v4i32:1635; CHECK: // %bb.0:1636; CHECK-NEXT: ptrue p0.d, vl41637; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]1638; CHECK-NEXT: fcvtzs z0.d, p0/m, z0.d1639; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s1640; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z01641; CHECK-NEXT: ret1642 %op1 = load <4 x double>, ptr %a1643 %res = fptosi <4 x double> %op1 to <4 x i32>1644 ret <4 x i32> %res1645}1646 1647define void @fcvtzs_v8f64_v8i32(ptr %a, ptr %b) #0 {1648; VBITS_GE_256-LABEL: fcvtzs_v8f64_v8i32:1649; VBITS_GE_256: // %bb.0:1650; VBITS_GE_256-NEXT: ptrue p0.d, vl41651; VBITS_GE_256-NEXT: mov x8, #4 // =0x41652; VBITS_GE_256-NEXT: ld1d { z0.d }, p0/z, [x0, x8, lsl #3]1653; VBITS_GE_256-NEXT: ld1d { z1.d }, p0/z, [x0]1654; VBITS_GE_256-NEXT: fcvtzs z0.d, p0/m, z0.d1655; VBITS_GE_256-NEXT: fcvtzs z1.d, p0/m, z1.d1656; VBITS_GE_256-NEXT: ptrue p0.s, vl41657; VBITS_GE_256-NEXT: uzp1 z0.s, z0.s, z0.s1658; VBITS_GE_256-NEXT: uzp1 z1.s, z1.s, z1.s1659; VBITS_GE_256-NEXT: splice z1.s, p0, z1.s, z0.s1660; VBITS_GE_256-NEXT: ptrue p0.s, vl81661; VBITS_GE_256-NEXT: st1w { z1.s }, p0, [x1]1662; VBITS_GE_256-NEXT: ret1663;1664; VBITS_GE_512-LABEL: fcvtzs_v8f64_v8i32:1665; VBITS_GE_512: // %bb.0:1666; VBITS_GE_512-NEXT: ptrue p0.d, vl81667; VBITS_GE_512-NEXT: ld1d { z0.d }, p0/z, [x0]1668; VBITS_GE_512-NEXT: fcvtzs z0.d, p0/m, z0.d1669; VBITS_GE_512-NEXT: st1w { z0.d }, p0, [x1]1670; VBITS_GE_512-NEXT: ret1671 %op1 = load <8 x double>, ptr %a1672 %res = fptosi <8 x double> %op1 to <8 x i32>1673 store <8 x i32> %res, ptr %b1674 ret void1675}1676 1677define void @fcvtzs_v16f64_v16i32(ptr %a, ptr %b) vscale_range(8,0) #0 {1678; CHECK-LABEL: fcvtzs_v16f64_v16i32:1679; CHECK: // %bb.0:1680; CHECK-NEXT: ptrue p0.d, vl161681; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]1682; CHECK-NEXT: fcvtzs z0.d, p0/m, z0.d1683; CHECK-NEXT: st1w { z0.d }, p0, [x1]1684; CHECK-NEXT: ret1685 %op1 = load <16 x double>, ptr %a1686 %res = fptosi <16 x double> %op1 to <16 x i32>1687 store <16 x i32> %res, ptr %b1688 ret void1689}1690 1691define void @fcvtzs_v32f64_v32i32(ptr %a, ptr %b) vscale_range(16,0) #0 {1692; CHECK-LABEL: fcvtzs_v32f64_v32i32:1693; CHECK: // %bb.0:1694; CHECK-NEXT: ptrue p0.d, vl321695; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]1696; CHECK-NEXT: fcvtzs z0.d, p0/m, z0.d1697; CHECK-NEXT: st1w { z0.d }, p0, [x1]1698; CHECK-NEXT: ret1699 %op1 = load <32 x double>, ptr %a1700 %res = fptosi <32 x double> %op1 to <32 x i32>1701 store <32 x i32> %res, ptr %b1702 ret void1703}1704 1705;1706; FCVTZS D -> D1707;1708 1709; Don't use SVE for 64-bit vectors.1710define <1 x i64> @fcvtzs_v1f64_v1i64(<1 x double> %op1) vscale_range(2,0) #0 {1711; CHECK-LABEL: fcvtzs_v1f64_v1i64:1712; CHECK: // %bb.0:1713; CHECK-NEXT: fcvtzs x8, d01714; CHECK-NEXT: fmov d0, x81715; CHECK-NEXT: ret1716 %res = fptosi <1 x double> %op1 to <1 x i64>1717 ret <1 x i64> %res1718}1719 1720; Don't use SVE for 128-bit vectors.1721define <2 x i64> @fcvtzs_v2f64_v2i64(<2 x double> %op1) vscale_range(2,0) #0 {1722; CHECK-LABEL: fcvtzs_v2f64_v2i64:1723; CHECK: // %bb.0:1724; CHECK-NEXT: fcvtzs v0.2d, v0.2d1725; CHECK-NEXT: ret1726 %res = fptosi <2 x double> %op1 to <2 x i64>1727 ret <2 x i64> %res1728}1729 1730define void @fcvtzs_v4f64_v4i64(ptr %a, ptr %b) vscale_range(2,0) #0 {1731; CHECK-LABEL: fcvtzs_v4f64_v4i64:1732; CHECK: // %bb.0:1733; CHECK-NEXT: ptrue p0.d, vl41734; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]1735; CHECK-NEXT: fcvtzs z0.d, p0/m, z0.d1736; CHECK-NEXT: st1d { z0.d }, p0, [x1]1737; CHECK-NEXT: ret1738 %op1 = load <4 x double>, ptr %a1739 %res = fptosi <4 x double> %op1 to <4 x i64>1740 store <4 x i64> %res, ptr %b1741 ret void1742}1743 1744define void @fcvtzs_v8f64_v8i64(ptr %a, ptr %b) #0 {1745; VBITS_GE_256-LABEL: fcvtzs_v8f64_v8i64:1746; VBITS_GE_256: // %bb.0:1747; VBITS_GE_256-NEXT: ptrue p0.d, vl41748; VBITS_GE_256-NEXT: mov x8, #4 // =0x41749; VBITS_GE_256-NEXT: ld1d { z0.d }, p0/z, [x0, x8, lsl #3]1750; VBITS_GE_256-NEXT: ld1d { z1.d }, p0/z, [x0]1751; VBITS_GE_256-NEXT: fcvtzs z0.d, p0/m, z0.d1752; VBITS_GE_256-NEXT: fcvtzs z1.d, p0/m, z1.d1753; VBITS_GE_256-NEXT: st1d { z0.d }, p0, [x1, x8, lsl #3]1754; VBITS_GE_256-NEXT: st1d { z1.d }, p0, [x1]1755; VBITS_GE_256-NEXT: ret1756;1757; VBITS_GE_512-LABEL: fcvtzs_v8f64_v8i64:1758; VBITS_GE_512: // %bb.0:1759; VBITS_GE_512-NEXT: ptrue p0.d, vl81760; VBITS_GE_512-NEXT: ld1d { z0.d }, p0/z, [x0]1761; VBITS_GE_512-NEXT: fcvtzs z0.d, p0/m, z0.d1762; VBITS_GE_512-NEXT: st1d { z0.d }, p0, [x1]1763; VBITS_GE_512-NEXT: ret1764 %op1 = load <8 x double>, ptr %a1765 %res = fptosi <8 x double> %op1 to <8 x i64>1766 store <8 x i64> %res, ptr %b1767 ret void1768}1769 1770define void @fcvtzs_v16f64_v16i64(ptr %a, ptr %b) vscale_range(8,0) #0 {1771; CHECK-LABEL: fcvtzs_v16f64_v16i64:1772; CHECK: // %bb.0:1773; CHECK-NEXT: ptrue p0.d, vl161774; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]1775; CHECK-NEXT: fcvtzs z0.d, p0/m, z0.d1776; CHECK-NEXT: st1d { z0.d }, p0, [x1]1777; CHECK-NEXT: ret1778 %op1 = load <16 x double>, ptr %a1779 %res = fptosi <16 x double> %op1 to <16 x i64>1780 store <16 x i64> %res, ptr %b1781 ret void1782}1783 1784define void @fcvtzs_v32f64_v32i64(ptr %a, ptr %b) vscale_range(16,0) #0 {1785; CHECK-LABEL: fcvtzs_v32f64_v32i64:1786; CHECK: // %bb.0:1787; CHECK-NEXT: ptrue p0.d, vl321788; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]1789; CHECK-NEXT: fcvtzs z0.d, p0/m, z0.d1790; CHECK-NEXT: st1d { z0.d }, p0, [x1]1791; CHECK-NEXT: ret1792 %op1 = load <32 x double>, ptr %a1793 %res = fptosi <32 x double> %op1 to <32 x i64>1794 store <32 x i64> %res, ptr %b1795 ret void1796}1797 1798attributes #0 = { "target-features"="+sve" }1799