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

    <tr>
        <th>Summary</th>
        <td>
            Vector reduction on zeroed vectors not eliminated
        </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>
    Zig version: [Godbolt link](https://zig.godbo.lt/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:zig,selection:(endColumn:2,endLineNumber:34,positionColumn:2,positionLineNumber:34,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:'const+std+%3D+@import(%22std%22)%3B%0A%0Aexport+fn+count_external(ptr:+%5B*%5Dconst+u8,+len:+usize)+usize+%7B%0A++++return+count(ptr%5B0..len%5D,+0)%3B%0A%7D%0A%0A///+In+a+64+byte+vector,+we+consider+8+%22lanes%22+of+8+bytes+each.%0A///+This+function+returns+a+vector+where+each+lane+is+the+sum+of+the+8+bytes+in+the+corresponding+input+lane.%0Afn+sum_u64_lanes(a:+@Vector(64,+u8))+@Vector(8,+u64)+%7B%0A++++return+@as(@Vector(8,+u64),+@bitCast(a))+*+@as(@Vector(8,+u64),+@splat(0x0101010101010101))+%3E%3E+@splat(56)%3B%0A%7D%0A%0Afn+count(x:+%5B%5Dconst+u8,+char:+u8)+usize+%7B%0A++++var+cur+%3D+x%3B%0A++++var+accumulators:+@Vector(8,+u64)+%3D+@splat(0)%3B%0A%0A++++const+UNROLL_FACTOR+%3D+1%3B%0A++++//std.debug.assert(x.len+%25+64+%3D%3D+0+and+x.len+!!%3D+0)%3B%0A++++std.debug.assert(x.len+%25+64+*+UNROLL_FACTOR+%3D%3D+0)%3B%0A%0A++++while+(cur.len+%3E%3D+64+*+UNROLL_FACTOR)+%7B%0A++++++++inline+for+(0..UNROLL_FACTOR)+%7C_%7C+%7B%0A++++++++++++accumulators+%2B%3D+sum_u64_lanes(@select(%0A++++++++++++++++u8,%0A++++++++++++++++cur%5B0..64%5D.*+%3D%3D+@as(@Vector(64,+u8),+@splat(char)),%0A++++++++++++++++%5B1%5Du8%7B1%7D+**+64,%0A++++++++++++++++%5B1%5Du8%7B0%7D+**+64,%0A++++++++++++))%3B%0A++++++++++++cur+%3D+cur%5B64..%5D%3B%0A++++++++%7D%0A++++%7D%0A%0A++++return+@reduce(.Add,+accumulators)%3B%0A%7D'),l:'5',n:'0',o:'Zig+source+%231',t:'0')),k:52.020916986304115,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:ztrunk,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:zig,libs:!(),options:'-O+ReleaseFast+-target+x86_64-linux+-mcpu%3Dznver5',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+zig+trunk+(Editor+%231)',t:'0')),k:47.9790830136959,l:'4',m:100,n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4)

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

export fn count_external(ptr: [*]const u8, len: usize) usize {
    return count(ptr[0..len], 0);
}

/// In a 64 byte vector, we consider 8 "lanes" of 8 bytes each.
/// This function returns a vector where each lane is the sum of the 8 bytes in the corresponding input lane.
fn sum_u64_lanes(a: @Vector(64, u8)) @Vector(8, u64) {
    return @as(@Vector(8, u64), @bitCast(a)) * @as(@Vector(8, u64), @splat(0x0101010101010101)) >> @splat(56);
}

fn count(x: []const u8, char: u8) usize {
    var cur = x;
    var accumulators: @Vector(8, u64) = @splat(0);

    const UNROLL_FACTOR = 1;
    //std.debug.assert(x.len % 64 == 0 and x.len != 0);
    std.debug.assert(x.len % 64 * UNROLL_FACTOR == 0);

    while (cur.len >= 64 * UNROLL_FACTOR) {
        inline for (0..UNROLL_FACTOR) |_| {
            accumulators += sum_u64_lanes(@select(
                u8,
                cur[0..64].* == @as(@Vector(64, u8), @splat(char)),
                [1]u8{1} ** 64,
 [1]u8{0} ** 64,
            ));
            cur = cur[64..];
 }
    }

    return @reduce(.Add, accumulators);
}
```

On Zen 5, we get the following emit:

```asm
.LCPI0_0:
        .zero 64,1
.LCPI0_1:
        .quad   72340172838076673
count_external:
 test    rsi, rsi
        je      .LBB0_1
        push    rbp
        mov rbp, rsp
        vpbroadcastq    zmm1, qword ptr [rip + .LCPI0_1]
 vpxor   xmm0, xmm0, xmm0
        xor     eax, eax
.LBB0_4:
 vmovdqu64       zmm2, zmmword ptr [rdi + rax]
        add     rax, 64
 vptestnmb       k1, zmm2, zmm2
        vmovdqu8        zmm2 {k1} {z}, zmmword ptr [rip + .LCPI0_0]
        vpmullq zmm2, zmm2, zmm1
 vpsrlq  zmm2, zmm2, 56
        vpaddq  zmm0, zmm2, zmm0
        cmp rsi, rax
        jne     .LBB0_4
        pop     rbp
        jmp .LBB0_2
.LBB0_1:
        vpxor   xmm0, xmm0, xmm0
.LBB0_2:
 vextracti64x4   ymm1, zmm0, 1
        vpaddq  zmm0, zmm0, zmm1
 vextracti128    xmm1, ymm0, 1
        vpaddq  xmm0, xmm0, xmm1
 vpshufd xmm1, xmm0, 238
        vpaddq  xmm0, xmm0, xmm1
        vmovq rax, xmm0
        vzeroupper
        ret
```

Same problem occurs on ARM, and I assume other arches as well.

Doing math in `.LBB0_2` is unnecessary. I also wish the two constants here would be recognized as identical. And, if we wanted to get even more nitpicky, the `vpxor   xmm0, xmm0, xmm0` which happens in the TRUE and FALSE branches of the first `test` conditional could have been hoisted above the `test` conditional.

Should be:

```diff
-.LCPI0_0:
-       .zero   64,1
.LCPI0_1:
        .quad 72340172838076673
count_external:
+       xor     eax, eax
        test rsi, rsi
        je      .LBB0_1
        push    rbp
        mov     rbp, rsp
        vpbroadcastq    zmm1, qword ptr [rip + .LCPI0_1]
        vpxor xmm0, xmm0, xmm0
-       xor     eax, eax
.LBB0_4:
        vmovdqu64 zmm2, zmmword ptr [rdi + rax]
        add     rax, 64
        vptestnmb k1, zmm2, zmm2
-       vmovdqu8        zmm2 {k1} {z}, zmmword ptr [rip + .LCPI0_0]
+       vmovdqu8        zmm2 {k1} {z}, zmm1
        vpmullq zmm2, zmm2, zmm1
        vpsrlq  zmm2, zmm2, 56
        vpaddq  zmm0, zmm2, zmm0
        cmp     rsi, rax
        jne     .LBB0_4
        pop rbp
-       jmp     .LBB0_2
-.LBB0_1:
-       vpxor   xmm0, xmm0, xmm0
-.LBB0_2:
        vextracti64x4   ymm1, zmm0, 1
        vpaddq  zmm0, zmm0, zmm1
        vextracti128    xmm1, ymm0, 1
        vpaddq  xmm0, xmm0, xmm1
        vpshufd xmm1, xmm0, 238
        vpaddq  xmm0, xmm0, xmm1
        vmovq   rax, xmm0
        vzeroupper
+.LBB0_1:
 ret
```

LLVM emit (before optimizations):

```llvm
; ModuleID = 'main'
source_filename = "main"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux4.19.0-musl"

@builtin.zig_backend = internal unnamed_addr constant i64 2, 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
define dso_local i64 @count_external(ptr align 1 readonly nonnull %0, i64 %1) #0 {
2:
  %3 = alloca [8 x i8], align 8
  store ptr %0, ptr %3, align 8
  %4 = load ptr, ptr %3, align 8
  %5 = getelementptr inbounds i8, ptr %4, i64 0
  %6 = insertvalue { ptr, i64 } poison, ptr %5, 0
  %7 = insertvalue { ptr, i64 } %6, i64 %1, 1
  %8 = extractvalue { ptr, i64 } %7, 0
  %9 = extractvalue { ptr, i64 } %7, 1
  %10 = call fastcc i64 @main.count(ptr align 1 readonly nonnull %8, i64 %9, i8 0)
  ret i64 %10
}

