617 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; FCVT H -> S10;11 12; Don't use SVE for 64-bit vectors.13define void @fcvt_v2f16_v2f32(ptr %a, ptr %b) vscale_range(2,0) #0 {14; CHECK-LABEL: fcvt_v2f16_v2f32:15; CHECK: // %bb.0:16; CHECK-NEXT: ldr s0, [x0]17; CHECK-NEXT: fcvtl v0.4s, v0.4h18; CHECK-NEXT: str d0, [x1]19; CHECK-NEXT: ret20 %op1 = load <2 x half>, ptr %a21 %res = fpext <2 x half> %op1 to <2 x float>22 store <2 x float> %res, ptr %b23 ret void24}25 26; Don't use SVE for 128-bit vectors.27define void @fcvt_v4f16_v4f32(ptr %a, ptr %b) vscale_range(2,0) #0 {28; CHECK-LABEL: fcvt_v4f16_v4f32:29; CHECK: // %bb.0:30; CHECK-NEXT: ldr d0, [x0]31; CHECK-NEXT: fcvtl v0.4s, v0.4h32; CHECK-NEXT: str q0, [x1]33; CHECK-NEXT: ret34 %op1 = load <4 x half>, ptr %a35 %res = fpext <4 x half> %op1 to <4 x float>36 store <4 x float> %res, ptr %b37 ret void38}39 40define void @fcvt_v8f16_v8f32(ptr %a, ptr %b) vscale_range(2,0) #0 {41; CHECK-LABEL: fcvt_v8f16_v8f32:42; CHECK: // %bb.0:43; CHECK-NEXT: ptrue p0.s, vl844; CHECK-NEXT: ld1h { z0.s }, p0/z, [x0]45; CHECK-NEXT: fcvt z0.s, p0/m, z0.h46; CHECK-NEXT: st1w { z0.s }, p0, [x1]47; CHECK-NEXT: ret48 %op1 = load <8 x half>, ptr %a49 %res = fpext <8 x half> %op1 to <8 x float>50 store <8 x float> %res, ptr %b51 ret void52}53 54define void @fcvt_v16f16_v16f32(ptr %a, ptr %b) #0 {55; VBITS_GE_256-LABEL: fcvt_v16f16_v16f32:56; VBITS_GE_256: // %bb.0:57; VBITS_GE_256-NEXT: ptrue p0.s, vl858; VBITS_GE_256-NEXT: mov x8, #8 // =0x859; VBITS_GE_256-NEXT: ld1h { z0.s }, p0/z, [x0, x8, lsl #1]60; VBITS_GE_256-NEXT: ld1h { z1.s }, p0/z, [x0]61; VBITS_GE_256-NEXT: fcvt z0.s, p0/m, z0.h62; VBITS_GE_256-NEXT: fcvt z1.s, p0/m, z1.h63; VBITS_GE_256-NEXT: st1w { z0.s }, p0, [x1, x8, lsl #2]64; VBITS_GE_256-NEXT: st1w { z1.s }, p0, [x1]65; VBITS_GE_256-NEXT: ret66;67; VBITS_GE_512-LABEL: fcvt_v16f16_v16f32:68; VBITS_GE_512: // %bb.0:69; VBITS_GE_512-NEXT: ptrue p0.s, vl1670; VBITS_GE_512-NEXT: ld1h { z0.s }, p0/z, [x0]71; VBITS_GE_512-NEXT: fcvt z0.s, p0/m, z0.h72; VBITS_GE_512-NEXT: st1w { z0.s }, p0, [x1]73; VBITS_GE_512-NEXT: ret74 %op1 = load <16 x half>, ptr %a75 %res = fpext <16 x half> %op1 to <16 x float>76 store <16 x float> %res, ptr %b77 ret void78}79 80define void @fcvt_v32f16_v32f32(ptr %a, ptr %b) vscale_range(8,0) #0 {81; CHECK-LABEL: fcvt_v32f16_v32f32:82; CHECK: // %bb.0:83; CHECK-NEXT: ptrue p0.s, vl3284; CHECK-NEXT: ld1h { z0.s }, p0/z, [x0]85; CHECK-NEXT: fcvt z0.s, p0/m, z0.h86; CHECK-NEXT: st1w { z0.s }, p0, [x1]87; CHECK-NEXT: ret88 %op1 = load <32 x half>, ptr %a89 %res = fpext <32 x half> %op1 to <32 x float>90 store <32 x float> %res, ptr %b91 ret void92}93 94define void @fcvt_v64f16_v64f32(ptr %a, ptr %b) vscale_range(16,0) #0 {95; CHECK-LABEL: fcvt_v64f16_v64f32:96; CHECK: // %bb.0:97; CHECK-NEXT: ptrue p0.s, vl6498; CHECK-NEXT: ld1h { z0.s }, p0/z, [x0]99; CHECK-NEXT: fcvt z0.s, p0/m, z0.h100; CHECK-NEXT: st1w { z0.s }, p0, [x1]101; CHECK-NEXT: ret102 %op1 = load <64 x half>, ptr %a103 %res = fpext <64 x half> %op1 to <64 x float>104 store <64 x float> %res, ptr %b105 ret void106}107 108;109; FCVT H -> D110;111 112; Don't use SVE for 64-bit vectors.113define void @fcvt_v1f16_v1f64(ptr %a, ptr %b) vscale_range(2,0) #0 {114; CHECK-LABEL: fcvt_v1f16_v1f64:115; CHECK: // %bb.0:116; CHECK-NEXT: ldr h0, [x0]117; CHECK-NEXT: fcvt d0, h0118; CHECK-NEXT: str d0, [x1]119; CHECK-NEXT: ret120 %op1 = load <1 x half>, ptr %a121 %res = fpext <1 x half> %op1 to <1 x double>122 store <1 x double> %res, ptr %b123 ret void124}125 126; v2f16 is not legal for NEON, so use SVE127define void @fcvt_v2f16_v2f64(ptr %a, ptr %b) vscale_range(2,0) #0 {128; CHECK-LABEL: fcvt_v2f16_v2f64:129; CHECK: // %bb.0:130; CHECK-NEXT: ldr s0, [x0]131; CHECK-NEXT: ptrue p0.d, vl4132; CHECK-NEXT: uunpklo z0.s, z0.h133; CHECK-NEXT: uunpklo z0.d, z0.s134; CHECK-NEXT: fcvt z0.d, p0/m, z0.h135; CHECK-NEXT: str q0, [x1]136; CHECK-NEXT: ret137 %op1 = load <2 x half>, ptr %a138 %res = fpext <2 x half> %op1 to <2 x double>139 store <2 x double> %res, ptr %b140 ret void141}142 143define void @fcvt_v4f16_v4f64(ptr %a, ptr %b) vscale_range(2,0) #0 {144; CHECK-LABEL: fcvt_v4f16_v4f64:145; CHECK: // %bb.0:146; CHECK-NEXT: ptrue p0.d, vl4147; CHECK-NEXT: ld1h { z0.d }, p0/z, [x0]148; CHECK-NEXT: fcvt z0.d, p0/m, z0.h149; CHECK-NEXT: st1d { z0.d }, p0, [x1]150; CHECK-NEXT: ret151 %op1 = load <4 x half>, ptr %a152 %res = fpext <4 x half> %op1 to <4 x double>153 store <4 x double> %res, ptr %b154 ret void155}156 157define void @fcvt_v8f16_v8f64(ptr %a, ptr %b) #0 {158; VBITS_GE_256-LABEL: fcvt_v8f16_v8f64:159; VBITS_GE_256: // %bb.0:160; VBITS_GE_256-NEXT: ptrue p0.d, vl4161; VBITS_GE_256-NEXT: mov x8, #4 // =0x4162; VBITS_GE_256-NEXT: ld1h { z0.d }, p0/z, [x0, x8, lsl #1]163; VBITS_GE_256-NEXT: ld1h { z1.d }, p0/z, [x0]164; VBITS_GE_256-NEXT: fcvt z0.d, p0/m, z0.h165; VBITS_GE_256-NEXT: fcvt z1.d, p0/m, z1.h166; VBITS_GE_256-NEXT: st1d { z0.d }, p0, [x1, x8, lsl #3]167; VBITS_GE_256-NEXT: st1d { z1.d }, p0, [x1]168; VBITS_GE_256-NEXT: ret169;170; VBITS_GE_512-LABEL: fcvt_v8f16_v8f64:171; VBITS_GE_512: // %bb.0:172; VBITS_GE_512-NEXT: ptrue p0.d, vl8173; VBITS_GE_512-NEXT: ld1h { z0.d }, p0/z, [x0]174; VBITS_GE_512-NEXT: fcvt z0.d, p0/m, z0.h175; VBITS_GE_512-NEXT: st1d { z0.d }, p0, [x1]176; VBITS_GE_512-NEXT: ret177 %op1 = load <8 x half>, ptr %a178 %res = fpext <8 x half> %op1 to <8 x double>179 store <8 x double> %res, ptr %b180 ret void181}182 183define void @fcvt_v16f16_v16f64(ptr %a, ptr %b) vscale_range(8,0) #0 {184; CHECK-LABEL: fcvt_v16f16_v16f64:185; CHECK: // %bb.0:186; CHECK-NEXT: ptrue p0.d, vl16187; CHECK-NEXT: ld1h { z0.d }, p0/z, [x0]188; CHECK-NEXT: fcvt z0.d, p0/m, z0.h189; CHECK-NEXT: st1d { z0.d }, p0, [x1]190; CHECK-NEXT: ret191 %op1 = load <16 x half>, ptr %a192 %res = fpext <16 x half> %op1 to <16 x double>193 store <16 x double> %res, ptr %b194 ret void195}196 197define void @fcvt_v32f16_v32f64(ptr %a, ptr %b) vscale_range(16,0) #0 {198; CHECK-LABEL: fcvt_v32f16_v32f64:199; CHECK: // %bb.0:200; CHECK-NEXT: ptrue p0.d, vl32201; CHECK-NEXT: ld1h { z0.d }, p0/z, [x0]202; CHECK-NEXT: fcvt z0.d, p0/m, z0.h203; CHECK-NEXT: st1d { z0.d }, p0, [x1]204; CHECK-NEXT: ret205 %op1 = load <32 x half>, ptr %a206 %res = fpext <32 x half> %op1 to <32 x double>207 store <32 x double> %res, ptr %b208 ret void209}210 211;212; FCVT S -> D213;214 215; Don't use SVE for 64-bit vectors.216define void @fcvt_v1f32_v1f64(ptr %a, ptr %b) vscale_range(2,0) #0 {217; CHECK-LABEL: fcvt_v1f32_v1f64:218; CHECK: // %bb.0:219; CHECK-NEXT: ldr s0, [x0]220; CHECK-NEXT: fcvtl v0.2d, v0.2s221; CHECK-NEXT: str d0, [x1]222; CHECK-NEXT: ret223 %op1 = load <1 x float>, ptr %a224 %res = fpext <1 x float> %op1 to <1 x double>225 store <1 x double> %res, ptr %b226 ret void227}228 229; Don't use SVE for 128-bit vectors.230define void @fcvt_v2f32_v2f64(ptr %a, ptr %b) vscale_range(2,0) #0 {231; CHECK-LABEL: fcvt_v2f32_v2f64:232; CHECK: // %bb.0:233; CHECK-NEXT: ldr d0, [x0]234; CHECK-NEXT: fcvtl v0.2d, v0.2s235; CHECK-NEXT: str q0, [x1]236; CHECK-NEXT: ret237 %op1 = load <2 x float>, ptr %a238 %res = fpext <2 x float> %op1 to <2 x double>239 store <2 x double> %res, ptr %b240 ret void241}242 243define void @fcvt_v4f32_v4f64(ptr %a, ptr %b) vscale_range(2,0) #0 {244; CHECK-LABEL: fcvt_v4f32_v4f64:245; CHECK: // %bb.0:246; CHECK-NEXT: ptrue p0.d, vl4247; CHECK-NEXT: ld1w { z0.d }, p0/z, [x0]248; CHECK-NEXT: fcvt z0.d, p0/m, z0.s249; CHECK-NEXT: st1d { z0.d }, p0, [x1]250; CHECK-NEXT: ret251 %op1 = load <4 x float>, ptr %a252 %res = fpext <4 x float> %op1 to <4 x double>253 store <4 x double> %res, ptr %b254 ret void255}256 257define void @fcvt_v8f32_v8f64(ptr %a, ptr %b) #0 {258; VBITS_GE_256-LABEL: fcvt_v8f32_v8f64:259; VBITS_GE_256: // %bb.0:260; VBITS_GE_256-NEXT: ptrue p0.d, vl4261; VBITS_GE_256-NEXT: mov x8, #4 // =0x4262; VBITS_GE_256-NEXT: ld1w { z0.d }, p0/z, [x0, x8, lsl #2]263; VBITS_GE_256-NEXT: ld1w { z1.d }, p0/z, [x0]264; VBITS_GE_256-NEXT: fcvt z0.d, p0/m, z0.s265; VBITS_GE_256-NEXT: fcvt z1.d, p0/m, z1.s266; VBITS_GE_256-NEXT: st1d { z0.d }, p0, [x1, x8, lsl #3]267; VBITS_GE_256-NEXT: st1d { z1.d }, p0, [x1]268; VBITS_GE_256-NEXT: ret269;270; VBITS_GE_512-LABEL: fcvt_v8f32_v8f64:271; VBITS_GE_512: // %bb.0:272; VBITS_GE_512-NEXT: ptrue p0.d, vl8273; VBITS_GE_512-NEXT: ld1w { z0.d }, p0/z, [x0]274; VBITS_GE_512-NEXT: fcvt z0.d, p0/m, z0.s275; VBITS_GE_512-NEXT: st1d { z0.d }, p0, [x1]276; VBITS_GE_512-NEXT: ret277 %op1 = load <8 x float>, ptr %a278 %res = fpext <8 x float> %op1 to <8 x double>279 store <8 x double> %res, ptr %b280 ret void281}282 283define void @fcvt_v16f32_v16f64(ptr %a, ptr %b) vscale_range(8,0) #0 {284; CHECK-LABEL: fcvt_v16f32_v16f64:285; CHECK: // %bb.0:286; CHECK-NEXT: ptrue p0.d, vl16287; CHECK-NEXT: ld1w { z0.d }, p0/z, [x0]288; CHECK-NEXT: fcvt z0.d, p0/m, z0.s289; CHECK-NEXT: st1d { z0.d }, p0, [x1]290; CHECK-NEXT: ret291 %op1 = load <16 x float>, ptr %a292 %res = fpext <16 x float> %op1 to <16 x double>293 store <16 x double> %res, ptr %b294 ret void295}296 297define void @fcvt_v32f32_v32f64(ptr %a, ptr %b) vscale_range(16,0) #0 {298; CHECK-LABEL: fcvt_v32f32_v32f64:299; CHECK: // %bb.0:300; CHECK-NEXT: ptrue p0.d, vl32301; CHECK-NEXT: ld1w { z0.d }, p0/z, [x0]302; CHECK-NEXT: fcvt z0.d, p0/m, z0.s303; CHECK-NEXT: st1d { z0.d }, p0, [x1]304; CHECK-NEXT: ret305 %op1 = load <32 x float>, ptr %a306 %res = fpext <32 x float> %op1 to <32 x double>307 store <32 x double> %res, ptr %b308 ret void309}310 311;312; FCVT S -> H313;314 315; Don't use SVE for 64-bit vectors.316define void @fcvt_v2f32_v2f16(ptr %a, ptr %b) vscale_range(2,0) #0 {317; CHECK-LABEL: fcvt_v2f32_v2f16:318; CHECK: // %bb.0:319; CHECK-NEXT: ldr d0, [x0]320; CHECK-NEXT: fcvtn v0.4h, v0.4s321; CHECK-NEXT: str s0, [x1]322; CHECK-NEXT: ret323 %op1 = load <2 x float>, ptr %a324 %res = fptrunc <2 x float> %op1 to <2 x half>325 store <2 x half> %res, ptr %b326 ret void327}328 329; Don't use SVE for 128-bit vectors.330define void @fcvt_v4f32_v4f16(ptr %a, ptr %b) vscale_range(2,0) #0 {331; CHECK-LABEL: fcvt_v4f32_v4f16:332; CHECK: // %bb.0:333; CHECK-NEXT: ldr q0, [x0]334; CHECK-NEXT: fcvtn v0.4h, v0.4s335; CHECK-NEXT: str d0, [x1]336; CHECK-NEXT: ret337 %op1 = load <4 x float>, ptr %a338 %res = fptrunc <4 x float> %op1 to <4 x half>339 store <4 x half> %res, ptr %b340 ret void341}342 343define void @fcvt_v8f32_v8f16(ptr %a, ptr %b) vscale_range(2,0) #0 {344; CHECK-LABEL: fcvt_v8f32_v8f16:345; CHECK: // %bb.0:346; CHECK-NEXT: ptrue p0.s, vl8347; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]348; CHECK-NEXT: fcvt z0.h, p0/m, z0.s349; CHECK-NEXT: st1h { z0.s }, p0, [x1]350; CHECK-NEXT: ret351 %op1 = load <8 x float>, ptr %a352 %res = fptrunc <8 x float> %op1 to <8 x half>353 store <8 x half> %res, ptr %b354 ret void355}356 357define void @fcvt_v16f32_v16f16(ptr %a, ptr %b) #0 {358; VBITS_GE_256-LABEL: fcvt_v16f32_v16f16:359; VBITS_GE_256: // %bb.0:360; VBITS_GE_256-NEXT: ptrue p0.s, vl8361; VBITS_GE_256-NEXT: mov x8, #8 // =0x8362; VBITS_GE_256-NEXT: ld1w { z0.s }, p0/z, [x0, x8, lsl #2]363; VBITS_GE_256-NEXT: ld1w { z1.s }, p0/z, [x0]364; VBITS_GE_256-NEXT: fcvt z0.h, p0/m, z0.s365; VBITS_GE_256-NEXT: fcvt z1.h, p0/m, z1.s366; VBITS_GE_256-NEXT: st1h { z0.s }, p0, [x1, x8, lsl #1]367; VBITS_GE_256-NEXT: st1h { z1.s }, p0, [x1]368; VBITS_GE_256-NEXT: ret369;370; VBITS_GE_512-LABEL: fcvt_v16f32_v16f16:371; VBITS_GE_512: // %bb.0:372; VBITS_GE_512-NEXT: ptrue p0.s, vl16373; VBITS_GE_512-NEXT: ld1w { z0.s }, p0/z, [x0]374; VBITS_GE_512-NEXT: fcvt z0.h, p0/m, z0.s375; VBITS_GE_512-NEXT: st1h { z0.s }, p0, [x1]376; VBITS_GE_512-NEXT: ret377 %op1 = load <16 x float>, ptr %a378 %res = fptrunc <16 x float> %op1 to <16 x half>379 store <16 x half> %res, ptr %b380 ret void381}382 383define void @fcvt_v32f32_v32f16(ptr %a, ptr %b) vscale_range(8,0) #0 {384; CHECK-LABEL: fcvt_v32f32_v32f16:385; CHECK: // %bb.0:386; CHECK-NEXT: ptrue p0.s, vl32387; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]388; CHECK-NEXT: fcvt z0.h, p0/m, z0.s389; CHECK-NEXT: st1h { z0.s }, p0, [x1]390; CHECK-NEXT: ret391 %op1 = load <32 x float>, ptr %a392 %res = fptrunc <32 x float> %op1 to <32 x half>393 store <32 x half> %res, ptr %b394 ret void395}396 397define void @fcvt_v64f32_v64f16(ptr %a, ptr %b) vscale_range(16,0) #0 {398; CHECK-LABEL: fcvt_v64f32_v64f16:399; CHECK: // %bb.0:400; CHECK-NEXT: ptrue p0.s, vl64401; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]402; CHECK-NEXT: fcvt z0.h, p0/m, z0.s403; CHECK-NEXT: st1h { z0.s }, p0, [x1]404; CHECK-NEXT: ret405 %op1 = load <64 x float>, ptr %a406 %res = fptrunc <64 x float> %op1 to <64 x half>407 store <64 x half> %res, ptr %b408 ret void409}410 411;412; FCVT D -> H413;414 415; Don't use SVE for 64-bit vectors.416define void @fcvt_v1f64_v1f16(ptr %a, ptr %b) vscale_range(2,0) #0 {417; CHECK-LABEL: fcvt_v1f64_v1f16:418; CHECK: // %bb.0:419; CHECK-NEXT: ldr d0, [x0]420; CHECK-NEXT: fcvt h0, d0421; CHECK-NEXT: str h0, [x1]422; CHECK-NEXT: ret423 %op1 = load <1 x double>, ptr %a424 %res = fptrunc <1 x double> %op1 to <1 x half>425 store <1 x half> %res, ptr %b426 ret void427}428 429; v2f16 is not legal for NEON, so use SVE430define void @fcvt_v2f64_v2f16(ptr %a, ptr %b) vscale_range(2,0) #0 {431; CHECK-LABEL: fcvt_v2f64_v2f16:432; CHECK: // %bb.0:433; CHECK-NEXT: ptrue p0.d434; CHECK-NEXT: ldr q0, [x0]435; CHECK-NEXT: fcvt z0.h, p0/m, z0.d436; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s437; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h438; CHECK-NEXT: str s0, [x1]439; CHECK-NEXT: ret440 %op1 = load <2 x double>, ptr %a441 %res = fptrunc <2 x double> %op1 to <2 x half>442 store <2 x half> %res, ptr %b443 ret void444}445 446define void @fcvt_v4f64_v4f16(ptr %a, ptr %b) vscale_range(2,0) #0 {447; CHECK-LABEL: fcvt_v4f64_v4f16:448; CHECK: // %bb.0:449; CHECK-NEXT: ptrue p0.d, vl4450; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]451; CHECK-NEXT: fcvt z0.h, p0/m, z0.d452; CHECK-NEXT: st1h { z0.d }, p0, [x1]453; CHECK-NEXT: ret454 %op1 = load <4 x double>, ptr %a455 %res = fptrunc <4 x double> %op1 to <4 x half>456 store <4 x half> %res, ptr %b457 ret void458}459 460define void @fcvt_v8f64_v8f16(ptr %a, ptr %b) #0 {461; VBITS_GE_256-LABEL: fcvt_v8f64_v8f16:462; VBITS_GE_256: // %bb.0:463; VBITS_GE_256-NEXT: ptrue p0.d, vl4464; VBITS_GE_256-NEXT: mov x8, #4 // =0x4465; VBITS_GE_256-NEXT: ld1d { z0.d }, p0/z, [x0, x8, lsl #3]466; VBITS_GE_256-NEXT: ld1d { z1.d }, p0/z, [x0]467; VBITS_GE_256-NEXT: ptrue p0.d468; VBITS_GE_256-NEXT: fcvt z0.h, p0/m, z0.d469; VBITS_GE_256-NEXT: fcvt z1.h, p0/m, z1.d470; VBITS_GE_256-NEXT: uzp1 z0.s, z0.s, z0.s471; VBITS_GE_256-NEXT: uzp1 z1.s, z1.s, z1.s472; VBITS_GE_256-NEXT: uzp1 z0.h, z0.h, z0.h473; VBITS_GE_256-NEXT: uzp1 z1.h, z1.h, z1.h474; VBITS_GE_256-NEXT: mov v1.d[1], v0.d[0]475; VBITS_GE_256-NEXT: str q1, [x1]476; VBITS_GE_256-NEXT: ret477;478; VBITS_GE_512-LABEL: fcvt_v8f64_v8f16:479; VBITS_GE_512: // %bb.0:480; VBITS_GE_512-NEXT: ptrue p0.d, vl8481; VBITS_GE_512-NEXT: ld1d { z0.d }, p0/z, [x0]482; VBITS_GE_512-NEXT: fcvt z0.h, p0/m, z0.d483; VBITS_GE_512-NEXT: st1h { z0.d }, p0, [x1]484; VBITS_GE_512-NEXT: ret485 %op1 = load <8 x double>, ptr %a486 %res = fptrunc <8 x double> %op1 to <8 x half>487 store <8 x half> %res, ptr %b488 ret void489}490 491define void @fcvt_v16f64_v16f16(ptr %a, ptr %b) vscale_range(8,0) #0 {492; CHECK-LABEL: fcvt_v16f64_v16f16:493; CHECK: // %bb.0:494; CHECK-NEXT: ptrue p0.d, vl16495; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]496; CHECK-NEXT: fcvt z0.h, p0/m, z0.d497; CHECK-NEXT: st1h { z0.d }, p0, [x1]498; CHECK-NEXT: ret499 %op1 = load <16 x double>, ptr %a500 %res = fptrunc <16 x double> %op1 to <16 x half>501 store <16 x half> %res, ptr %b502 ret void503}504 505define void @fcvt_v32f64_v32f16(ptr %a, ptr %b) vscale_range(16,0) #0 {506; CHECK-LABEL: fcvt_v32f64_v32f16:507; CHECK: // %bb.0:508; CHECK-NEXT: ptrue p0.d, vl32509; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]510; CHECK-NEXT: fcvt z0.h, p0/m, z0.d511; CHECK-NEXT: st1h { z0.d }, p0, [x1]512; CHECK-NEXT: ret513 %op1 = load <32 x double>, ptr %a514 %res = fptrunc <32 x double> %op1 to <32 x half>515 store <32 x half> %res, ptr %b516 ret void517}518 519;520; FCVT D -> S521;522 523; Don't use SVE for 64-bit vectors.524define void @fcvt_v1f64_v1f32(<1 x double> %op1, ptr %b) vscale_range(2,0) #0 {525; CHECK-LABEL: fcvt_v1f64_v1f32:526; CHECK: // %bb.0:527; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0528; CHECK-NEXT: fcvtn v0.2s, v0.2d529; CHECK-NEXT: str s0, [x0]530; CHECK-NEXT: ret531 %res = fptrunc <1 x double> %op1 to <1 x float>532 store <1 x float> %res, ptr %b533 ret void534}535 536; Don't use SVE for 128-bit vectors.537define void @fcvt_v2f64_v2f32(<2 x double> %op1, ptr %b) vscale_range(2,0) #0 {538; CHECK-LABEL: fcvt_v2f64_v2f32:539; CHECK: // %bb.0:540; CHECK-NEXT: fcvtn v0.2s, v0.2d541; CHECK-NEXT: str d0, [x0]542; CHECK-NEXT: ret543 %res = fptrunc <2 x double> %op1 to <2 x float>544 store <2 x float> %res, ptr %b545 ret void546}547 548define void @fcvt_v4f64_v4f32(ptr %a, ptr %b) vscale_range(2,0) #0 {549; CHECK-LABEL: fcvt_v4f64_v4f32:550; CHECK: // %bb.0:551; CHECK-NEXT: ptrue p0.d, vl4552; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]553; CHECK-NEXT: fcvt z0.s, p0/m, z0.d554; CHECK-NEXT: st1w { z0.d }, p0, [x1]555; CHECK-NEXT: ret556 %op1 = load <4 x double>, ptr %a557 %res = fptrunc <4 x double> %op1 to <4 x float>558 store <4 x float> %res, ptr %b559 ret void560}561 562define void @fcvt_v8f64_v8f32(ptr %a, ptr %b) #0 {563; VBITS_GE_256-LABEL: fcvt_v8f64_v8f32:564; VBITS_GE_256: // %bb.0:565; VBITS_GE_256-NEXT: ptrue p0.d, vl4566; VBITS_GE_256-NEXT: mov x8, #4 // =0x4567; VBITS_GE_256-NEXT: ld1d { z0.d }, p0/z, [x0, x8, lsl #3]568; VBITS_GE_256-NEXT: ld1d { z1.d }, p0/z, [x0]569; VBITS_GE_256-NEXT: fcvt z0.s, p0/m, z0.d570; VBITS_GE_256-NEXT: fcvt z1.s, p0/m, z1.d571; VBITS_GE_256-NEXT: st1w { z0.d }, p0, [x1, x8, lsl #2]572; VBITS_GE_256-NEXT: st1w { z1.d }, p0, [x1]573; VBITS_GE_256-NEXT: ret574;575; VBITS_GE_512-LABEL: fcvt_v8f64_v8f32:576; VBITS_GE_512: // %bb.0:577; VBITS_GE_512-NEXT: ptrue p0.d, vl8578; VBITS_GE_512-NEXT: ld1d { z0.d }, p0/z, [x0]579; VBITS_GE_512-NEXT: fcvt z0.s, p0/m, z0.d580; VBITS_GE_512-NEXT: st1w { z0.d }, p0, [x1]581; VBITS_GE_512-NEXT: ret582 %op1 = load <8 x double>, ptr %a583 %res = fptrunc <8 x double> %op1 to <8 x float>584 store <8 x float> %res, ptr %b585 ret void586}587 588define void @fcvt_v16f64_v16f32(ptr %a, ptr %b) vscale_range(8,0) #0 {589; CHECK-LABEL: fcvt_v16f64_v16f32:590; CHECK: // %bb.0:591; CHECK-NEXT: ptrue p0.d, vl16592; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]593; CHECK-NEXT: fcvt z0.s, p0/m, z0.d594; CHECK-NEXT: st1w { z0.d }, p0, [x1]595; CHECK-NEXT: ret596 %op1 = load <16 x double>, ptr %a597 %res = fptrunc <16 x double> %op1 to <16 x float>598 store <16 x float> %res, ptr %b599 ret void600}601 602define void @fcvt_v32f64_v32f32(ptr %a, ptr %b) vscale_range(16,0) #0 {603; CHECK-LABEL: fcvt_v32f64_v32f32:604; CHECK: // %bb.0:605; CHECK-NEXT: ptrue p0.d, vl32606; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]607; CHECK-NEXT: fcvt z0.s, p0/m, z0.d608; CHECK-NEXT: st1w { z0.d }, p0, [x1]609; CHECK-NEXT: ret610 %op1 = load <32 x double>, ptr %a611 %res = fptrunc <32 x double> %op1 to <32 x float>612 store <32 x float> %res, ptr %b613 ret void614}615 616attributes #0 = { "target-features"="+sve" }617