900 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 42; RUN: llc -mtriple=arm64-apple-macosx -o - %s | FileCheck %s3; RUN: llc -mtriple=aarch64_be -o - %s | FileCheck --check-prefix BE %s4 5define <16 x i8> @load_v3i8(ptr %src) {6; CHECK-LABEL: load_v3i8:7; CHECK: ; %bb.0:8; CHECK-NEXT: ldrb w8, [x0, #2]9; CHECK-NEXT: ldrh w9, [x0]10; CHECK-NEXT: orr w8, w9, w8, lsl #1611; CHECK-NEXT: fmov s0, w812; CHECK-NEXT: ret13;14; BE-LABEL: load_v3i8:15; BE: // %bb.0:16; BE-NEXT: sub sp, sp, #1617; BE-NEXT: .cfi_def_cfa_offset 1618; BE-NEXT: ldrh w8, [x0]19; BE-NEXT: strh w8, [sp, #12]20; BE-NEXT: ldr s0, [sp, #12]21; BE-NEXT: rev32 v0.8b, v0.8b22; BE-NEXT: ushll v0.8h, v0.8b, #023; BE-NEXT: umov w8, v0.h[0]24; BE-NEXT: umov w9, v0.h[1]25; BE-NEXT: fmov s0, w826; BE-NEXT: add x8, x0, #227; BE-NEXT: mov v0.b[1], w928; BE-NEXT: ld1 { v0.b }[2], [x8]29; BE-NEXT: rev64 v0.16b, v0.16b30; BE-NEXT: ext v0.16b, v0.16b, v0.16b, #831; BE-NEXT: add sp, sp, #1632; BE-NEXT: ret33 %l = load <3 x i8>, ptr %src, align 134 %s = shufflevector <3 x i8> poison, <3 x i8> %l, <16 x i32> <i32 3, i32 4, i32 5, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>35 ret <16 x i8> %s36}37 38define <4 x i32> @load_v3i8_to_4xi32(ptr %src) {39; CHECK-LABEL: load_v3i8_to_4xi32:40; CHECK: ; %bb.0:41; CHECK-NEXT: ldrb w8, [x0, #2]42; CHECK-NEXT: ldrh w9, [x0]43; CHECK-NEXT: movi.2d v1, #0x0000ff000000ff44; CHECK-NEXT: orr w8, w9, w8, lsl #1645; CHECK-NEXT: fmov s0, w846; CHECK-NEXT: zip1.8b v0, v0, v047; CHECK-NEXT: ushll.4s v0, v0, #048; CHECK-NEXT: and.16b v0, v0, v149; CHECK-NEXT: ret50;51; BE-LABEL: load_v3i8_to_4xi32:52; BE: // %bb.0:53; BE-NEXT: sub sp, sp, #1654; BE-NEXT: .cfi_def_cfa_offset 1655; BE-NEXT: ldrh w8, [x0]56; BE-NEXT: movi v1.2d, #0x0000ff000000ff57; BE-NEXT: strh w8, [sp, #12]58; BE-NEXT: ldr s0, [sp, #12]59; BE-NEXT: ldrsb w8, [x0, #2]60; BE-NEXT: rev32 v0.8b, v0.8b61; BE-NEXT: ushll v0.8h, v0.8b, #062; BE-NEXT: mov v0.h[1], v0.h[1]63; BE-NEXT: mov v0.h[2], w864; BE-NEXT: ushll v0.4s, v0.4h, #065; BE-NEXT: and v0.16b, v0.16b, v1.16b66; BE-NEXT: rev64 v0.4s, v0.4s67; BE-NEXT: ext v0.16b, v0.16b, v0.16b, #868; BE-NEXT: add sp, sp, #1669; BE-NEXT: ret70 %l = load <3 x i8>, ptr %src, align 171 %s = shufflevector <3 x i8> poison, <3 x i8> %l, <4 x i32> <i32 3, i32 4, i32 5, i32 undef>72 %e = zext <4 x i8> %s to <4 x i32>73 ret <4 x i32> %e74}75 76define <4 x i32> @load_v3i8_to_4xi32_align_2(ptr %src) {77; CHECK-LABEL: load_v3i8_to_4xi32_align_2:78; CHECK: ; %bb.0:79; CHECK-NEXT: ldrb w8, [x0, #2]80; CHECK-NEXT: ldrh w9, [x0]81; CHECK-NEXT: movi.2d v1, #0x0000ff000000ff82; CHECK-NEXT: orr w8, w9, w8, lsl #1683; CHECK-NEXT: fmov s0, w884; CHECK-NEXT: zip1.8b v0, v0, v085; CHECK-NEXT: ushll.4s v0, v0, #086; CHECK-NEXT: and.16b v0, v0, v187; CHECK-NEXT: ret88;89; BE-LABEL: load_v3i8_to_4xi32_align_2:90; BE: // %bb.0:91; BE-NEXT: sub sp, sp, #1692; BE-NEXT: .cfi_def_cfa_offset 1693; BE-NEXT: ldrh w8, [x0]94; BE-NEXT: movi v1.2d, #0x0000ff000000ff95; BE-NEXT: strh w8, [sp, #12]96; BE-NEXT: ldr s0, [sp, #12]97; BE-NEXT: ldrsb w8, [x0, #2]98; BE-NEXT: rev32 v0.8b, v0.8b99; BE-NEXT: ushll v0.8h, v0.8b, #0100; BE-NEXT: mov v0.h[1], v0.h[1]101; BE-NEXT: mov v0.h[2], w8102; BE-NEXT: ushll v0.4s, v0.4h, #0103; BE-NEXT: and v0.16b, v0.16b, v1.16b104; BE-NEXT: rev64 v0.4s, v0.4s105; BE-NEXT: ext v0.16b, v0.16b, v0.16b, #8106; BE-NEXT: add sp, sp, #16107; BE-NEXT: ret108 %l = load <3 x i8>, ptr %src, align 2109 %s = shufflevector <3 x i8> poison, <3 x i8> %l, <4 x i32> <i32 3, i32 4, i32 5, i32 undef>110 %e = zext <4 x i8> %s to <4 x i32>111 ret <4 x i32> %e112}113 114define <4 x i32> @load_v3i8_to_4xi32_align_4(ptr %src) {115; CHECK-LABEL: load_v3i8_to_4xi32_align_4:116; CHECK: ; %bb.0:117; CHECK-NEXT: ldr s0, [x0]118; CHECK-NEXT: movi.2d v1, #0x0000ff000000ff119; CHECK-NEXT: zip1.8b v0, v0, v0120; CHECK-NEXT: ushll.4s v0, v0, #0121; CHECK-NEXT: and.16b v0, v0, v1122; CHECK-NEXT: ret123;124; BE-LABEL: load_v3i8_to_4xi32_align_4:125; BE: // %bb.0:126; BE-NEXT: ldr s0, [x0]127; BE-NEXT: movi v1.2d, #0x0000ff000000ff128; BE-NEXT: rev32 v0.8b, v0.8b129; BE-NEXT: zip1 v0.8b, v0.8b, v0.8b130; BE-NEXT: ushll v0.4s, v0.4h, #0131; BE-NEXT: and v0.16b, v0.16b, v1.16b132; BE-NEXT: rev64 v0.4s, v0.4s133; BE-NEXT: ext v0.16b, v0.16b, v0.16b, #8134; BE-NEXT: ret135 %l = load <3 x i8>, ptr %src, align 4136 %s = shufflevector <3 x i8> poison, <3 x i8> %l, <4 x i32> <i32 3, i32 4, i32 5, i32 undef>137 %e = zext <4 x i8> %s to <4 x i32>138 ret <4 x i32> %e139}140 141define <4 x i32> @load_v3i8_to_4xi32_const_offset_1(ptr %src) {142; CHECK-LABEL: load_v3i8_to_4xi32_const_offset_1:143; CHECK: ; %bb.0:144; CHECK-NEXT: ldrb w8, [x0, #3]145; CHECK-NEXT: ldurh w9, [x0, #1]146; CHECK-NEXT: movi.2d v1, #0x0000ff000000ff147; CHECK-NEXT: orr w8, w9, w8, lsl #16148; CHECK-NEXT: fmov s0, w8149; CHECK-NEXT: zip1.8b v0, v0, v0150; CHECK-NEXT: ushll.4s v0, v0, #0151; CHECK-NEXT: and.16b v0, v0, v1152; CHECK-NEXT: ret153;154; BE-LABEL: load_v3i8_to_4xi32_const_offset_1:155; BE: // %bb.0:156; BE-NEXT: sub sp, sp, #16157; BE-NEXT: .cfi_def_cfa_offset 16158; BE-NEXT: ldurh w8, [x0, #1]159; BE-NEXT: movi v1.2d, #0x0000ff000000ff160; BE-NEXT: strh w8, [sp, #12]161; BE-NEXT: ldr s0, [sp, #12]162; BE-NEXT: ldrsb w8, [x0, #3]163; BE-NEXT: rev32 v0.8b, v0.8b164; BE-NEXT: ushll v0.8h, v0.8b, #0165; BE-NEXT: mov v0.h[1], v0.h[1]166; BE-NEXT: mov v0.h[2], w8167; BE-NEXT: ushll v0.4s, v0.4h, #0168; BE-NEXT: and v0.16b, v0.16b, v1.16b169; BE-NEXT: rev64 v0.4s, v0.4s170; BE-NEXT: ext v0.16b, v0.16b, v0.16b, #8171; BE-NEXT: add sp, sp, #16172; BE-NEXT: ret173 %src.1 = getelementptr inbounds i8, ptr %src, i64 1174 %l = load <3 x i8>, ptr %src.1, align 1175 %s = shufflevector <3 x i8> poison, <3 x i8> %l, <4 x i32> <i32 3, i32 4, i32 5, i32 undef>176 %e = zext <4 x i8> %s to <4 x i32>177 ret <4 x i32> %e178}179 180define <4 x i32> @load_v3i8_to_4xi32_const_offset_3(ptr %src) {181; CHECK-LABEL: load_v3i8_to_4xi32_const_offset_3:182; CHECK: ; %bb.0:183; CHECK-NEXT: ldrb w8, [x0, #5]184; CHECK-NEXT: ldurh w9, [x0, #3]185; CHECK-NEXT: movi.2d v1, #0x0000ff000000ff186; CHECK-NEXT: orr w8, w9, w8, lsl #16187; CHECK-NEXT: fmov s0, w8188; CHECK-NEXT: zip1.8b v0, v0, v0189; CHECK-NEXT: ushll.4s v0, v0, #0190; CHECK-NEXT: and.16b v0, v0, v1191; CHECK-NEXT: ret192;193; BE-LABEL: load_v3i8_to_4xi32_const_offset_3:194; BE: // %bb.0:195; BE-NEXT: sub sp, sp, #16196; BE-NEXT: .cfi_def_cfa_offset 16197; BE-NEXT: ldurh w8, [x0, #3]198; BE-NEXT: movi v1.2d, #0x0000ff000000ff199; BE-NEXT: strh w8, [sp, #12]200; BE-NEXT: ldr s0, [sp, #12]201; BE-NEXT: ldrsb w8, [x0, #5]202; BE-NEXT: rev32 v0.8b, v0.8b203; BE-NEXT: ushll v0.8h, v0.8b, #0204; BE-NEXT: mov v0.h[1], v0.h[1]205; BE-NEXT: mov v0.h[2], w8206; BE-NEXT: ushll v0.4s, v0.4h, #0207; BE-NEXT: and v0.16b, v0.16b, v1.16b208; BE-NEXT: rev64 v0.4s, v0.4s209; BE-NEXT: ext v0.16b, v0.16b, v0.16b, #8210; BE-NEXT: add sp, sp, #16211; BE-NEXT: ret212 %src.3 = getelementptr inbounds i8, ptr %src, i64 3213 %l = load <3 x i8>, ptr %src.3, align 1214 %s = shufflevector <3 x i8> poison, <3 x i8> %l, <4 x i32> <i32 3, i32 4, i32 5, i32 undef>215 %e = zext <4 x i8> %s to <4 x i32>216 ret <4 x i32> %e217}218 219define <4 x i32> @volatile_load_v3i8_to_4xi32(ptr %src) {220; CHECK-LABEL: volatile_load_v3i8_to_4xi32:221; CHECK: ; %bb.0:222; CHECK-NEXT: sub sp, sp, #16223; CHECK-NEXT: .cfi_def_cfa_offset 16224; CHECK-NEXT: ldrh w8, [x0]225; CHECK-NEXT: movi.2d v1, #0x0000ff000000ff226; CHECK-NEXT: strh w8, [sp, #12]227; CHECK-NEXT: ldr s0, [sp, #12]228; CHECK-NEXT: ldrsb w8, [x0, #2]229; CHECK-NEXT: ushll.8h v0, v0, #0230; CHECK-NEXT: mov.h v0[1], v0[1]231; CHECK-NEXT: mov.h v0[2], w8232; CHECK-NEXT: ushll.4s v0, v0, #0233; CHECK-NEXT: and.16b v0, v0, v1234; CHECK-NEXT: add sp, sp, #16235; CHECK-NEXT: ret236;237; BE-LABEL: volatile_load_v3i8_to_4xi32:238; BE: // %bb.0:239; BE-NEXT: sub sp, sp, #16240; BE-NEXT: .cfi_def_cfa_offset 16241; BE-NEXT: ldrh w8, [x0]242; BE-NEXT: movi v1.2d, #0x0000ff000000ff243; BE-NEXT: strh w8, [sp, #12]244; BE-NEXT: ldr s0, [sp, #12]245; BE-NEXT: ldrsb w8, [x0, #2]246; BE-NEXT: rev32 v0.8b, v0.8b247; BE-NEXT: ushll v0.8h, v0.8b, #0248; BE-NEXT: mov v0.h[1], v0.h[1]249; BE-NEXT: mov v0.h[2], w8250; BE-NEXT: ushll v0.4s, v0.4h, #0251; BE-NEXT: and v0.16b, v0.16b, v1.16b252; BE-NEXT: rev64 v0.4s, v0.4s253; BE-NEXT: ext v0.16b, v0.16b, v0.16b, #8254; BE-NEXT: add sp, sp, #16255; BE-NEXT: ret256 %l = load volatile <3 x i8>, ptr %src, align 1257 %s = shufflevector <3 x i8> poison, <3 x i8> %l, <4 x i32> <i32 3, i32 4, i32 5, i32 undef>258 %e = zext <4 x i8> %s to <4 x i32>259 ret <4 x i32> %e260}261 262define <3 x i32> @load_v3i32(ptr %src) {263; CHECK-LABEL: load_v3i32:264; CHECK: ; %bb.0:265; CHECK-NEXT: ldr d0, [x0]266; CHECK-NEXT: add x8, x0, #8267; CHECK-NEXT: ld1.s { v0 }[2], [x8]268; CHECK-NEXT: ret269;270; BE-LABEL: load_v3i32:271; BE: // %bb.0:272; BE-NEXT: ldr d0, [x0]273; BE-NEXT: add x8, x0, #8274; BE-NEXT: rev64 v0.4s, v0.4s275; BE-NEXT: ld1 { v0.s }[2], [x8]276; BE-NEXT: rev64 v0.4s, v0.4s277; BE-NEXT: ext v0.16b, v0.16b, v0.16b, #8278; BE-NEXT: ret279 %l = load <3 x i32>, ptr %src, align 1280 ret <3 x i32> %l281}282 283define <3 x i32> @load_v3i8_zext_to_3xi32(ptr %src) {284; CHECK-LABEL: load_v3i8_zext_to_3xi32:285; CHECK: ; %bb.0:286; CHECK-NEXT: ldrb w8, [x0, #2]287; CHECK-NEXT: ldrh w9, [x0]288; CHECK-NEXT: movi.2d v1, #0x0000ff000000ff289; CHECK-NEXT: orr w8, w9, w8, lsl #16290; CHECK-NEXT: fmov s0, w8291; CHECK-NEXT: zip1.8b v0, v0, v0292; CHECK-NEXT: ushll.4s v0, v0, #0293; CHECK-NEXT: and.16b v0, v0, v1294; CHECK-NEXT: ret295;296; BE-LABEL: load_v3i8_zext_to_3xi32:297; BE: // %bb.0:298; BE-NEXT: sub sp, sp, #16299; BE-NEXT: .cfi_def_cfa_offset 16300; BE-NEXT: ldrh w8, [x0]301; BE-NEXT: movi v1.2d, #0x0000ff000000ff302; BE-NEXT: strh w8, [sp, #12]303; BE-NEXT: add x8, x0, #2304; BE-NEXT: ldr s0, [sp, #12]305; BE-NEXT: rev32 v0.8b, v0.8b306; BE-NEXT: zip1 v0.8b, v0.8b, v0.8b307; BE-NEXT: ld1 { v0.b }[4], [x8]308; BE-NEXT: ushll v0.4s, v0.4h, #0309; BE-NEXT: and v0.16b, v0.16b, v1.16b310; BE-NEXT: rev64 v0.4s, v0.4s311; BE-NEXT: ext v0.16b, v0.16b, v0.16b, #8312; BE-NEXT: add sp, sp, #16313; BE-NEXT: ret314 %l = load <3 x i8>, ptr %src, align 1315 %e = zext <3 x i8> %l to <3 x i32>316 ret <3 x i32> %e317}318 319define <3 x i32> @load_v3i8_sext_to_3xi32(ptr %src) {320; CHECK-LABEL: load_v3i8_sext_to_3xi32:321; CHECK: ; %bb.0:322; CHECK-NEXT: ldrb w8, [x0, #2]323; CHECK-NEXT: ldrh w9, [x0]324; CHECK-NEXT: orr w8, w9, w8, lsl #16325; CHECK-NEXT: fmov s0, w8326; CHECK-NEXT: zip1.8b v0, v0, v0327; CHECK-NEXT: ushll.4s v0, v0, #0328; CHECK-NEXT: shl.4s v0, v0, #24329; CHECK-NEXT: sshr.4s v0, v0, #24330; CHECK-NEXT: ret331;332; BE-LABEL: load_v3i8_sext_to_3xi32:333; BE: // %bb.0:334; BE-NEXT: sub sp, sp, #16335; BE-NEXT: .cfi_def_cfa_offset 16336; BE-NEXT: ldrh w8, [x0]337; BE-NEXT: strh w8, [sp, #12]338; BE-NEXT: add x8, x0, #2339; BE-NEXT: ldr s0, [sp, #12]340; BE-NEXT: rev32 v0.8b, v0.8b341; BE-NEXT: ushll v0.8h, v0.8b, #0342; BE-NEXT: ld1 { v0.b }[4], [x8]343; BE-NEXT: ushll v0.4s, v0.4h, #0344; BE-NEXT: shl v0.4s, v0.4s, #24345; BE-NEXT: sshr v0.4s, v0.4s, #24346; BE-NEXT: rev64 v0.4s, v0.4s347; BE-NEXT: ext v0.16b, v0.16b, v0.16b, #8348; BE-NEXT: add sp, sp, #16349; BE-NEXT: ret350 %l = load <3 x i8>, ptr %src, align 1351 %e = sext <3 x i8> %l to <3 x i32>352 ret <3 x i32> %e353}354 355define void @store_trunc_from_64bits(ptr %src, ptr %dst) {356; CHECK-LABEL: store_trunc_from_64bits:357; CHECK: ; %bb.0: ; %entry358; CHECK-NEXT: add x8, x0, #4359; CHECK-NEXT: ld1r.4h { v0 }, [x8]360; CHECK-NEXT: ldr w8, [x0]361; CHECK-NEXT: lsr w9, w8, #16362; CHECK-NEXT: strb w8, [x1]363; CHECK-NEXT: mov b0, v0[4]364; CHECK-NEXT: strb w9, [x1, #1]365; CHECK-NEXT: stur b0, [x1, #2]366; CHECK-NEXT: ret367;368; BE-LABEL: store_trunc_from_64bits:369; BE: // %bb.0: // %entry370; BE-NEXT: sub sp, sp, #16371; BE-NEXT: .cfi_def_cfa_offset 16372; BE-NEXT: ldr s0, [x0]373; BE-NEXT: ldrh w8, [x0, #4]374; BE-NEXT: rev32 v0.4h, v0.4h375; BE-NEXT: strb w8, [x1, #2]376; BE-NEXT: mov v0.h[2], w8377; BE-NEXT: uzp1 v0.8b, v0.8b, v0.8b378; BE-NEXT: rev32 v0.16b, v0.16b379; BE-NEXT: rev32 v0.4h, v0.4h380; BE-NEXT: ushll v0.4s, v0.4h, #0381; BE-NEXT: str h0, [x1]382; BE-NEXT: add sp, sp, #16383; BE-NEXT: ret384entry:385 %l = load <3 x i16>, ptr %src, align 1386 %t = trunc <3 x i16> %l to <3 x i8>387 store <3 x i8> %t, ptr %dst, align 1388 ret void389}390 391define void @store_trunc_add_from_64bits(ptr %src, ptr %dst) {392; CHECK-LABEL: store_trunc_add_from_64bits:393; CHECK: ; %bb.0: ; %entry394; CHECK-NEXT: ldr s0, [x0]395; CHECK-NEXT: add x9, x0, #4396; CHECK-NEXT: Lloh0:397; CHECK-NEXT: adrp x8, lCPI11_0@PAGE398; CHECK-NEXT: Lloh1:399; CHECK-NEXT: ldr d1, [x8, lCPI11_0@PAGEOFF]400; CHECK-NEXT: ld1.h { v0 }[2], [x9]401; CHECK-NEXT: add.4h v0, v0, v1402; CHECK-NEXT: mov b1, v0[2]403; CHECK-NEXT: mov b2, v0[4]404; CHECK-NEXT: str b0, [x1]405; CHECK-NEXT: stur b1, [x1, #1]406; CHECK-NEXT: stur b2, [x1, #2]407; CHECK-NEXT: ret408; CHECK-NEXT: .loh AdrpLdr Lloh0, Lloh1409;410; BE-LABEL: store_trunc_add_from_64bits:411; BE: // %bb.0: // %entry412; BE-NEXT: sub sp, sp, #16413; BE-NEXT: .cfi_def_cfa_offset 16414; BE-NEXT: ldr s0, [x0]415; BE-NEXT: add x8, x0, #4416; BE-NEXT: rev32 v0.4h, v0.4h417; BE-NEXT: ld1 { v0.h }[2], [x8]418; BE-NEXT: adrp x8, .LCPI11_0419; BE-NEXT: add x8, x8, :lo12:.LCPI11_0420; BE-NEXT: ld1 { v1.4h }, [x8]421; BE-NEXT: add v0.4h, v0.4h, v1.4h422; BE-NEXT: uzp1 v1.8b, v0.8b, v0.8b423; BE-NEXT: mov h0, v0.h[2]424; BE-NEXT: rev32 v1.16b, v1.16b425; BE-NEXT: stur b0, [x1, #2]426; BE-NEXT: rev32 v1.4h, v1.4h427; BE-NEXT: ushll v1.4s, v1.4h, #0428; BE-NEXT: str h1, [x1]429; BE-NEXT: add sp, sp, #16430; BE-NEXT: ret431entry:432 %l = load <3 x i16>, ptr %src, align 1433 %a = add <3 x i16> %l, <i16 3, i16 4, i16 5>434 %t = trunc <3 x i16> %a to <3 x i8>435 store <3 x i8> %t, ptr %dst, align 1436 ret void437}438 439define void @load_ext_to_64bits(ptr %src, ptr %dst) {440; CHECK-LABEL: load_ext_to_64bits:441; CHECK: ; %bb.0: ; %entry442; CHECK-NEXT: ldrb w8, [x0, #2]443; CHECK-NEXT: ldrh w9, [x0]444; CHECK-NEXT: orr w8, w9, w8, lsl #16445; CHECK-NEXT: fmov s0, w8446; CHECK-NEXT: zip1.8b v0, v0, v0447; CHECK-NEXT: bic.4h v0, #255, lsl #8448; CHECK-NEXT: mov h1, v0[2]449; CHECK-NEXT: str s0, [x1]450; CHECK-NEXT: str h1, [x1, #4]451; CHECK-NEXT: ret452;453; BE-LABEL: load_ext_to_64bits:454; BE: // %bb.0: // %entry455; BE-NEXT: sub sp, sp, #16456; BE-NEXT: .cfi_def_cfa_offset 16457; BE-NEXT: ldrh w8, [x0]458; BE-NEXT: strh w8, [sp, #12]459; BE-NEXT: add x8, x0, #2460; BE-NEXT: ldr s0, [sp, #12]461; BE-NEXT: rev32 v0.8b, v0.8b462; BE-NEXT: ushll v0.8h, v0.8b, #0463; BE-NEXT: ld1 { v0.b }[4], [x8]464; BE-NEXT: bic v0.4h, #255, lsl #8465; BE-NEXT: rev32 v1.8h, v0.8h466; BE-NEXT: mov h0, v0.h[2]467; BE-NEXT: str s1, [x1]468; BE-NEXT: str h0, [x1, #4]469; BE-NEXT: add sp, sp, #16470; BE-NEXT: ret471entry:472 %l = load <3 x i8>, ptr %src, align 1473 %e = zext <3 x i8> %l to <3 x i16>474 store <3 x i16> %e, ptr %dst, align 1475 ret void476}477 478define void @load_ext_to_64bits_default_align(ptr %src, ptr %dst) {479; CHECK-LABEL: load_ext_to_64bits_default_align:480; CHECK: ; %bb.0: ; %entry481; CHECK-NEXT: ldr s0, [x0]482; CHECK-NEXT: zip1.8b v0, v0, v0483; CHECK-NEXT: bic.4h v0, #255, lsl #8484; CHECK-NEXT: mov h1, v0[2]485; CHECK-NEXT: str s0, [x1]486; CHECK-NEXT: str h1, [x1, #4]487; CHECK-NEXT: ret488;489; BE-LABEL: load_ext_to_64bits_default_align:490; BE: // %bb.0: // %entry491; BE-NEXT: ldr s0, [x0]492; BE-NEXT: rev32 v0.8b, v0.8b493; BE-NEXT: zip1 v0.8b, v0.8b, v0.8b494; BE-NEXT: bic v0.4h, #255, lsl #8495; BE-NEXT: rev32 v1.8h, v0.8h496; BE-NEXT: mov h0, v0.h[2]497; BE-NEXT: str s1, [x1]498; BE-NEXT: str h0, [x1, #4]499; BE-NEXT: ret500entry:501 %l = load <3 x i8>, ptr %src502 %e = zext <3 x i8> %l to <3 x i16>503 store <3 x i16> %e, ptr %dst, align 1504 ret void505}506 507define void @load_ext_to_64bits_align_4(ptr %src, ptr %dst) {508; CHECK-LABEL: load_ext_to_64bits_align_4:509; CHECK: ; %bb.0: ; %entry510; CHECK-NEXT: ldr s0, [x0]511; CHECK-NEXT: zip1.8b v0, v0, v0512; CHECK-NEXT: bic.4h v0, #255, lsl #8513; CHECK-NEXT: mov h1, v0[2]514; CHECK-NEXT: str s0, [x1]515; CHECK-NEXT: str h1, [x1, #4]516; CHECK-NEXT: ret517;518; BE-LABEL: load_ext_to_64bits_align_4:519; BE: // %bb.0: // %entry520; BE-NEXT: ldr s0, [x0]521; BE-NEXT: rev32 v0.8b, v0.8b522; BE-NEXT: zip1 v0.8b, v0.8b, v0.8b523; BE-NEXT: bic v0.4h, #255, lsl #8524; BE-NEXT: rev32 v1.8h, v0.8h525; BE-NEXT: mov h0, v0.h[2]526; BE-NEXT: str s1, [x1]527; BE-NEXT: str h0, [x1, #4]528; BE-NEXT: ret529entry:530 %l = load <3 x i8>, ptr %src, align 4531 %e = zext <3 x i8> %l to <3 x i16>532 store <3 x i16> %e, ptr %dst, align 1533 ret void534}535 536define void @load_ext_add_to_64bits(ptr %src, ptr %dst) {537; CHECK-LABEL: load_ext_add_to_64bits:538; CHECK: ; %bb.0: ; %entry539; CHECK-NEXT: ldrb w9, [x0, #2]540; CHECK-NEXT: ldrh w10, [x0]541; CHECK-NEXT: Lloh2:542; CHECK-NEXT: adrp x8, lCPI15_0@PAGE543; CHECK-NEXT: Lloh3:544; CHECK-NEXT: ldr d1, [x8, lCPI15_0@PAGEOFF]545; CHECK-NEXT: orr w9, w10, w9, lsl #16546; CHECK-NEXT: fmov s0, w9547; CHECK-NEXT: zip1.8b v0, v0, v0548; CHECK-NEXT: bic.4h v0, #255, lsl #8549; CHECK-NEXT: add.4h v0, v0, v1550; CHECK-NEXT: mov h1, v0[2]551; CHECK-NEXT: str s0, [x1]552; CHECK-NEXT: str h1, [x1, #4]553; CHECK-NEXT: ret554; CHECK-NEXT: .loh AdrpLdr Lloh2, Lloh3555;556; BE-LABEL: load_ext_add_to_64bits:557; BE: // %bb.0: // %entry558; BE-NEXT: sub sp, sp, #16559; BE-NEXT: .cfi_def_cfa_offset 16560; BE-NEXT: ldrh w8, [x0]561; BE-NEXT: strh w8, [sp, #12]562; BE-NEXT: add x8, x0, #2563; BE-NEXT: ldr s0, [sp, #12]564; BE-NEXT: rev32 v0.8b, v0.8b565; BE-NEXT: ushll v0.8h, v0.8b, #0566; BE-NEXT: ld1 { v0.b }[4], [x8]567; BE-NEXT: adrp x8, .LCPI15_0568; BE-NEXT: add x8, x8, :lo12:.LCPI15_0569; BE-NEXT: ld1 { v1.4h }, [x8]570; BE-NEXT: bic v0.4h, #255, lsl #8571; BE-NEXT: add v0.4h, v0.4h, v1.4h572; BE-NEXT: rev32 v1.8h, v0.8h573; BE-NEXT: mov h0, v0.h[2]574; BE-NEXT: str s1, [x1]575; BE-NEXT: str h0, [x1, #4]576; BE-NEXT: add sp, sp, #16577; BE-NEXT: ret578entry:579 %l = load <3 x i8>, ptr %src, align 1580 %e = zext <3 x i8> %l to <3 x i16>581 %a = add <3 x i16> %e, <i16 3, i16 4, i16 5>582 store <3 x i16> %a, ptr %dst, align 1583 ret void584}585 586define void @shift_trunc_store(ptr %src, ptr %dst) {587; CHECK-LABEL: shift_trunc_store:588; CHECK: ; %bb.0:589; CHECK-NEXT: ldr q0, [x0]590; CHECK-NEXT: ushr.4s v0, v0, #16591; CHECK-NEXT: mov b1, v0[4]592; CHECK-NEXT: mov b2, v0[8]593; CHECK-NEXT: str b0, [x1]594; CHECK-NEXT: stur b1, [x1, #1]595; CHECK-NEXT: stur b2, [x1, #2]596; CHECK-NEXT: ret597;598; BE-LABEL: shift_trunc_store:599; BE: // %bb.0:600; BE-NEXT: sub sp, sp, #16601; BE-NEXT: .cfi_def_cfa_offset 16602; BE-NEXT: ld1 { v0.4s }, [x0]603; BE-NEXT: shrn v0.4h, v0.4s, #16604; BE-NEXT: uzp1 v1.8b, v0.8b, v0.8b605; BE-NEXT: mov h0, v0.h[2]606; BE-NEXT: rev32 v1.16b, v1.16b607; BE-NEXT: stur b0, [x1, #2]608; BE-NEXT: rev32 v1.4h, v1.4h609; BE-NEXT: ushll v1.4s, v1.4h, #0610; BE-NEXT: str h1, [x1]611; BE-NEXT: add sp, sp, #16612; BE-NEXT: ret613 %l = load <3 x i32>, ptr %src614 %s = lshr <3 x i32> %l, <i32 16, i32 16, i32 16>615 %t = trunc <3 x i32> %s to <3 x i8>616 store <3 x i8> %t, ptr %dst, align 1617 ret void618}619 620define void @shift_trunc_store_default_align(ptr %src, ptr %dst) {621; CHECK-LABEL: shift_trunc_store_default_align:622; CHECK: ; %bb.0:623; CHECK-NEXT: ldr q0, [x0]624; CHECK-NEXT: ushr.4s v0, v0, #16625; CHECK-NEXT: mov b1, v0[4]626; CHECK-NEXT: mov b2, v0[8]627; CHECK-NEXT: str b0, [x1]628; CHECK-NEXT: stur b1, [x1, #1]629; CHECK-NEXT: stur b2, [x1, #2]630; CHECK-NEXT: ret631;632; BE-LABEL: shift_trunc_store_default_align:633; BE: // %bb.0:634; BE-NEXT: sub sp, sp, #16635; BE-NEXT: .cfi_def_cfa_offset 16636; BE-NEXT: ld1 { v0.4s }, [x0]637; BE-NEXT: shrn v0.4h, v0.4s, #16638; BE-NEXT: uzp1 v1.8b, v0.8b, v0.8b639; BE-NEXT: mov h0, v0.h[2]640; BE-NEXT: rev32 v1.16b, v1.16b641; BE-NEXT: stur b0, [x1, #2]642; BE-NEXT: rev32 v1.4h, v1.4h643; BE-NEXT: ushll v1.4s, v1.4h, #0644; BE-NEXT: str h1, [x1]645; BE-NEXT: add sp, sp, #16646; BE-NEXT: ret647 %l = load <3 x i32>, ptr %src648 %s = lshr <3 x i32> %l, <i32 16, i32 16, i32 16>649 %t = trunc <3 x i32> %s to <3 x i8>650 store <3 x i8> %t, ptr %dst651 ret void652}653 654define void @shift_trunc_store_align_4(ptr %src, ptr %dst) {655; CHECK-LABEL: shift_trunc_store_align_4:656; CHECK: ; %bb.0:657; CHECK-NEXT: ldr q0, [x0]658; CHECK-NEXT: ushr.4s v0, v0, #16659; CHECK-NEXT: mov b1, v0[4]660; CHECK-NEXT: mov b2, v0[8]661; CHECK-NEXT: str b0, [x1]662; CHECK-NEXT: stur b1, [x1, #1]663; CHECK-NEXT: stur b2, [x1, #2]664; CHECK-NEXT: ret665;666; BE-LABEL: shift_trunc_store_align_4:667; BE: // %bb.0:668; BE-NEXT: sub sp, sp, #16669; BE-NEXT: .cfi_def_cfa_offset 16670; BE-NEXT: ld1 { v0.4s }, [x0]671; BE-NEXT: shrn v0.4h, v0.4s, #16672; BE-NEXT: uzp1 v1.8b, v0.8b, v0.8b673; BE-NEXT: mov h0, v0.h[2]674; BE-NEXT: rev32 v1.16b, v1.16b675; BE-NEXT: stur b0, [x1, #2]676; BE-NEXT: rev32 v1.4h, v1.4h677; BE-NEXT: ushll v1.4s, v1.4h, #0678; BE-NEXT: str h1, [x1]679; BE-NEXT: add sp, sp, #16680; BE-NEXT: ret681 %l = load <3 x i32>, ptr %src682 %s = lshr <3 x i32> %l, <i32 16, i32 16, i32 16>683 %t = trunc <3 x i32> %s to <3 x i8>684 store <3 x i8> %t, ptr %dst, align 4685 ret void686}687 688define void @shift_trunc_store_const_offset_1(ptr %src, ptr %dst) {689; CHECK-LABEL: shift_trunc_store_const_offset_1:690; CHECK: ; %bb.0:691; CHECK-NEXT: ldr q0, [x0]692; CHECK-NEXT: ushr.4s v0, v0, #16693; CHECK-NEXT: mov b1, v0[4]694; CHECK-NEXT: mov b2, v0[8]695; CHECK-NEXT: stur b0, [x1, #1]696; CHECK-NEXT: stur b1, [x1, #2]697; CHECK-NEXT: stur b2, [x1, #3]698; CHECK-NEXT: ret699;700; BE-LABEL: shift_trunc_store_const_offset_1:701; BE: // %bb.0:702; BE-NEXT: sub sp, sp, #16703; BE-NEXT: .cfi_def_cfa_offset 16704; BE-NEXT: ld1 { v0.4s }, [x0]705; BE-NEXT: shrn v0.4h, v0.4s, #16706; BE-NEXT: uzp1 v1.8b, v0.8b, v0.8b707; BE-NEXT: mov h0, v0.h[2]708; BE-NEXT: rev32 v1.16b, v1.16b709; BE-NEXT: stur b0, [x1, #3]710; BE-NEXT: rev32 v1.4h, v1.4h711; BE-NEXT: ushll v1.4s, v1.4h, #0712; BE-NEXT: stur h1, [x1, #1]713; BE-NEXT: add sp, sp, #16714; BE-NEXT: ret715 %l = load <3 x i32>, ptr %src716 %s = lshr <3 x i32> %l, <i32 16, i32 16, i32 16>717 %t = trunc <3 x i32> %s to <3 x i8>718 %dst.1 = getelementptr inbounds i8, ptr %dst, i64 1719 store <3 x i8> %t, ptr %dst.1, align 1720 ret void721}722 723define void @shift_trunc_store_const_offset_3(ptr %src, ptr %dst) {724; CHECK-LABEL: shift_trunc_store_const_offset_3:725; CHECK: ; %bb.0:726; CHECK-NEXT: ldr q0, [x0]727; CHECK-NEXT: ushr.4s v0, v0, #16728; CHECK-NEXT: mov b1, v0[4]729; CHECK-NEXT: mov b2, v0[8]730; CHECK-NEXT: stur b0, [x1, #3]731; CHECK-NEXT: stur b1, [x1, #4]732; CHECK-NEXT: stur b2, [x1, #5]733; CHECK-NEXT: ret734;735; BE-LABEL: shift_trunc_store_const_offset_3:736; BE: // %bb.0:737; BE-NEXT: sub sp, sp, #16738; BE-NEXT: .cfi_def_cfa_offset 16739; BE-NEXT: ld1 { v0.4s }, [x0]740; BE-NEXT: shrn v0.4h, v0.4s, #16741; BE-NEXT: uzp1 v1.8b, v0.8b, v0.8b742; BE-NEXT: mov h0, v0.h[2]743; BE-NEXT: rev32 v1.16b, v1.16b744; BE-NEXT: stur b0, [x1, #5]745; BE-NEXT: rev32 v1.4h, v1.4h746; BE-NEXT: ushll v1.4s, v1.4h, #0747; BE-NEXT: stur h1, [x1, #3]748; BE-NEXT: add sp, sp, #16749; BE-NEXT: ret750 %l = load <3 x i32>, ptr %src751 %s = lshr <3 x i32> %l, <i32 16, i32 16, i32 16>752 %t = trunc <3 x i32> %s to <3 x i8>753 %dst.3 = getelementptr inbounds i8, ptr %dst, i64 3754 store <3 x i8> %t, ptr %dst.3, align 1755 ret void756}757 758define void @shift_trunc_volatile_store(ptr %src, ptr %dst) {759; CHECK-LABEL: shift_trunc_volatile_store:760; CHECK: ; %bb.0:761; CHECK-NEXT: sub sp, sp, #16762; CHECK-NEXT: .cfi_def_cfa_offset 16763; CHECK-NEXT: ldr q0, [x0]764; CHECK-NEXT: shrn.4h v0, v0, #16765; CHECK-NEXT: uzp1.8b v1, v0, v0766; CHECK-NEXT: mov h0, v0[2]767; CHECK-NEXT: ushll.4s v1, v1, #0768; CHECK-NEXT: stur b0, [x1, #2]769; CHECK-NEXT: str h1, [x1]770; CHECK-NEXT: add sp, sp, #16771; CHECK-NEXT: ret772;773; BE-LABEL: shift_trunc_volatile_store:774; BE: // %bb.0:775; BE-NEXT: sub sp, sp, #16776; BE-NEXT: .cfi_def_cfa_offset 16777; BE-NEXT: ld1 { v0.4s }, [x0]778; BE-NEXT: shrn v0.4h, v0.4s, #16779; BE-NEXT: uzp1 v1.8b, v0.8b, v0.8b780; BE-NEXT: mov h0, v0.h[2]781; BE-NEXT: rev32 v1.16b, v1.16b782; BE-NEXT: stur b0, [x1, #2]783; BE-NEXT: rev32 v1.4h, v1.4h784; BE-NEXT: ushll v1.4s, v1.4h, #0785; BE-NEXT: str h1, [x1]786; BE-NEXT: add sp, sp, #16787; BE-NEXT: ret788 %l = load <3 x i32>, ptr %src789 %s = lshr <3 x i32> %l, <i32 16, i32 16, i32 16>790 %t = trunc <3 x i32> %s to <3 x i8>791 store volatile <3 x i8> %t, ptr %dst, align 1792 ret void793}794 795define void @load_v3i8_zext_to_3xi32_add_trunc_store(ptr %src) {796; CHECK-LABEL: load_v3i8_zext_to_3xi32_add_trunc_store:797; CHECK: ; %bb.0:798; CHECK-NEXT: ldrb w9, [x0, #2]799; CHECK-NEXT: ldrh w10, [x0]800; CHECK-NEXT: Lloh4:801; CHECK-NEXT: adrp x8, lCPI22_0@PAGE802; CHECK-NEXT: Lloh5:803; CHECK-NEXT: ldr q1, [x8, lCPI22_0@PAGEOFF]804; CHECK-NEXT: orr w9, w10, w9, lsl #16805; CHECK-NEXT: fmov s0, w9806; CHECK-NEXT: zip1.8b v0, v0, v0807; CHECK-NEXT: uaddw.4s v0, v1, v0808; CHECK-NEXT: mov b1, v0[8]809; CHECK-NEXT: mov b2, v0[4]810; CHECK-NEXT: str b0, [x0]811; CHECK-NEXT: stur b1, [x0, #2]812; CHECK-NEXT: stur b2, [x0, #1]813; CHECK-NEXT: ret814; CHECK-NEXT: .loh AdrpLdr Lloh4, Lloh5815;816; BE-LABEL: load_v3i8_zext_to_3xi32_add_trunc_store:817; BE: // %bb.0:818; BE-NEXT: sub sp, sp, #16819; BE-NEXT: .cfi_def_cfa_offset 16820; BE-NEXT: ldrh w9, [x0]821; BE-NEXT: adrp x8, .LCPI22_0822; BE-NEXT: add x8, x8, :lo12:.LCPI22_0823; BE-NEXT: ld1 { v1.4h }, [x8]824; BE-NEXT: strh w9, [sp, #12]825; BE-NEXT: add x9, x0, #2826; BE-NEXT: ldr s0, [sp, #12]827; BE-NEXT: rev32 v0.8b, v0.8b828; BE-NEXT: ushll v0.8h, v0.8b, #0829; BE-NEXT: ld1 { v0.b }[4], [x9]830; BE-NEXT: add v0.4h, v0.4h, v1.4h831; BE-NEXT: uzp1 v1.8b, v0.8b, v0.8b832; BE-NEXT: mov h0, v0.h[2]833; BE-NEXT: rev32 v1.16b, v1.16b834; BE-NEXT: stur b0, [x0, #2]835; BE-NEXT: rev32 v1.4h, v1.4h836; BE-NEXT: ushll v1.4s, v1.4h, #0837; BE-NEXT: str h1, [x0]838; BE-NEXT: add sp, sp, #16839; BE-NEXT: ret840 %l = load <3 x i8>, ptr %src, align 1841 %e = zext <3 x i8> %l to <3 x i32>842 %add = add <3 x i32> %e, <i32 1, i32 2, i32 3>843 %t = trunc <3 x i32> %add to <3 x i8>844 store <3 x i8> %t, ptr %src845 ret void846}847 848define void @load_v3i8_sext_to_3xi32_add_trunc_store(ptr %src) {849; CHECK-LABEL: load_v3i8_sext_to_3xi32_add_trunc_store:850; CHECK: ; %bb.0:851; CHECK-NEXT: ldrb w9, [x0, #2]852; CHECK-NEXT: ldrh w10, [x0]853; CHECK-NEXT: Lloh6:854; CHECK-NEXT: adrp x8, lCPI23_0@PAGE855; CHECK-NEXT: Lloh7:856; CHECK-NEXT: ldr q1, [x8, lCPI23_0@PAGEOFF]857; CHECK-NEXT: orr w9, w10, w9, lsl #16858; CHECK-NEXT: fmov s0, w9859; CHECK-NEXT: zip1.8b v0, v0, v0860; CHECK-NEXT: uaddw.4s v0, v1, v0861; CHECK-NEXT: mov b1, v0[8]862; CHECK-NEXT: mov b2, v0[4]863; CHECK-NEXT: str b0, [x0]864; CHECK-NEXT: stur b1, [x0, #2]865; CHECK-NEXT: stur b2, [x0, #1]866; CHECK-NEXT: ret867; CHECK-NEXT: .loh AdrpLdr Lloh6, Lloh7868;869; BE-LABEL: load_v3i8_sext_to_3xi32_add_trunc_store:870; BE: // %bb.0:871; BE-NEXT: sub sp, sp, #16872; BE-NEXT: .cfi_def_cfa_offset 16873; BE-NEXT: ldrh w9, [x0]874; BE-NEXT: adrp x8, .LCPI23_0875; BE-NEXT: add x8, x8, :lo12:.LCPI23_0876; BE-NEXT: ld1 { v1.4h }, [x8]877; BE-NEXT: strh w9, [sp, #12]878; BE-NEXT: add x9, x0, #2879; BE-NEXT: ldr s0, [sp, #12]880; BE-NEXT: rev32 v0.8b, v0.8b881; BE-NEXT: ushll v0.8h, v0.8b, #0882; BE-NEXT: ld1 { v0.b }[4], [x9]883; BE-NEXT: add v0.4h, v0.4h, v1.4h884; BE-NEXT: uzp1 v1.8b, v0.8b, v0.8b885; BE-NEXT: mov h0, v0.h[2]886; BE-NEXT: rev32 v1.16b, v1.16b887; BE-NEXT: stur b0, [x0, #2]888; BE-NEXT: rev32 v1.4h, v1.4h889; BE-NEXT: ushll v1.4s, v1.4h, #0890; BE-NEXT: str h1, [x0]891; BE-NEXT: add sp, sp, #16892; BE-NEXT: ret893 %l = load <3 x i8>, ptr %src, align 1894 %e = sext <3 x i8> %l to <3 x i32>895 %add = add <3 x i32> %e, <i32 1, i32 2, i32 3>896 %t = trunc <3 x i32> %add to <3 x i8>897 store <3 x i8> %t, ptr %src898 ret void899}900