; Function Attrs: nounwind uwtable
define internal fastcc i64 @main.count(ptr align 1 readonly nonnull %0, i64 %1, i8 %2) unnamed_addr #0 {
3:
  %4 = alloca [64 x i8], align 64
  %5 = alloca [16 x i8], align 8
 %6 = insertvalue { ptr, i64 } poison, ptr %0, 0
  %7 = insertvalue { ptr, i64 } %6, i64 %1, 1
  store { ptr, i64 } %7, ptr %5, align 8
  store <8 x i64> zeroinitializer, ptr %4, align 64
  %8 = extractvalue { ptr, i64 } %7, 1
  %9 = urem i64 %8, 64
  %10 = icmp eq i64 %9, 0
  call fastcc void @debug.assert(i1 %10)
  br label %14

11:
  %12 = load <8 x i64>, ptr %4, align 64
  %13 = call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %12)
 ret i64 %13

14:
  %15 = load { ptr, i64 }, ptr %5, align 8
  %16 = extractvalue { ptr, i64 } %15, 1
  %17 = icmp uge i64 %16, 64
  br i1 %17, label %19, label %38

18:
  br label %14

19:
  %20 = load <8 x i64>, ptr %4, align 64
  %21 = load { ptr, i64 }, ptr %5, align 8
  %22 = extractvalue { ptr, i64 } %21, 0
  %23 = getelementptr inbounds i8, ptr %22, i64 0
  %24 = insertelement <1 x i8> poison, i8 %2, i32 0
  %25 = shufflevector <1 x i8> %24, <1 x i8> poison, <64 x i32> zeroinitializer
 %26 = load <64 x i8>, ptr %23, align 1
  %27 = icmp eq <64 x i8> %26, %25
 %28 = select <64 x i1> %27, <64 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>, <64 x i8> zeroinitializer
  %29 = call fastcc <8 x i64> @main.sum_u64_lanes(<64 x i8> %28)
  %30 = add nuw <8 x i64> %20, %29
  store <8 x i64> %30, ptr %4, align 64
  %31 = load { ptr, i64 }, ptr %5, align 8
  %32 = extractvalue { ptr, i64 } %31, 0
  %33 = getelementptr inbounds i8, ptr %32, i64 64
  %34 = extractvalue { ptr, i64 } %31, 1
  %35 = sub nuw i64 %34, 64
  %36 = insertvalue { ptr, i64 } poison, ptr %33, 0
  %37 = insertvalue { ptr, i64 } %36, i64 %35, 1
  store { ptr, i64 } %37, ptr %5, align 8
  br label %18

