<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/107287>107287</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [Aarch64] Various idioms equivalent to a simple vector `shl` or `shr` should be optimized
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          Validark
      </td>
    </tr>
</table>

<pre>
    [Godbolt link](https://zig.godbolt.org/z/87rjhxxdc)

```zig
const std = @import("std");

// This one is compiled to a `shl`. The rest are not.
export fn foo1(v: @Vector(8, u16)) @Vector(8, u16) {
    return v << @splat(8);
}

export fn foo2(v: @Vector(16, u8)) @Vector(16, u8) {
    return @as(@Vector(16, u8), .{ 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF }) &
 std.simd.shiftElementsRight(v, 1, 0);
}

export fn foo3(v: @Vector(16, u8)) @Vector(16, u8) {
    return @shuffle(u8, v, @as(@Vector(16, u8), @splat(0)), [_]i32{ -1, 0, -1, 2, -1, 4, -1, 6, -1, 8, -1, 10, -1, 12, -1, 14 });
}

// Extra test cases, that currently compile to the same `tbl` instruction
export fn foo4(v: @Vector(16, u8)) @Vector(16, u8) {
    return @shuffle(u8, @as(@Vector(16, u8), @splat(0)), v, [_]i32{ 0, -1, 0, -3, 0, -5, 0, -7, 0, -9, 0, -11, 0, -13, 0, -15 });
}

export fn foo5(v: @Vector(16, u8)) @Vector(16, u8) {
 return std.simd.interlace(.{ @as(@Vector(8, u8), @splat(0)), std.simd.deinterlace(2, v)[0] });
}
```

On x86, these all compile down to `vpsllw xmm0, xmm0, 8`. Arm should be able to get this optimization too.

<details>
  <summary>Preoptimized LLVM dump</summary>

via `zig build-obj ./src/llvm_code.zig -O ReleaseFast -target aarch64-linux -mcpu apple_latest --verbose-llvm-ir -fstrip >llvm_code.ll 2>&1`

```llvm
; ModuleID = 'llvm_code'
source_filename = "llvm_code"
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64-unknown-linux-musl"

%Target.Cpu.Feature.Set = type { [5 x i64] }
%Target.Cpu.Model = type { { ptr, i64 }, { ptr, i64 }, %Target.Cpu.Feature.Set }
%Target.Cpu = type { ptr, %Target.Cpu.Feature.Set, i6, [7 x i8] }

@builtin.zig_backend = internal unnamed_addr constant i64 2, align 8
@Target.Cpu.Feature.Set.empty = internal unnamed_addr constant %Target.Cpu.Feature.Set zeroinitializer, align 8
@Target.aarch64.cpu.apple_latest = internal unnamed_addr constant %Target.Cpu.Model { { ptr, i64 } { ptr getelementptr inbounds (i8, ptr @__anon_227, i64 0), i64 12 }, { ptr, i64 } { ptr getelementptr inbounds (i8, ptr @__anon_230, i64 0), i64 12 }, %Target.Cpu.Feature.Set { [5 x i64] [i64 158329674598400, i64 2251799830972420, i64 1125900041060352, i64 12885032960, i64 0] } }, align 8
@__anon_227 = internal unnamed_addr constant [13 x i8] c"apple_latest\00", align 1
@__anon_230 = internal unnamed_addr constant [13 x i8] c"apple-latest\00", align 1
@builtin.cpu = internal unnamed_addr constant %Target.Cpu { ptr getelementptr inbounds (i8, ptr @Target.aarch64.cpu.apple_latest, i64 0), %Target.Cpu.Feature.Set { [5 x i64] [i64 -6882457295353816576, i64 3831332528523300484, i64 4612917471702155264, i64 47783866528, i64 0] }, i6 6, [7 x i8] undef }, align 8
@start.simplified_logic = internal unnamed_addr constant i1 false, align 1
@builtin.output_mode = internal unnamed_addr constant i2 -2, align 1

; Function Attrs: nounwind uwtable nosanitize_coverage skipprofile
define dso_local <8 x i16> @foo1(<8 x i16> %0) #0 {
1:
 %2 = zext <8 x i4> <i4 -8, i4 -8, i4 -8, i4 -8, i4 -8, i4 -8, i4 -8, i4 -8> to <8 x i16>
  %3 = shl <8 x i16> %0, %2
  ret <8 x i16> %3
}

; Function Attrs: nounwind uwtable nosanitize_coverage skipprofile
define dso_local <16 x i8> @foo2(<16 x i8> %0) #0 {
1:
 %2 = call fastcc <16 x i8> @simd.shiftElementsRight__anon_1518(<16 x i8> %0, i8 0)
  %3 = and <16 x i8> <i8 0, i8 -1, i8 0, i8 -1, i8 0, i8 -1, i8 0, i8 -1, i8 0, i8 -1, i8 0, i8 -1, i8 0, i8 -1, i8 0, i8 -1>, %2
  ret <16 x i8> %3
}

; Function Attrs: nounwind uwtable nosanitize_coverage skipprofile
define internal fastcc <16 x i8> @simd.shiftElementsRight__anon_1518(<16 x i8> %0, i8 %1) unnamed_addr #0 {
2:
  %3 = insertelement <1 x i8> poison, i8 %1, i32 0
  %4 = shufflevector <1 x i8> %3, <1 x i8> poison, <16 x i32> zeroinitializer
 %5 = call fastcc <16 x i8> @simd.mergeShift__anon_1524(<16 x i8> %4, <16 x i8> %0)
  ret <16 x i8> %5
}

; Function Attrs: nounwind uwtable nosanitize_coverage skipprofile
define internal fastcc <16 x i8> @simd.mergeShift__anon_1524(<16 x i8> %0, <16 x i8> %1) unnamed_addr #0 {
2:
  %3 = call fastcc <32 x i8> @simd.join__anon_1538(<16 x i8> %0, <16 x i8> %1)
  %4 = call fastcc <16 x i8> @simd.extract__anon_1554(<32 x i8> %3)
  ret <16 x i8> %4
}

; Function Attrs: nounwind uwtable nosanitize_coverage skipprofile
define internal fastcc <32 x i8> @simd.join__anon_1538(<16 x i8> %0, <16 x i8> %1) unnamed_addr #0 {
2:
 %3 = shufflevector <16 x i8> %0, <16 x i8> %1, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
  ret <32 x i8> %3
}

; Function Attrs: nounwind uwtable nosanitize_coverage skipprofile
define internal fastcc <16 x i8> @simd.extract__anon_1554(<32 x i8> %0) unnamed_addr #0 {
1:
  call fastcc void @debug.assert(i1 true)
  %2 = shufflevector <32 x i8> %0, <32 x i8> undef, <16 x i32> <i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30>
  ret <16 x i8> %2
}

; Function Attrs: nounwind uwtable nosanitize_coverage skipprofile
define internal fastcc void @debug.assert(i1 %0) unnamed_addr #0 {
1:
  %2 = xor i1 %0, true
 br i1 %2, label %4, label %5

3:
  ret void

4:
 unreachable

5:
  br label %3
}

; Function Attrs: nounwind uwtable nosanitize_coverage skipprofile
define dso_local <16 x i8> @foo3(<16 x i8> %0) #0 {
1:
  %2 = shufflevector <16 x i8> %0, <16 x i8> zeroinitializer, <16 x i32> <i32 16, i32 0, i32 16, i32 2, i32 16, i32 4, i32 16, i32 6, i32 16, i32 8, i32 16, i32 10, i32 16, i32 12, i32 16, i32 14>
  ret <16 x i8> %2
}

; Function Attrs: nounwind uwtable nosanitize_coverage skipprofile
define dso_local <16 x i8> @foo4(<16 x i8> %0) #0 {
1:
  %2 = shufflevector <16 x i8> zeroinitializer, <16 x i8> %0, <16 x i32> <i32 0, i32 16, i32 0, i32 18, i32 0, i32 20, i32 0, i32 22, i32 0, i32 24, i32 0, i32 26, i32 0, i32 28, i32 0, i32 30>
  ret <16 x i8> %2
}

; Function Attrs: nounwind uwtable nosanitize_coverage skipprofile
define dso_local <16 x i8> @foo5(<16 x i8> %0) #0 {
1:
 %2 = alloca [8 x i8], align 8
  %3 = alloca [16 x i8], align 8
  call fastcc void @simd.deinterlace__anon_1670(ptr sret([2 x <8 x i8>]) %3, <16 x i8> %0)
  %4 = getelementptr inbounds [2 x <8 x i8>], ptr %3, i64 0, i64 0
  %5 = load <8 x i8>, ptr %4
  %6 = getelementptr inbounds { <8 x i8> }, ptr %2, i32 0, i32 0
  store <8 x i8> %5, ptr %6, align 8
  %7 = call fastcc <16 x i8> @simd.interlace__anon_1677(ptr align 8 readonly nonnull %2)
  ret <16 x i8> %7
}

; Function Attrs: nounwind uwtable nosanitize_coverage skipprofile
define internal fastcc void @simd.deinterlace__anon_1670(ptr noalias sret([2 x <8 x i8>]) nonnull %0, <16 x i8> %1) unnamed_addr #0 {
2:
  %3 = alloca [16 x i8], align 8
 call void @llvm.memset.p0.i64(ptr align 8 %3, i8 undef, i64 16, i1 false)
 %4 = getelementptr inbounds [2 x <8 x i8>], ptr %3, i64 0, i64 0
  %5 = shufflevector <16 x i8> %1, <16 x i8> undef, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
  store <8 x i8> %5, ptr %4, align 8
  %6 = getelementptr inbounds [2 x <8 x i8>], ptr %3, i64 0, i64 1
 %7 = shufflevector <16 x i8> %1, <16 x i8> undef, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>
  store <8 x i8> %7, ptr %6, align 8
  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %0, ptr align 8 %3, i64 16, i1 false)
  ret void
}

; Function Attrs: nounwind uwtable nosanitize_coverage skipprofile
define internal fastcc <16 x i8> @simd.interlace__anon_1677(ptr align 8 readonly nonnull %0) unnamed_addr #0 {
1:
  %2 = alloca [16 x i8], align 8
  %3 = alloca [16 x i8], align 8
  %4 = getelementptr inbounds { <8 x i8> }, ptr %0, i32 0, i32 0
  %5 = load <8 x i8>, ptr %4, align 8
  %6 = getelementptr inbounds [2 x <8 x i8>], ptr %3, i64 0, i64 0
  store <8 x i8> zeroinitializer, ptr %6, align 8
  %7 = getelementptr inbounds [2 x <8 x i8>], ptr %3, i64 0, i64 1
 store <8 x i8> %5, ptr %7, align 8
  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %2, ptr align 8 %3, i64 16, i1 false)
  %8 = getelementptr inbounds <8 x i8>, ptr %2, i64 0
  %9 = call fastcc <8 x i8> @simd.interlace__anon_1735(ptr align 8 readonly nonnull %8)
  %10 = getelementptr inbounds <8 x i8>, ptr %2, i64 1
  %11 = call fastcc <8 x i8> @simd.interlace__anon_1735(ptr align 8 readonly nonnull %10)
  %12 = shufflevector <8 x i8> %9, <8 x i8> %11, <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15>
  ret <16 x i8> %12
}

; Function Attrs: nounwind willreturn nofree nocallback memory(argmem: write)
declare void @llvm.memset.p0.i64(ptr nocapture writeonly %0, i8 %1, i64 %2, i1 immarg %3) #1

; Function Attrs: nounwind willreturn nofree nocallback memory(argmem: readwrite)
declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly %0, ptr noalias nocapture readonly %1, i64 %2, i1 immarg %3) #2

; Function Attrs: nounwind uwtable nosanitize_coverage skipprofile
define internal fastcc <8 x i8> @simd.interlace__anon_1735(ptr align 8 readonly nonnull %0) unnamed_addr #0 {
1:
  %2 = alloca [8 x i8], align 8
  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %2, ptr align 8 %0, i64 8, i1 false)
  %3 = getelementptr inbounds [1 x <8 x i8>], ptr %0, i64 0, i64 0
  %4 = load <8 x i8>, ptr %3
  ret <8 x i8> %4
}

attributes #0 = { nounwind uwtable nosanitize_coverage skipprofile "frame-pointer"="none" "target-cpu"="apple-latest" "target-features"="-a510,-a520,-a65,-a710,-a720,-a76,-a78,-a78c,-addr-lsl-fast,+aes,-aggressive-fma,+alternate-sextload-cvt-f32-pattern,+altnzcv,-alu-lsl-fast,+am,+amvs,+arith-bcc-fusion,+arith-cbz-fusion,-ascend-store-address,-b16b16,-balance-fp-ops,+bf16,-brbe,+bti,-call-saved-x10,-call-saved-x11,-call-saved-x12,-call-saved-x13,-call-saved-x14,-call-saved-x15,-call-saved-x18,-call-saved-x8,-call-saved-x9,+ccdp,+ccidx,+ccpp,-chk,-clrbhb,-cmp-bcc-fusion,+complxnum,+CONTEXTIDREL2,-cortex-r82,-cpa,+crc,+crypto,-cssc,-d128,+disable-latency-sched-heuristic,-disable-ldp,-disable-stp,+dit,+dotprod,+ecv,+el2vmsa,+el3,-enable-select-opt,-ete,-exynos-cheap-as-move,-f32mm,-f64mm,-faminmax,+fgt,-fix-cortex-a53-835769,+flagm,-fmv,-force-32bit-jump-tables,+fp16fml,-fp8,-fp8dot2,-fp8dot4,-fp8fma,+fp-armv8,-fpmr,+fptoint,+fullfp16,+fuse-address,-fuse-addsub-2reg-const1,-fuse-adrp-add,+fuse-aes,+fuse-arith-logic,+fuse-crypto-eor,+fuse-csel,+fuse-literals,-gcs,-harden-sls-blr,-harden-sls-nocomdat,-harden-sls-retbr,-hbc,+hcx,+i8mm,-ite,+jsconv,-ldp-aligned-only,+lor,-ls64,+lse,-lse128,+lse2,-lut,-mec,-mops,+mpam,-mte,+neon,-nmi,-no-bti-at-return-twice,-no-neg-immediates,-no-sve-fp-ld1r,-no-zcz-fp,+nv,-outline-atomics,+pan,+pan-rwv,+pauth,-pauth-lr,+perfmon,-predictable-select-expensive,+predres,-prfm-slc-target,-rand,+ras,-rasv2,+rcpc,-rcpc3,+rcpc-immo,+rdm,-reserve-x1,-reserve-x10,-reserve-x11,-reserve-x12,-reserve-x13,-reserve-x14,-reserve-x15,-reserve-x18,-reserve-x2,-reserve-x20,-reserve-x21,-reserve-x22,-reserve-x23,-reserve-x24,-reserve-x25,-reserve-x26,-reserve-x27,-reserve-x28,-reserve-x3,-reserve-x30,-reserve-x4,-reserve-x5,-reserve-x6,-reserve-x7,-reserve-x9,-rme,+sb,+sel2,+sha2,+sha3,-slow-misaligned-128store,-slow-paired-128,-slow-strqro-store,-sm4,-sme,-sme2,-sme2p1,-sme-f16f16,-sme-f64f64,-sme-f8f16,-sme-f8f32,-sme-fa64,-sme-i16i64,-sme-lutv2,-spe,-spe-eef,-specres2,+specrestrict,+ssbs,-ssve-fp8dot2,-ssve-fp8dot4,-ssve-fp8fma,+store-pair-suppress,-stp-aligned-only,-strict-align,-sve,-sve2,-sve2-aes,-sve2-bitperm,-sve2-sha3,-sve2-sm4,-sve2p1,-tagged-globals,-the,+tlb-rmi,-tlbiw,-tme,-tpidr-el1,-tpidr-el2,-tpidr-el3,-tpidrro-el0,+tracev8.4,-trbe,+uaops,-use-experimental-zeroing-pseudos,-use-postra-scheduler,-use-reciprocal-square-root,-use-scalar-inc-vl,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,-v8.7a,-v8.8a,-v8.9a,+v8a,-v8r,-v9.1a,-v9.2a,-v9.3a,-v9.4a,-v9.5a,-v9a,+vh,-wfxt,-xs,+zcm,+zcz,-zcz-fp-workaround,+zcz-gp" }
attributes #1 = { nounwind willreturn nofree nocallback memory(argmem: write) }
attributes #2 = { nounwind willreturn nofree nocallback memory(argmem: readwrite) }

!llvm.module.flags = !{}
```

</details>


<details>
  <summary>Optimized LLVM</summary>


```llvm
ddefine dso_local <8 x i16> @foo1(<8 x i16> %0) local_unnamed_addr {
Entry:
  %1 = shl <8 x i16> %0, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8>
  ret <8 x i16> %1
}

declare void @llvm.dbg.value(metadata, metadata, metadata) #1

define dso_local <16 x i8> @foo2(<16 x i8> %0) local_unnamed_addr {
Entry:
  %1 = shufflevector <16 x i8> <i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 0>, <16 x i8> %0, <16 x i32> <i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30>
 %2 = and <16 x i8> %1, <i8 0, i8 -1, i8 0, i8 -1, i8 0, i8 -1, i8 0, i8 -1, i8 0, i8 -1, i8 0, i8 -1, i8 0, i8 -1, i8 0, i8 -1>
  ret <16 x i8> %2
}

define dso_local <16 x i8> @foo3(<16 x i8> %0) local_unnamed_addr {
Entry:
  %1 = shufflevector <16 x i8> %0, <16 x i8> <i8 0, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison>, <16 x i32> <i32 16, i32 0, i32 16, i32 2, i32 16, i32 4, i32 16, i32 6, i32 16, i32 8, i32 16, i32 10, i32 16, i32 12, i32 16, i32 14>
  ret <16 x i8> %1
}

define dso_local <16 x i8> @foo4(<16 x i8> %0) local_unnamed_addr {
Entry:
  %1 = shufflevector <16 x i8> <i8 0, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison>, <16 x i8> %0, <16 x i32> <i32 0, i32 16, i32 0, i32 18, i32 0, i32 20, i32 0, i32 22, i32 0, i32 24, i32 0, i32 26, i32 0, i32 28, i32 0, i32 30>
  ret <16 x i8> %1
}

define dso_local <16 x i8> @foo5(<16 x i8> %0) local_unnamed_addr {
Entry:
  %1 = shufflevector <16 x i8> %0, <16 x i8> poison, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
  %2 = shufflevector <8 x i8> zeroinitializer, <8 x i8> %1, <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15>
  ret <16 x i8> %2
}

declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
```

</details>
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzcfFtv5Ki28K9xvyBKBl_roR86leTTlvb-5mhmNDpvEbapKrqx8QCuVPLrj8D4VnZdknTP9GypO14s8FqLdQUbF1GK7SpKP3vRnRfdfyKN3gv5-Q_CWUHkt0-ZKF5M3_8TRSa4BpxV37zo3sPpXutaecEXDz96-PGV7Va7dsxKyJ3BePgxTeTX_fFY5B5ee_69539xf2O__ffKdi0mF5XSQOkCeME98EKflbWQ2sOph7HShYexoRHcTchY1uD3PVNAVBQwBXJR1ozTAmgBCPBiX-25F_sr8PueAkmVBkRSUAm9aknQo2EDthXYCoE8nB684Ivh_wfNtZAeTlMPb0CDYsMer891AS9xogEAgKS6kRU4AC_YeMHG3KRqTnR7z2gayf14PhNh8JIwhtcGNOmCMKOuRWG80CfK6PMcuQ1Yeckd8A3kHx8f7fXHNICZuJETx05OpYuVYmWxUnu21Q-clrTS6le222urB7wByJG4TX3B91ef2jfbLaceThtreSvVDWodWd9vOVtsdPfkRfcswEbrEPUKakE8gOEAxgOYDiAa3YdGN6LQKfqcxlwAPRy1JECb6MiJosrcq_dEg7yRklaav3RxZcJK7ylQpKQmunRmoguwSmnZ5JqJasEU4Y83xbutcJibYqTMFgwGMBrAZADXI9uN7Ti6EUVXTDHRWPRdNObU1YcWqzSVnORGbTbUl7SW3qC0nmJBxzSxU-jai-58L7o_P-Mu_Y8V8EsFjmncuh5VFBDOe68rxHNlXM-L_UOtOH8Gx7K0iu2uqU3yX2QJ1F40vAAZBSRrHXZHNdC2RtSaleyVGD8FWojVJBaCTUE1YVx5wUPnc16wUU1ZEvniBQ__I6mjQAvw73__8R9QNGVtUjx-HEaNaR6YrUGvbAeyhvECiuwrWJnhMvfwI-eH8ikXBV2ZEfAX8CvllCj6SJQGUBNpJCdE5vs4hJxVzRHAMq8bQOqa0ydObMhCeKAyE4pCQw8yCeBWaclq4AUPAwvOATbi4RidaL43hxncKeMO_EcUDaf_um8rMk56Uh5O2lFKNDKnT1vGaWUTgh2IRwNxO9BNpSCacPIiGt0NpbD0gi8UstQLvpj_AYYMxV7wxf4xrTj0gi9xCBnCZgDCKawC3OJ-Q3Z9MGFiZs57WTrtNdW3SjxXrRZh2Sje39elwuh3S2C1qZvVIyW6kXT1G21F1S81BTZkorsIHIGRyjn4wt3_EQXlJ_cld6DW0rgqi11a3pzDnhdlkd-Uk6N3lkjLzKW9xMwlnU6l_Rv6xmM1q4xvPmUk_0ardnFmQ74iHDSVsXrxRIpCAruAI5W2E7GZgHC2q0Da01sWZ0XLWr_cQvi8Wl6pFKximhHOXqm8wNy5wyqvm9UkiN7M39l40bQdymQe2i5lTItVmWiqQgEPp8zmWYP1Qv_piVSiesI46Yj4LtMaGOHz7vJeToF_hdMFF5wFQXRnb47SAK_jJIzWaej39DGOULJep4G_TnCIezxCOFr7vh8iP_aDCA8ypGnkG0ojEVv_7IQ7te2gvpvMGN2hoHf73OSIkSN40cbIPnJgNOMT-B_gA6_z6QIvd6H9Fr98q0NciYtTL3mHX8A4TXEYJXgdBVGQojhK4o5skAYoCHCE0wgHge-Hadh1hTHCa5SECUp8jKIIx0NXkqRBGscRTk9dpG2DeXprqoJuzzmQ0kRqs6KpOdsyWjxxsWP5TckOgS3hil4yo2h03einUhT0JpIYwAW36MvyY1PZhTb4orU0G3BQiaZ6ZlUBmmdt1zyVUMSkw1f6lIsDlWRHgfrG6loKU6tbWgXdsoqCQoknLnJi6tUmNfoylffB-IbbEZ_gceS3WzcTBt1aE3mBE9EMwHaer_Soe6KhvTfYsBDA1mofAIIHuxgcy9Uv2HAUWO5qP5uRldz6MO6GS6rno4LlvdIP1j2KW2ftdY9b3Y_xN-s-N6vnLVE6z-e0z-yzXXpDEUrPcN4Alrap4FTbxK4NJncEm3awvandTv0dCLPiXbT5dHZ_mc376P8x1vFwhIyLTHLL1F_w4C-DAVmlqOwqhhWqp14LpkQ1ob8BLMDAH1EJXdDZbfnBbianVKyOjSWWSfcTMkv7h9mKrnfv6Eb3Lqnc0d-MFnvF4XBJceGE-zjMLvpL9HP5y83T9Ren-y6XOTFCgGdSfRWs6uUJzvvtojwz57pudHrUkuSDCiKngrFo1g0v2zb8G237vbV4o1VHZfM0gm9jtBmEbyPY5H-bI1yy6LMG7oCgA8IOiDog7oCkA9IOWPcEB9I9bdQTRz111JNHPX3UM0A9B9SzQD0P3PPAg_w9D9zzwD0P3PPAPQ_c88A9D9zzCHoeARotZJxnnrruT5V1bos3_4objtYvkxg_CFYYVgXNmt2KKFOgzPYFAS0bOs0QeNl5Z4JsTrB2W7BQf5z3_rQeM_OTaUDiv8tPztvsjY7Q2_QoJOhv37Smb8dkXYdVLycZ5X1B71vRWAHBiIHRm5F23B8O_U0lKcn3RiHjEdGIQiYHNj_JliF4-5bhQvRcTf0Lz93OxFE8rBlnAYXnqHCOiueodCE4F-ijBQYo_GlC6LJFzy3iPmzRS7ZbNvmZur5g2nSGGtKiP8-K_jwp-vOc6M9Tov8TZsTL5ow-sKcn3NAFXnSXdo-1Zg-zxlvyfnjHbXH8UsU9fbfXFfg48T2c1loCJak9mxHdmVraPUExE7Jc1pPt3tmdVb-0P_ew8gx59_TSsXDPJztgoN3uFbkgxZTEcH84Gh1flCS5m9DoniQ6OnNX7uVQWkh6cq8pS8PN8bIVkxs3PQtWSpyVHFEgKSlExV9AJaqq4dyJfHkXlPzda4jrXlgJwhlR171xNO_vuAG-LcKsBbs5cX4oVyUtFdWr2l-xODwxVe_U6bA2ta9F2jzYP25eD9nhx4fQlZUBmqt0vK5OzxcPPCv4C8XdXyjk4_J9PcLC5Qi7HPFvVxwabJL8EL2h2dY5mm2U1wu74mC0A76mt-RKZlp057x-Me58zqP9jubMyy949ukK_SfZ874z3b5r73NjCX9ryb-aMy4Xu_lS7q1F9y-JxksVeGHxe0sx_v6p4nruSr5TDOJ3xaCHo_Ti1JdNjJdqyXppQZNeD7AkiG4IsHQqNfI_IjYaU0I_VG50siBGZ7ZuEwdZj0tEX07QDdu1oazOCgaeV9xgXkzCeTWO5oVmvNE-rVCTIrS49ETv2q09M87dkcdKbCU12d9YLSP5N1DSUsgXD6dE7kpamhufJdODrxc050TS6ys1Q7TWjaQtAWvP2Qs4d0CncykEWFkSueteP5jk_5YX-2-dmnG026a3lDW6ZfWlmS6P6x38Zi3gv76of7fQ_WBNv7SL_14Zvi846fkEH1ypbehibfMv7h_Cq6uB4CQTpNffxBGtJcsaTZVTeNCeg3urowAP460kJYW1sC7gYewF9x7Glaioh7EZ0J4qhXnd9L2Tc1yTUdv2QJTqh0JiE_wGkgi31ziyl8ShE4e2Z6IgSVJ3ye21KCTkikPjvB7eePiO2NP5kOx2kirFDhRuS-K6uHV1TaGiR210DvODhtsAw5po09ePq17zgyXDm1P6ZXc9KAdJpvcwy3O4bRQT1RibZ68DFhKV06qAdk1jZafKCpuhOLMrDJgRTqqcwm0NRe3oZ1vXJzPqMJoZhIkBqMiBFvDYamuCQTMMnmGCGSacYaIZJj3FzBDrVtA8L-oOYsWxA-vajt9_sxcus31mobKeqTEXZc2PVeO0vvnl___-8L-__-v-14d_t7MRUtMjlGnbqp2pc5l3wEuthe1TyvpMYY9Em76CKRMF1lGr_AWqfE8LuKeNZEqzdnA3xM6jbypddyScWxRC11IUbYNa5zEAx4dSka5htU2rlgTlNNdQ1NoiTSXaQHp8qYSC-Z6SGhIFS3Gw-G2Ay9ICcegAUrKqJE6l252lsmXHTiEkCmAaREnsLLHlZNfeWFrH3gqZUxjgjGn4tSlraBOC87htjeJtye24OnWXQmg8gKED--Da1pDI8uBGl7LDapM5XKPh3JDuWmoSBF1bNRnEku6gPfCHRl2yNv3ju3uBbctGnD2ZOMK2DgCpkGOkonzU5ExTSbgVY5fby57IglZQcQUzLk8wlchFWRB9gpZUZ-3QzEmwz52BWNqaza44DOKrykVlLcGLGtqCRAtoCmjbz628kCt7qtMg7BlKyBXt_Zcrai3CGytJSa3Lln3iKGubrGDZMa1om4eq0uaPSsBMM0g0bJdOUD-znLqeiu4gK0taMJPGHVIdbGriBZIO85q_wq0LhnY-otGcVRQSLUqWO1FqUvUAlM-HrtHovbnHApA7E9VUbstW0lrSguV6HDH0WNPKJHY3WNJCtgLWcltCxXP3YYhBSVI5h5FEtQh1wA6T11Zh5hoMKDNr4ZqF1Z-kisoDhUc0bfnT5kkvnjaDaTOcNqNpM500p5TwlC2essUng6ds8ZQtnrK1r5JGzWTanAo1JRxMhZqymXKZMpnyWNtW6UyrMnel3JlM7ckAWQkUF8-wZKqLIIRTW177vpow2eJ7lNLyTyngMK4M24trtVFlrjVyENyi2JVh24rDbRz2rXTclW4D3DfIMIqhmA0t3uhDO6ym7gKpfbJpwFxS1U20bWnJcpdGlcqsK6s2GvvEPGqH43afott1h1EIVE1dd4lX6VkCgi2_Fm3bbR1SB6ebA8Uu-7ZwxnRNZdm3e_PYhtPvoVOoJrsdLeCOi8xlXb13Ntc8g7JNT5pn7NkCrWF0zQoJKUfjBh43gr4hBaTcdyQlyekhXVkhdL-IakibKKGpACapSGYW94TD9uHXDtaKNoXox9RCaUnaVULD7UMxi5c0Z7U0202o_myIpFAKobtelRNOJGRVDg-u5hzSFSI9iAcwGMBwAKMBjA0ID-kq6YC0A9b9KIex8h3WLSsD4A4IOiDsgMgBHQ2blJ-3RzuLo8vhr3nZAa8G36Z--CzkNyLNZqjvhbvaLvu7Xcl0P4Lm-5H3Ppk4xwJ_nMX4CcHs2y-M2i2n_QBwZdZWyn1Ph8zm9uJnnO3nkKdfUp6MuPKh5S-TrywvfWB5IsjwAWPxwc8b7D1P0819t69_qLQRZLy3R9e-OQg2DMXdLvz9wOzB2ZQXWtwvLz77KbLd6kB4Qz2cllSTgmgTHmAZnj-x-uAnDO_U74X3afZ7g8lZ9X9mw-8-WXjDaZyf_5zi8Pxr_qXI8Cb0Z_li5O0niT54PO_7h8PySYeJiv9-X_9A4yRI_unHDc9l7g8dEfxBSfa_0X_-C488fsClzh9T_IsS1eTDsB99gOj8edmLJwZm719vcJ1_xOvXcxXuzCrSdbx9HXnL9uFT8Tko1sGafKKfUYKjMIniOPi0_-wn2yBFebKN8Rr7URqGKfVpmq1zhFAS5Z_YZ-zj0F_7IUrDJAxW6wL5NEvybF1sSZyuvdCnJWF8ZWci5O4TU6qhn5Gf4DT5ZM_2K_u7aBhX9BnYXg9jL7r_JD_b31rJmp0yqmBKq4GMZprbH1T70n5V70X34A8imWgUYAUTpQL0z4YdCKeVbn-ozH57TkHned3PloGuIU1j-GWb_mdoPjWSf57-EtuO6X2TrXJRul-YcRdYS_GV5trDj3YmysOPbqqHz_j_AgAA__-i59-v">