395 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve,+bf16 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-LE3; RUN: llc -mtriple=aarch64_be-linux-gnu -mattr=+sve,+bf16 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-BE4 5; LD1B6 7define <vscale x 16 x i8> @ld1_nxv16i8(ptr %addr, i64 %off) {8; CHECK-LABEL: ld1_nxv16i8:9; CHECK: // %bb.0:10; CHECK-NEXT: ptrue p0.b11; CHECK-NEXT: ld1b { z0.b }, p0/z, [x0, x1]12; CHECK-NEXT: ret13 %ptr = getelementptr inbounds i8, ptr %addr, i64 %off14 %val = load volatile <vscale x 16 x i8>, ptr %ptr15 ret <vscale x 16 x i8> %val16}17 18define <vscale x 8 x i16> @ld1_nxv16i8_bitcast_to_i16(ptr %addr, i64 %off) {19; CHECK-LE-LABEL: ld1_nxv16i8_bitcast_to_i16:20; CHECK-LE: // %bb.0:21; CHECK-LE-NEXT: ptrue p0.b22; CHECK-LE-NEXT: ld1b { z0.b }, p0/z, [x0, x1]23; CHECK-LE-NEXT: ret24;25; CHECK-BE-LABEL: ld1_nxv16i8_bitcast_to_i16:26; CHECK-BE: // %bb.0:27; CHECK-BE-NEXT: ptrue p0.h28; CHECK-BE-NEXT: add x8, x0, x129; CHECK-BE-NEXT: ld1h { z0.h }, p0/z, [x8]30; CHECK-BE-NEXT: ret31 %ptr = getelementptr inbounds i8, ptr %addr, i64 %off32 %val = load volatile <vscale x 8 x i16>, ptr %ptr33 ret <vscale x 8 x i16> %val34}35 36define <vscale x 4 x i32> @ld1_nxv16i8_bitcast_to_i32(ptr %addr, i64 %off) {37; CHECK-LE-LABEL: ld1_nxv16i8_bitcast_to_i32:38; CHECK-LE: // %bb.0:39; CHECK-LE-NEXT: ptrue p0.b40; CHECK-LE-NEXT: ld1b { z0.b }, p0/z, [x0, x1]41; CHECK-LE-NEXT: ret42;43; CHECK-BE-LABEL: ld1_nxv16i8_bitcast_to_i32:44; CHECK-BE: // %bb.0:45; CHECK-BE-NEXT: ptrue p0.s46; CHECK-BE-NEXT: add x8, x0, x147; CHECK-BE-NEXT: ld1w { z0.s }, p0/z, [x8]48; CHECK-BE-NEXT: ret49 %ptr = getelementptr inbounds i8, ptr %addr, i64 %off50 %val = load volatile <vscale x 4 x i32>, ptr %ptr51 ret <vscale x 4 x i32> %val52}53 54define <vscale x 2 x i64> @ld1_nxv16i8_bitcast_to_i64(ptr %addr, i64 %off) {55; CHECK-LE-LABEL: ld1_nxv16i8_bitcast_to_i64:56; CHECK-LE: // %bb.0:57; CHECK-LE-NEXT: ptrue p0.b58; CHECK-LE-NEXT: ld1b { z0.b }, p0/z, [x0, x1]59; CHECK-LE-NEXT: ret60;61; CHECK-BE-LABEL: ld1_nxv16i8_bitcast_to_i64:62; CHECK-BE: // %bb.0:63; CHECK-BE-NEXT: ptrue p0.d64; CHECK-BE-NEXT: add x8, x0, x165; CHECK-BE-NEXT: ld1d { z0.d }, p0/z, [x8]66; CHECK-BE-NEXT: ret67 %ptr = getelementptr inbounds i8, ptr %addr, i64 %off68 %val = load volatile <vscale x 2 x i64>, ptr %ptr69 ret <vscale x 2 x i64> %val70}71 72define <vscale x 8 x i16> @ld1_nxv8i16_zext8(ptr %addr, i64 %off) {73; CHECK-LABEL: ld1_nxv8i16_zext8:74; CHECK: // %bb.0:75; CHECK-NEXT: ptrue p0.h76; CHECK-NEXT: ld1b { z0.h }, p0/z, [x0, x1]77; CHECK-NEXT: ret78 %ptr = getelementptr inbounds i8, ptr %addr, i64 %off79 %val = load volatile <vscale x 8 x i8>, ptr %ptr80 %zext = zext <vscale x 8 x i8> %val to <vscale x 8 x i16>81 ret <vscale x 8 x i16> %zext82}83 84define <vscale x 4 x i32> @ld1_nxv4i32_zext8(ptr %addr, i64 %off) {85; CHECK-LABEL: ld1_nxv4i32_zext8:86; CHECK: // %bb.0:87; CHECK-NEXT: ptrue p0.s88; CHECK-NEXT: ld1b { z0.s }, p0/z, [x0, x1]89; CHECK-NEXT: ret90 %ptr = getelementptr inbounds i8, ptr %addr, i64 %off91 %val = load volatile <vscale x 4 x i8>, ptr %ptr92 %zext = zext <vscale x 4 x i8> %val to <vscale x 4 x i32>93 ret <vscale x 4 x i32> %zext94}95 96define <vscale x 2 x i64> @ld1_nxv2i64_zext8(ptr %addr, i64 %off) {97; CHECK-LABEL: ld1_nxv2i64_zext8:98; CHECK: // %bb.0:99; CHECK-NEXT: ptrue p0.d100; CHECK-NEXT: ld1b { z0.d }, p0/z, [x0, x1]101; CHECK-NEXT: ret102 %ptr = getelementptr inbounds i8, ptr %addr, i64 %off103 %val = load volatile <vscale x 2 x i8>, ptr %ptr104 %zext = zext <vscale x 2 x i8> %val to <vscale x 2 x i64>105 ret <vscale x 2 x i64> %zext106}107 108define <vscale x 8 x i16> @ld1_nxv8i16_sext8(ptr %addr, i64 %off) {109; CHECK-LABEL: ld1_nxv8i16_sext8:110; CHECK: // %bb.0:111; CHECK-NEXT: ptrue p0.h112; CHECK-NEXT: ld1sb { z0.h }, p0/z, [x0, x1]113; CHECK-NEXT: ret114 %ptr = getelementptr inbounds i8, ptr %addr, i64 %off115 %val = load volatile <vscale x 8 x i8>, ptr %ptr116 %sext = sext <vscale x 8 x i8> %val to <vscale x 8 x i16>117 ret <vscale x 8 x i16> %sext118}119 120define <vscale x 4 x i32> @ld1_nxv4i32_sext8(ptr %addr, i64 %off) {121; CHECK-LABEL: ld1_nxv4i32_sext8:122; CHECK: // %bb.0:123; CHECK-NEXT: ptrue p0.s124; CHECK-NEXT: ld1sb { z0.s }, p0/z, [x0, x1]125; CHECK-NEXT: ret126 %ptr = getelementptr inbounds i8, ptr %addr, i64 %off127 %val = load volatile <vscale x 4 x i8>, ptr %ptr128 %sext = sext <vscale x 4 x i8> %val to <vscale x 4 x i32>129 ret <vscale x 4 x i32> %sext130}131 132define <vscale x 2 x i64> @ld1_nxv2i64_sext8(ptr %addr, i64 %off) {133; CHECK-LABEL: ld1_nxv2i64_sext8:134; CHECK: // %bb.0:135; CHECK-NEXT: ptrue p0.d136; CHECK-NEXT: ld1sb { z0.d }, p0/z, [x0, x1]137; CHECK-NEXT: ret138 %ptr = getelementptr inbounds i8, ptr %addr, i64 %off139 %val = load volatile <vscale x 2 x i8>, ptr %ptr140 %sext = sext <vscale x 2 x i8> %val to <vscale x 2 x i64>141 ret <vscale x 2 x i64> %sext142}143 144; LD1H145 146define <vscale x 8 x i16> @ld1_nxv8i16(ptr %addr, i64 %off) {147; CHECK-LABEL: ld1_nxv8i16:148; CHECK: // %bb.0:149; CHECK-NEXT: ptrue p0.h150; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0, x1, lsl #1]151; CHECK-NEXT: ret152 %ptr = getelementptr inbounds i16, ptr %addr, i64 %off153 %val = load volatile <vscale x 8 x i16>, ptr %ptr154 ret <vscale x 8 x i16> %val155}156 157define <vscale x 4 x i32> @ld1_nxv4i32_zext16(ptr %addr, i64 %off) {158; CHECK-LABEL: ld1_nxv4i32_zext16:159; CHECK: // %bb.0:160; CHECK-NEXT: ptrue p0.s161; CHECK-NEXT: ld1h { z0.s }, p0/z, [x0, x1, lsl #1]162; CHECK-NEXT: ret163 %ptr = getelementptr inbounds i16, ptr %addr, i64 %off164 %val = load volatile <vscale x 4 x i16>, ptr %ptr165 %zext = zext <vscale x 4 x i16> %val to <vscale x 4 x i32>166 ret <vscale x 4 x i32> %zext167}168 169define <vscale x 2 x i64> @ld1_nxv2i64_zext16(ptr %addr, i64 %off) {170; CHECK-LABEL: ld1_nxv2i64_zext16:171; CHECK: // %bb.0:172; CHECK-NEXT: ptrue p0.d173; CHECK-NEXT: ld1h { z0.d }, p0/z, [x0, x1, lsl #1]174; CHECK-NEXT: ret175 %ptr = getelementptr inbounds i16, ptr %addr, i64 %off176 %val = load volatile <vscale x 2 x i16>, ptr %ptr177 %zext = zext <vscale x 2 x i16> %val to <vscale x 2 x i64>178 ret <vscale x 2 x i64> %zext179}180 181define <vscale x 4 x i32> @ld1_nxv4i32_sext16(ptr %addr, i64 %off) {182; CHECK-LABEL: ld1_nxv4i32_sext16:183; CHECK: // %bb.0:184; CHECK-NEXT: ptrue p0.s185; CHECK-NEXT: ld1sh { z0.s }, p0/z, [x0, x1, lsl #1]186; CHECK-NEXT: ret187 %ptr = getelementptr inbounds i16, ptr %addr, i64 %off188 %val = load volatile <vscale x 4 x i16>, ptr %ptr189 %sext = sext <vscale x 4 x i16> %val to <vscale x 4 x i32>190 ret <vscale x 4 x i32> %sext191}192 193define <vscale x 2 x i64> @ld1_nxv2i64_sext16(ptr %addr, i64 %off) {194; CHECK-LABEL: ld1_nxv2i64_sext16:195; CHECK: // %bb.0:196; CHECK-NEXT: ptrue p0.d197; CHECK-NEXT: ld1sh { z0.d }, p0/z, [x0, x1, lsl #1]198; CHECK-NEXT: ret199 %ptr = getelementptr inbounds i16, ptr %addr, i64 %off200 %val = load volatile <vscale x 2 x i16>, ptr %ptr201 %sext = sext <vscale x 2 x i16> %val to <vscale x 2 x i64>202 ret <vscale x 2 x i64> %sext203}204 205define <vscale x 8 x half> @ld1_nxv8f16(ptr %addr, i64 %off) {206; CHECK-LABEL: ld1_nxv8f16:207; CHECK: // %bb.0:208; CHECK-NEXT: ptrue p0.h209; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0, x1, lsl #1]210; CHECK-NEXT: ret211 %ptr = getelementptr inbounds half, ptr %addr, i64 %off212 %val = load volatile <vscale x 8 x half>, ptr %ptr213 ret <vscale x 8 x half> %val214}215 216define <vscale x 8 x bfloat> @ld1_nxv8bf16(ptr %addr, i64 %off) {217; CHECK-LABEL: ld1_nxv8bf16:218; CHECK: // %bb.0:219; CHECK-NEXT: ptrue p0.h220; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0, x1, lsl #1]221; CHECK-NEXT: ret222 %ptr = getelementptr inbounds bfloat, ptr %addr, i64 %off223 %val = load volatile <vscale x 8 x bfloat>, ptr %ptr224 ret <vscale x 8 x bfloat> %val225}226 227define <vscale x 4 x half> @ld1_nxv4f16(ptr %addr, i64 %off) {228; CHECK-LABEL: ld1_nxv4f16:229; CHECK: // %bb.0:230; CHECK-NEXT: ptrue p0.s231; CHECK-NEXT: ld1h { z0.s }, p0/z, [x0, x1, lsl #1]232; CHECK-NEXT: ret233 %ptr = getelementptr inbounds half, ptr %addr, i64 %off234 %val = load volatile <vscale x 4 x half>, ptr %ptr235 ret <vscale x 4 x half> %val236}237 238define <vscale x 4 x bfloat> @ld1_nxv4bf16(ptr %addr, i64 %off) {239; CHECK-LABEL: ld1_nxv4bf16:240; CHECK: // %bb.0:241; CHECK-NEXT: ptrue p0.s242; CHECK-NEXT: ld1h { z0.s }, p0/z, [x0, x1, lsl #1]243; CHECK-NEXT: ret244 %ptr = getelementptr inbounds bfloat, ptr %addr, i64 %off245 %val = load volatile <vscale x 4 x bfloat>, ptr %ptr246 ret <vscale x 4 x bfloat> %val247}248 249define <vscale x 2 x half> @ld1_nxv2f16(ptr %addr, i64 %off) {250; CHECK-LABEL: ld1_nxv2f16:251; CHECK: // %bb.0:252; CHECK-NEXT: ptrue p0.d253; CHECK-NEXT: ld1h { z0.d }, p0/z, [x0, x1, lsl #1]254; CHECK-NEXT: ret255 %ptr = getelementptr inbounds half, ptr %addr, i64 %off256 %val = load volatile <vscale x 2 x half>, ptr %ptr257 ret <vscale x 2 x half> %val258}259 260define <vscale x 2 x bfloat> @ld1_nxv2bf16(ptr %addr, i64 %off) {261; CHECK-LABEL: ld1_nxv2bf16:262; CHECK: // %bb.0:263; CHECK-NEXT: ptrue p0.d264; CHECK-NEXT: ld1h { z0.d }, p0/z, [x0, x1, lsl #1]265; CHECK-NEXT: ret266 %ptr = getelementptr inbounds bfloat, ptr %addr, i64 %off267 %val = load volatile <vscale x 2 x bfloat>, ptr %ptr268 ret <vscale x 2 x bfloat> %val269}270 271; Ensure we don't lose the free shift when using indexed addressing.272define <vscale x 2 x bfloat> @ld1_nxv2bf16_double_shift(ptr %addr, i64 %off) {273; CHECK-LABEL: ld1_nxv2bf16_double_shift:274; CHECK: // %bb.0:275; CHECK-NEXT: ptrue p0.d276; CHECK-NEXT: lsr x8, x1, #6277; CHECK-NEXT: ld1h { z0.d }, p0/z, [x0, x8, lsl #1]278; CHECK-NEXT: ret279 %off2 = lshr i64 %off, 6280 %ptr = getelementptr inbounds bfloat, ptr %addr, i64 %off2281 %val = load volatile <vscale x 2 x bfloat>, ptr %ptr282 ret <vscale x 2 x bfloat> %val283}284 285; LD1W286 287define <vscale x 4 x i32> @ld1_nxv4i32(ptr %addr, i64 %off) {288; CHECK-LABEL: ld1_nxv4i32:289; CHECK: // %bb.0:290; CHECK-NEXT: ptrue p0.s291; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0, x1, lsl #2]292; CHECK-NEXT: ret293 %ptr = getelementptr inbounds i32, ptr %addr, i64 %off294 %val = load volatile <vscale x 4 x i32>, ptr %ptr295 ret <vscale x 4 x i32> %val296}297 298define <vscale x 2 x i64> @ld1_nxv2i64_zext32(ptr %addr, i64 %off) {299; CHECK-LABEL: ld1_nxv2i64_zext32:300; CHECK: // %bb.0:301; CHECK-NEXT: ptrue p0.d302; CHECK-NEXT: ld1w { z0.d }, p0/z, [x0, x1, lsl #2]303; CHECK-NEXT: ret304 %ptr = getelementptr inbounds i32, ptr %addr, i64 %off305 %val = load volatile <vscale x 2 x i32>, ptr %ptr306 %zext = zext <vscale x 2 x i32> %val to <vscale x 2 x i64>307 ret <vscale x 2 x i64> %zext308}309 310define <vscale x 2 x i64> @ld1_nxv2i64_sext32(ptr %addr, i64 %off) {311; CHECK-LABEL: ld1_nxv2i64_sext32:312; CHECK: // %bb.0:313; CHECK-NEXT: ptrue p0.d314; CHECK-NEXT: ld1sw { z0.d }, p0/z, [x0, x1, lsl #2]315; CHECK-NEXT: ret316 %ptr = getelementptr inbounds i32, ptr %addr, i64 %off317 %val = load volatile <vscale x 2 x i32>, ptr %ptr318 %sext = sext <vscale x 2 x i32> %val to <vscale x 2 x i64>319 ret <vscale x 2 x i64> %sext320}321 322define <vscale x 4 x float> @ld1_nxv4f32(ptr %addr, i64 %off) {323; CHECK-LABEL: ld1_nxv4f32:324; CHECK: // %bb.0:325; CHECK-NEXT: ptrue p0.s326; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0, x1, lsl #2]327; CHECK-NEXT: ret328 %ptr = getelementptr inbounds float, ptr %addr, i64 %off329 %val = load volatile <vscale x 4 x float>, ptr %ptr330 ret <vscale x 4 x float> %val331}332 333define <vscale x 2 x float> @ld1_nxv2f32(ptr %addr, i64 %off) {334; CHECK-LABEL: ld1_nxv2f32:335; CHECK: // %bb.0:336; CHECK-NEXT: ptrue p0.d337; CHECK-NEXT: ld1w { z0.d }, p0/z, [x0, x1, lsl #2]338; CHECK-NEXT: ret339 %ptr = getelementptr inbounds float, ptr %addr, i64 %off340 %val = load volatile <vscale x 2 x float>, ptr %ptr341 ret <vscale x 2 x float> %val342}343 344; Ensure we don't lose the free shift when using indexed addressing.345define <vscale x 2 x float> @ld1_nxv2f32_double_shift(ptr %addr, i64 %off) {346; CHECK-LABEL: ld1_nxv2f32_double_shift:347; CHECK: // %bb.0:348; CHECK-NEXT: ptrue p0.d349; CHECK-NEXT: lsr x8, x1, #6350; CHECK-NEXT: ld1w { z0.d }, p0/z, [x0, x8, lsl #2]351; CHECK-NEXT: ret352 %off2 = lshr i64 %off, 6353 %ptr = getelementptr inbounds float, ptr %addr, i64 %off2354 %val = load volatile <vscale x 2 x float>, ptr %ptr355 ret <vscale x 2 x float> %val356}357 358; LD1D359 360define <vscale x 2 x i64> @ld1_nxv2i64(ptr %addr, i64 %off) {361; CHECK-LABEL: ld1_nxv2i64:362; CHECK: // %bb.0:363; CHECK-NEXT: ptrue p0.d364; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0, x1, lsl #3]365; CHECK-NEXT: ret366 %ptr = getelementptr inbounds i64, ptr %addr, i64 %off367 %val = load volatile <vscale x 2 x i64>, ptr %ptr368 ret <vscale x 2 x i64> %val369}370 371define <vscale x 2 x double> @ld1_nxv2f64(ptr %addr, i64 %off) {372; CHECK-LABEL: ld1_nxv2f64:373; CHECK: // %bb.0:374; CHECK-NEXT: ptrue p0.d375; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0, x1, lsl #3]376; CHECK-NEXT: ret377 %ptr = getelementptr inbounds double, ptr %addr, i64 %off378 %val = load volatile <vscale x 2 x double>, ptr %ptr379 ret <vscale x 2 x double> %val380}381 382; Ensure we don't lose the free shift when using indexed addressing.383define <vscale x 2 x double> @ld1_nxv2f64_double_shift(ptr %addr, i64 %off) {384; CHECK-LABEL: ld1_nxv2f64_double_shift:385; CHECK: // %bb.0:386; CHECK-NEXT: ptrue p0.d387; CHECK-NEXT: lsr x8, x1, #6388; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0, x8, lsl #3]389; CHECK-NEXT: ret390 %off2 = lshr i64 %off, 6391 %ptr = getelementptr inbounds double, ptr %addr, i64 %off2392 %val = load volatile <vscale x 2 x double>, ptr %ptr393 ret <vscale x 2 x double> %val394}395