38:
  br label %11
}

; Function Attrs: nounwind uwtable
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
define internal fastcc <8 x i64> @main.sum_u64_lanes(<64 x i8> %0) unnamed_addr #0 {
1:
  %2 = bitcast <64 x i8> %0 to <8 x i64>
  %3 = mul nuw <8 x i64> %2, <i64 72340172838076673, i64 72340172838076673, i64 72340172838076673, i64 72340172838076673, i64 72340172838076673, i64 72340172838076673, i64 72340172838076673, i64 72340172838076673>
  %4 = zext <8 x i6> <i6 -8, i6 -8, i6 -8, i6 -8, i6 -8, i6 -8, i6 -8, i6 -8> to <8 x i64>
  %5 = lshr <8 x i64> %3, %4
  ret <8 x i64> %5
}

; Function Attrs: nounwind speculatable willreturn nofree nosync nocallback memory(none)
declare i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %0) #1

attributes #0 = { nounwind uwtable "frame-pointer"="all" "target-cpu"="znver5" "target-features"="+64bit,+adx,+aes,+allow-light-256-bit,+avx,+avx2,+avx512bf16,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vp2intersect,+avx512vpopcntdq,+avxvnni,+bmi,+bmi2,+branchfusion,+clflushopt,+clwb,+clzero,+cmov,+crc32,+cx16,+cx8,+evex512,+f16c,+fast-15bytenop,+fast-bextr,+fast-dpwssd,+fast-imm16,+fast-lzcnt,+fast-movbe,+fast-scalar-fsqrt,+fast-scalar-shift-masks,+fast-variable-perlane-shuffle,+fast-vector-fsqrt,+fma,+fsgsbase,+fsrm,+fxsr,+gfni,+idivq-to-divl,+invpcid,+lzcnt,+macrofusion,+mmx,+movbe,+movdir64b,+movdiri,+mwaitx,+nopl,+pclmul,+pku,+popcnt,+prefetchi,+prfchw,+rdpid,+rdpru,+rdrnd,+rdseed,+sahf,+sbb-dep-breaking,+sha,+shstk,+slow-shld,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+vaes,+vpclmulqdq,+vzeroupper,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves,-16bit-mode,-32bit-mode,-amx-bf16,-amx-complex,-amx-fp16,-amx-int8,-amx-tile,-avx10.1-256,-avx10.1-512,-avx512fp16,-avxifma,-avxneconvert,-avxvnniint16,-avxvnniint8,-branch-hint,-ccmp,-cf,-cldemote,-cmpccxadd,-egpr,-enqcmd,-ermsb,-false-deps-getmant,-false-deps-lzcnt-tzcnt,-false-deps-mulc,-false-deps-mullq,-false-deps-perm,-false-deps-popcnt,-false-deps-range,-fast-11bytenop,-fast-7bytenop,-fast-gather,-fast-hops,-fast-shld-rotate,-fast-variable-crosslane-shuffle,-fast-vector-shift-masks,-faster-shift-than-shuffle,-fma4,-harden-sls-ijmp,-harden-sls-ret,-hreset,-idivl-to-divb,-inline-asm-use-gpr32,-kl,-lea-sp,-lea-uses-ag,-lvi-cfi,-lvi-load-hardening,-lwp,-ndd,-nf,-no-bypass-delay,-no-bypass-delay-blend,-no-bypass-delay-mov,-no-bypass-delay-shuffle,-pad-short-functions,-pconfig,-ppx,-prefer-128-bit,-prefer-256-bit,-prefer-mask-registers,-prefer-movmsk-over-vtest,-prefer-no-gather,-prefer-no-scatter,-ptwrite,-push2pop2,-raoint,-retpoline,-retpoline-external-thunk,-retpoline-indirect-branches,-retpoline-indirect-calls,-rtm,-serialize,-seses,-sgx,-sha512,-slow-3ops-lea,-slow-incdec,-slow-lea,-slow-pmaddwd,-slow-pmulld,-slow-two-mem-ops,-slow-unaligned-mem-16,-slow-unaligned-mem-32,-sm3,-sm4,-soft-float,-sse-unaligned-mem,-tagged-globals,-tbm,-tsxldtrk,-tuning-fast-imm-vector-shift,-uintr,-use-glm-div-sqrt-costs,-use-slm-arith-costs,-usermsr,-waitpkg,-widekl,-xop,-zu" }
attributes #1 = { nounwind speculatable willreturn nofree nosync nocallback memory(none) }

!llvm.module.flags = !{}
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzsXEtz27iW_jXMBkUVCYoStfBCspOprsq9udXp7kVvXCAJiohBgAZASfavn8KLBCXZsdOexdRMWmXheQ5w8J0XRDaSkuwZxjdRvovyu09oUC0XN38hSmokHj6VvH66-ZvswQELSTiLsi2I8t1_8brkVAFK2EOU30WwaJXqZZRtI_glgl-eyX6x12MWVJmWbG_60ggWESxerrRRtq14jT_XRHERwVtieouGUMxQh01tnUZwHcHbhjP1vUJUt6ZL1_CnxP852WGJHfZDd0fwliKmeT2TfQRvJaa4UnZHESwwq285HTpdhRG8xaz-Shj-99CVWETZNtPkey6JnjIb6Rsvh48svisk1DgpveiaTTXdlxOujdvoDj6Iyoml4kyqCO6kqiO4i2Ce3envZUK6ngtlJJxDaLpzCA2BPNMDk635g0923K5hEdxVfGDqHp8UFgzRCBa9EoaRnpHvIqgn5Xee61BE8DaCO4qtTHeDJM_YMPFFPXHt-e3Gj8BqECNHx0izSBYLTU1zsbST8zWv76bVW-iZz-43TQ5FcLdaRnBXPinN_YArC6oI7o7Y8GOS1FhEcFfY1UFIEcPSyWfHG9elKcgI7jCq2sUFtz9aojubgVlI-S1JtwjPeHdsscCOjBYVYrpmJqtWF-XQeba2IWRO2NhccSGw7DmrCdubrn5QjqJdnzlCOXT3w2p57zZVIHd-y-Qvt6RCC-jWHd_GnlbY7Q510MM2Pz_BaJkgzegVErd2WEnULdLAKdDEGG7fRUP2FGkKySlJ5_8FJPPss_sTTslXr0GpCdF4moH-CuKrFjnFcEL8Cd4PSGOhGkSgpadwLedDUVUN3UCR4kJenuCVI_KKPwroUtdDLn5Df_77929fv95_2d7-8e33gFJ6fXEW_1LVixqXw36BpMTGzJys2hqFyr0SOmKWYqJ3xbSZmsam5jP2b64zfTu77cs7us7kjNOxJdQeYlENYuJh8XT3KqOXVSX8EEaJsQANt1goksXiBUq39-bvm-iGnxl2rIzGcz03DxoxxjNZV_E2BuHHacQvzDTaYE2-lmqe3y2cNQhP7JppODNgZ6bB6KYzBr-2MrOs1CxJs8jXprK-80e_dUD4KOrJP6a-eVF5XpX-CAt_FqvlYuGc78-JTfbzeusrHkPgeqhwBIvFtq7tCc5Re2mo1_ZAqQ18chvosVnYx23tbx3u7VyYZPGfufhRheMdRB6ibJvDRQKTTbraFKssWaZpPrFavsLKVrSFTq5Qv70e63Y9oTiIdMeWbPusxMAedFxLqMLO9BfljHVJGBJPs7DYNn0rf2hFDjsq3nWYqW-MPs1oGHN6iyiVs-E17hDbUzwfS4SOXA9YzprxCVeDmofnhClMZ6MoKQUST7e8nhNVgnSzqQcsSi7xnV0BYftzWTYU7eVfBB-_9S7c_IikgJJSBiekGfFeR3Rus_G3CO5-xxQjib-Y4GUXKyT2WJdOxep-tYwpYcNJd3RVPxiNemYHLBxE-QELQWp8zuaVdCS9ko6k17KR9KVs5DLj-J9ORtI3q2cEd0b2O4d17QR98jcq6-Z1fV2uF5v1JimyJM1Wm3xzoa0aXGmS_JreBuTgT5X_2uQpdTYBWrLVn1ViP3rzydYEYECqGkTZHZhnbDZfM9latrOzbZ4GGgZeyNF0jq59h4tVgfHLwGZmwOdltgCitaYKAADWJoMwCxtzMJOBgWRaxfrO7cTnQeA3BhBYLYFOV8CYa4EjBj7PAgWIxgwLAt6AwoyWwOZVITWdUwGfUbmlSYAcYWAyKTMNaHqASKBaDOTQabK66EkTZqqzjAmYfAnYbEmH--BapgQuwgzgsyRwHoADG35fSvOlbAaMuQy4lg2BCG7fOPdnWRCIss9R9hlcZD_zg2ymkz95CM3x4_IcK4QL9ByQANUgDIJPlrZvPstfXhaeBf8sa_GY17TsYmYBspmTTuxez0lABHMN0Si70_MSgFgNfE9qmkaemtpP6cDt5XLmZBwlk0yAKZWwh3J3lcgcR_qfTRRAwwW4niSASCcI69uzefpfKHygjWp2d4H2WeA_n67_2bD-sl0Hij5ktwG73_-LgbrXoBly50H6JZ9Ih8gmQNbB9_oO2NAY2MA42c4GJNcGhMQso-xcTh67dlMm9s3v3DCrJGa2V5e5ip-HsOA8gA11zdt-S-gbA39jBnJnK_dYGXvVcEr5Udsq3BHjVuaOA8kuSraLr7f_-S25T2y_38riGQtuN59Og9KzQY8DqgEAa5gtk3QNi6xI1qvVOjP-aOZW7DyFpTK7lkSvVX9N1H5gR_XrbqdZTT39IFszreyD1o4fTIshFHYc-lJwVFdIqkddf-46HXOAxyMXNeiV0IctSK-hDMad5eZ8Dv2JCwDAqeu0J59_TyzsIAAwOule_aWFpBe-dHs9dPxQPw6rpZvy3HVQj33uutk6amLWIdDJLcErXV2bb2FZrJZ2eVqErCvdoIfUkYTjdyAHu4ICBCvQ2v1gFWC9e9ZourKkuWiS-boOfTdQ-jhnar9Tu0Qp6CO46M9XMyKoru2g5IxIKOaq60esGBGPWGE4wMoyxArvwSVWfnS9GwvHgzoD809O3s92h4tPSqBKkdXypA_4yUHM7yd9fa_JTGCeVgrNUZ0cradXaF1ZpBd-OzT1SMP3w6x4B5UAP48ef2cKcND2Yeh7LIJGgdWlcfqOOgx6wUuKO8CrahAScAa2v__LGDlWg98AknLoMOCqxQIgUbVYAiTBEVO6sFTuuLZjHVKtjsaiVeLPY5XowG1gDFdYSiSeFpoelRwciWyNHVRHbv0-YkoCE_Ud-UBrUGIgcMX3jDzjWjMkNWaKVIguwJYZI0wabVGPiClcA8WNbcUHzEDHBQaMqJ5UD096pOYUrZJXYbRKtBevWtCivsdsjCz_-P3Pz0YUX7Zfv38GpUDMyMDFoQ0RUmniWvk1kUrHoDqqRVRHXLQGLTpgUGLMQMuJ1ItFJT9gv6orE51gv7dOFJf-oSZNEyXbeO4hYnfY1kOAt_mIt3oIbXZesbCeqPEjH-ZEfOuHOpKZVXnBpsSv7XXuTQKVtE7lQ9zJuEjvVa76k3jO_IP8yXTU76GbvsMTjcM-1iGBIIB5h1OyuPOy_OEITU4pnnmleIafF71SPHdLftIHeqdzkh_gpKZz-WhfBd7irSK4mwcAV93W169__cvEzTpdKnGjzT3vFenIM7L3eTokPzeZlB50TB1lO_AvXg8U_3ZnU1K47hBhEVxHydbecd37BxLcAGgHaCjYC0FQI4UoeuKD8kNw3EXZFsc9XGtrnEHzR1fTeVWXVkvzJyZjIYVFlG1TWMRNkbgSM00rP321jL-n5s5oWocSpKfjMt0l5cAeGD8ye1m5XKSbRRJ3g6R2pv4sk3IgVBG2eCb7-xJVD5jZ2ynCrM3Xbht1uL5HdS1GFw3IagmM8iFK9gwUlpi5MlxI0vWUNATX95TvSfUmeiloEJV4IpnO18cH1Q_qvuM1fhM9CGJ4Rsye-Rd_2bRVyt5TMD6wI2E1GI4KlRRHybbGjc7Ea8nvKa8QNfuNlsm1izjPAgiMas7oE2CcsYFSEMHc6IGZDPPUXvhkiUvfR4sQwTwzm0JUc9P2uAAnQAp3HzfJGACpNMqN1XbUXTk7HxnB3FyBAMqRsfM_GZybwXusMMUdZkoPJazkA6ulXss0e-k3lfi5K3cmEgt1QHQwN0aep9n--g70nEjOAjq5vWx0NNZvoaF5zUXq7VoE88JQcFbwNRLrGePNu6aN3NLEXiQgSkGDpKoqjxJtJRbB_eqrCCmC7ZgbE1LYeyXNRmA1bjWZ3ce-E8mjuvyDlSbngieFLkJzTRhqYYDxLMD48gzjq-UlyF3MM8JxGp2uXlCJX4Zf8pHws3r5Cm5CzF8qdJTdGpXXfuAz0K6QMKIIouQZi3PVOxfV-3CfznE_CNz5_RRB2DkhnOiICj_OQGrFFmL_wEmtIXV2kUpSB16H6FIAikpsAJUuLZjTNEBJCiejNZPKz6SQZpM-OnhrV7-wPyUs7N3dAtX14lBoitrRhkI3vN0yQ73L3CKX4SLzYJEXon7tuPXk1VvPy_wkHVic9XQewx6PK1wFx1YK4ERuDnuS9WZWNfGb3lXhd3X1YDbBnmHyiwcD038gLAjfKiyYzvQZZm_2ZxBeODS4DMyBI6B3nVojlH0OzMloBm8ByWBAw4JER9ANxe4XrRkNw0jPe4FylN1aI6njvkuzYI0fXM3OxVvV2bnAbB4L2fWtZ-o9m2sJmzWYx60cK2tp7I8I04TUT1jPFm3pZLekAN5d_P_3_7VvC8M5Jq7g2MBncxFQnVloF7Bc_K51gdzCuxtt6qzdQnUN2HA8J6ntmof55kWHbMj8zM5l_8TOZW-2c9nczmVvt3PZaOeCRS_fx3e0HpmzbkNpxOp8kXkkPiT_a6FZls33-NbgLAujsyx_W3iWvRqfzfyi85rZda-ZfmSE_mo8lbwWc4fRlEXVifuowIBYiQHPgwU4Cw6Ws1ru9uyp6thIL842j1HRwARGVes2FSXb_JqMso8U0S9ah3cKrySqQlJd-scEKH4WCc2y-W6gL1gcZxI1Bi9v3R04_7d0TLu2luQZn9S0ZR8CrEDsEt1fL2SfXxS4C8dlK64YbmfelyN6L4bk70Cl7HE1UGSgCY6EUvd4AOONwBgwLp9YBRjXbqxE1QPocMfFUwQLxhm2fqnGFUUC_2qakriLJHerhZQSpBwUlg7ImbmRv1AkEEHYCNThuOdGlSIIo-wughBRGulAG0J7nRibhxpdp3-wMexvMFKDMM932UHm-eWSKPdcb31yBT3EFCjlx5iSfatimK_iaejhNBbgWMpTWDYmr5nqRCG6n7Ucw1pVh7X6Maw1YYU0HQrrh7Ij5_XZSg50VmNsPryHRpjSPFcTtvO-YipYyDRz5Dixsr8nNoN5htC-b0IbOsiW98rXj6Uv6QjKlTt-cCVRZY5YdfKyq07uvRF8wCeT3-pKk64qV0JSxWlePinMeB-0lToiCOp1f5SyDhpI13kmpk6fK6aCescPJQ7qskIUibiRj0JdNsuWNCrukHyQQecBCaKRG_dYaHMeu1wqHGLUZkbWH28j97JE0o-WonOlk3Q72zf-REhNDo-x4nFN_HETdugr4rYc7K5DleDhQXWdg3Cw5Y4faiJWyzKsOl7dERHlpjDeO3Z9RbvBlx8GVzAYcmWBG6yqlvhqU7VOA0Td-4WKuheDLwo2tkqMXVmi1umDLMu4xn1cCowezBtmprVFviDVgytq7ZUt9SS8UKXEcCxlY2m5SIPyNGLpKU-jD6OJOFgJPHqNCX4Qsu_ylYwTdnBLOBVrV5DogINiFZRH3TE1zSdOVyXR4Kz1nDiDYQ11p9iZHVOueNdTfPLVpp-6CFOFLyvzAtFtjA6nNFmksb0jHKtW62JniTyNw8nZIV1kuOLayipX15aCMDUOdXXD0RqKuCUGF3FVdb35bsxfWuOOK7Ocquur6oTMg2ox3vfCfLPHqrMtopManbH53UXjQMZ7rDpk6QatBvuxchoQ9nQDrS6b6ONZW4-N6s2aPLDDRoHYHts2bZXSySrZlvV5wx6p1sDDVlvey7Gi0RoLrpCaSI72pBJcyjOLEof2ZG6PTBf2rapFbDavQzpijlskasxiSWVMfthTCZoENtttBZa2pE0OdSbHHIR9_DNGsosHieN9L4w9jx-0VYgpRrHsfWmQWMZob6oHElcN8UWdfjq-VqVjejTTmEUCM0BhPC6feiRlXGOKnq40xSXFrL7WYT3ORXMgkR7VsWy5ULF_tNtIsa84a8wrGHHfG7UyNk3EKSxcROBbphjBt-iziAXeE2lekgk6-KGTDzE_YBEfzEM0Ux_jAUamNlkhpVyjOgpiIdIPsoU9743QBeJOwwRWPbdv8AWV2P8IGKvWvr4T9BFmX6CJ_VNCL3RX5m0c3aeMgkgs7J2IrUg7Ue6NrGSLnCkx1jjjWjUxGhsIq2pj_Ww17Oo7VNfHOqgPlE5VdeRxh7vYqY9pG5hJgnFteqwlutJhESq7zH4ZPZC8UXFDOTLikxLP5-hGhfZ7XMd7yktkJaBK2yFPtFbCyFMNGsGxjzZmqqn7B8JMiGK1hXZakWIdB8QVl0r6Hkm7GAmi2lmz6EwQEGtf3D8YTB5Jja2unayNeR5M1GsSg3mQnV4G2f84LwDByxapSQk683jCwrwF5X7aT3WWOn---FN9k9WbbIM-4Zt0nWdZkm02yaf2ZrOGBVovlxu8RGWBsqxOlilKcdGkm9V6ufpEbmAC82QNM5jkWZoslkWBYJblaJOgdbbE0TLBHSJ0YZbDxf4TkXLAN2meZDD9ZLJ6af6nEhAyfASmV2cD-d0ncaMnxeWwlzrFIVLJiYwiiuIb-8w4MCmPybY4M3eDuHbvf0jAuAKYko4wpHD9aRD0Zv7_oNgT1Q7louJdBL-YRzvsV9wLbl6Ng1_MqmQEv7hlH27gfwcAAP__fk6mcA">