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

    <tr>
        <th>Summary</th>
        <td>
            [X86,FMA] SPEC CPU2006/410.bwaves: suboptimal FMA generation
        </td>
    </tr>

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

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

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

<pre>
    The issue was noticed on Icelake CPU where the benchmark runs 1.38x slower when compiled with `-march=native` vs w/o this option.

There is a single loop that runs 1.5x slower, in `mat_times_vec` function from `block_solver.f`:
```
178 do m=1,nb 179 y(l,i,j,k)=y(l,i,j,k)+ 180     1               a(l,m,i,j,k)*x(m,i,j,k)+
181     2 axp(l,m,i,j,k)*x(m,ip1,j,k)+
182     3 ayp(l,m,i,j,k)*x(m,i,jp1,k)+
183     4 azp(l,m,i,j,k)*x(m,i,j,kp1)+
184     5 axm(l,m,i,j,k)*x(m,im1,j,k)+ 185     6 aym(l,m,i,j,k)*x(m,i,jm1,k)+
186     7 azm(l,m,i,j,k)*x(m,i,j,km1)
187                  enddo
```

The trip count `nb` is equal to 5.

This is the original LLVM IR produced by `Flang` for this module: [block_solver.orig.ll.gz](https://github.com/llvm/llvm-project/files/10514310/block_solver.orig.ll.gz)
`clang` invocation to reproduce `-march=native` behavior:
```
clang -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -disable-free -clear-ast-before-backend -main-file-name block_solver.ll -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=none -menable-no-infs -menable-no-nans -fapprox-func -funsafe-math-optimizations -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -funwind-tables=2 -target-cpu icelake-server -target-feature -avx512pf -target-feature -tsxldtrk -target-feature +cx16 -target-feature +sahf -target-feature -tbm -target-feature +avx512ifma -target-feature +sha -target-feature +crc32 -target-feature -fma4 -target-feature +vpclmulqdq -target-feature +prfchw -target-feature +bmi2 -target-feature -cldemote -target-feature +fsgsbase -target-feature -avx512bf16 -target-feature -amx-tile -target-feature -raoint -target-feature -uintr -target-feature +gfni -target-feature +popcnt -target-feature -ptwrite -target-feature +aes -target-feature +avx512bitalg -target-feature -movdiri -target-feature -widekl -target-feature +xsaves -target-feature -avx512er -target-feature -avxvnni -target-feature -avx512fp16 -target-feature +avx512vnni -target-feature -amx-bf16 -target-feature -avxvnniint8 -target-feature +avx512vpopcntdq -target-feature +pconfig -target-feature +clwb -target-feature -cmpccxadd -target-feature +avx512f -target-feature +xsavec -target-feature -clzero -target-feature +pku -target-feature -amx-fp16 -target-feature +mmx -target-feature -lwp -target-feature +rdpid -target-feature -xop -target-feature +rdseed -target-feature -waitpkg -target-feature -prefetchi -target-feature -kl -target-feature -movdir64b -target-feature -sse4a -target-feature +avx512bw -target-feature -avxneconvert -target-feature +clflushopt -target-feature +xsave -target-feature +avx512vbmi2 -target-feature +64bit -target-feature +avx512vl -target-feature -serialize -target-feature -hreset -target-feature +invpcid -target-feature +avx512cd -target-feature +avx -target-feature +vaes -target-feature -amx-int8 -target-feature +cx8 -target-feature +fma -target-feature -rtm -target-feature +bmi -target-feature -enqcmd -target-feature +rdrnd -target-feature -mwaitx -target-feature +sse4.1 -target-feature +sse4.2 -target-feature +avx2 -target-feature +fxsr -target-feature +wbnoinvd -target-feature +sse -target-feature +lzcnt -target-feature +pclmul -target-feature -rdpru -target-feature -avxifma -target-feature +f16c -target-feature +ssse3 -target-feature +sgx -target-feature -prefetchwt1 -target-feature +cmov -target-feature +avx512vbmi -target-feature -shstk -target-feature +movbe -target-feature -avx512vp2intersect -target-feature +xsaveopt -target-feature +avx512dq -target-feature +sse2 -target-feature +adx -target-feature +sse3 -mllvm -treat-scalable-fixed-error-as-warning -debugger-tuning=gdb -v -Ofast -ferror-limit 19 -fopenmp -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o block_solver.o -x ir block_solver.orig.ll
```
`clang` invocation to reproduce _default cpu_ behavior:
```
clang -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -disable-free -clear-ast-before-backend -main-file-name block_solver.ll -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=none -menable-no-infs -menable-no-nans -fapprox-func -funsafe-math-optimizations -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -mllvm -treat-scalable-fixed-error-as-warning -debugger-tuning=gdb -v -Ofast -ferror-limit 19 -fopenmp -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o block_solver.o -x ir block_solver.orig.ll
```

With `-march=native` the innermost loop is vectorized with runtime DD checks, but the vector loop is never executed because the trip count is small.  The execution time is spent in the scalar portion of the loop.  Here is the executed code in both cases:

<table>
<tr>
<td>W/o `-march=native` (fast):</td><td>With `-march=native` (slow):</td>
</tr>
<tr>
<td>

```
.LBB1_10: #   Parent Loop BB1_2 Depth=1
 #     Parent Loop BB1_4 Depth=2
 #       Parent Loop BB1_6 Depth=3
 #         Parent Loop BB1_8 Depth=4
 # =>        This Inner Loop Header: Depth=5
 movsd   (%rbx,%r8), %xmm1               # xmm1 = mem[0],zero
 movhpd  (%r14,%r8), %xmm1               # xmm1 = xmm1[0],mem[0]
 movsd   (%rbp,%r8), %xmm2               # xmm2 = mem[0],zero
 movhpd  (%rsi,%r8), %xmm2               # xmm2 = xmm2[0],mem[0]
 movq    232(%rsp), %rcx                 # 8-byte Reload
        movsd (%rcx,%r13,8), %xmm3            # xmm3 = mem[0],zero
        movq 224(%rsp), %rcx                 # 8-byte Reload
        movhpd (%rcx,%r13,8), %xmm3            # xmm3 = xmm3[0],mem[0]
        movq 216(%rsp), %rcx                 # 8-byte Reload
        movsd (%rcx,%r13,8), %xmm4            # xmm4 = mem[0],zero
        movq 208(%rsp), %rcx                 # 8-byte Reload
        movhpd (%rcx,%r13,8), %xmm4            # xmm4 = xmm4[0],mem[0]
        movsd (%rax,%r8), %xmm5               # xmm5 = mem[0],zero
        movq 200(%rsp), %rcx                 # 8-byte Reload
        mulsd (%rcx,%r13,8), %xmm5
        mulpd   %xmm1, %xmm3
        movsd (%rdx,%r8), %xmm1               # xmm1 = mem[0],zero
        mulsd (%rdi,%r13,8), %xmm1
        mulpd   %xmm2, %xmm4
        movsd (%r9,%r8), %xmm2                # xmm2 = mem[0],zero
        mulsd (%r15,%r13,8), %xmm2
        addpd   %xmm3, %xmm4
        addsd %xmm1, %xmm2
        addsd   %xmm5, %xmm2
        addsd   %xmm0, %xmm2
        movapd  %xmm4, %xmm0
        unpckhpd        %xmm4, %xmm0 # xmm0 = xmm0[1],xmm4[1]
        addsd   %xmm4, %xmm0
        addsd   %xmm2, %xmm0
        movq    192(%rsp), %rcx # 8-byte Reload
        movsd   %xmm0, (%rcx,%r12,8)
 addq    $8, %r8
        addq    %r10, %r13
        cmpq    %r8, %r11
        jne     .LBB1_10
        jmp .LBB1_11
```

</td>
<td>

```
.LBB1_32: # %scalar.ph
                                        # Parent Loop BB1_3 Depth=1
                                        # Parent Loop BB1_6 Depth=2
                                        # Parent Loop BB1_9 Depth=3
                                        # Parent Loop BB1_12 Depth=4
                                        # => This Inner Loop Header: Depth=5
        movq    376(%rsp), %r12 # 8-byte Reload
        vmovsd  (%r12,%r10,8), %xmm6 # xmm6 = mem[0],zero
        vfmadd132sd     (%r9,%r8), %xmm5, %xmm6 # xmm6 = (xmm6 * mem) + xmm5
        vmovsd  8(%rbx,%r10,8), %xmm5 # xmm5 = mem[0],zero
        vfmadd132sd     (%r14,%r8), %xmm6, %xmm5 # xmm5 = (xmm5 * mem) + xmm6
        movq    384(%rsp), %r12 # 8-byte Reload
        vmovsd  8(%r12,%r10,8), %xmm6           # xmm6 = mem[0],zero
        vfmadd132sd     (%rdx,%r8), %xmm5, %xmm6 # xmm6 = (xmm6 * mem) + xmm5
        movq    368(%rsp), %r12                 # 8-byte Reload
        vmovsd  (%r12,%r10,8), %xmm5            # xmm5 = mem[0],zero
        vfmadd132sd     (%rbp,%r8), %xmm6, %xmm5 # xmm5 = (xmm5 * mem) + xmm6
        vmovsd  8(%rax,%r10,8), %xmm6           # xmm6 = mem[0],zero
        vfmadd132sd     (%r13,%r8), %xmm5, %xmm6 # xmm6 = (xmm6 * mem) + xmm5
        movq    400(%rsp), %r12                 # 8-byte Reload
        vmovsd  8(%r12,%r10,8), %xmm7           # xmm7 = mem[0],zero
        vfmadd132sd     (%r11,%r8), %xmm6, %xmm7 # xmm7 = (xmm7 * mem) + xmm6
        vmovsd  (%rdi,%r10,8), %xmm5            # xmm5 = mem[0],zero
        vfmadd132sd     (%r15,%r8), %xmm7, %xmm5 # xmm5 = (xmm5 * mem) + xmm7
        movq    -72(%rsp), %r12                 # 8-byte Reload
        movq    %r10, %rcx
        movq    %rax, %r10
 movq    %rbx, %rax
        movq    %rdi, %rbx
        movq 392(%rsp), %rdi                 # 8-byte Reload
        vmovsd  %xmm5, (%r12,%rdi,8)
        movq    %rbx, %rdi
        movq    %rax, %rbx
 movq    %r10, %rax
        movq    %rcx, %r10
        movq 8(%rsp), %r12                   # 8-byte Reload
        incq    %r10
 addq    %rsi, %r15
        addq    %rsi, %r11
        addq %rsi, %r13
        addq    %rsi, %rbp
        addq    %rsi, %rdx
 addq    %rsi, %r14
        addq    %rsi, %r9
        cmpq    %r10, %r12
        jne     .LBB1_32
        jmp .LBB1_11
```

</td>
</tr>
</table>


There is extra GPR code in the slow version, but this is not the reason of the slowness (though, I will create a separate issue for LSR).

It seems that the main issue is the long dependency chain of FMAs, moreover, it is a loop-carried one.  I cleared `contract` fast-math flag from the instructions inside the loop and got **1.22x** speed-up (see [block_solver.nocontract.ll.gz](https://github.com/llvm/llvm-project/files/10514448/block_solver.nocontract.ll.gz) ).  The generated code seems to have shorter critical path on FP side:
```
.LBB1_32:                               # %scalar.ph
 #   Parent Loop BB1_3 Depth=1
 #     Parent Loop BB1_6 Depth=2
 #       Parent Loop BB1_9 Depth=3
 #         Parent Loop BB1_12 Depth=4
 # =>        This Inner Loop Header: Depth=5
 movq    376(%rsp), %r12                 # 8-byte Reload
        vmovsd (%r12,%r10,8), %xmm6            # xmm6 = mem[0],zero
        vmulsd (%r9,%r8), %xmm6, %xmm6
        vmovsd  8(%rbx,%r10,8), %xmm7           # xmm7 = mem[0],zero
        vmulsd  (%r14,%r8), %xmm7, %xmm7
 movq    384(%rsp), %r12                 # 8-byte Reload
        vmovsd 8(%r12,%r10,8), %xmm8           # xmm8 = mem[0],zero
        vaddsd %xmm5, %xmm6, %xmm5
        vmulsd  (%rdx,%r8), %xmm8, %xmm6
 vaddsd  %xmm6, %xmm7, %xmm6
        movq    368(%rsp), %r12 # 8-byte Reload
        vmovsd  (%r12,%r10,8), %xmm7            # xmm7 = mem[0],zero
        vmulsd  (%rbp,%r8), %xmm7, %xmm7
        vmovsd 8(%rax,%r10,8), %xmm8           # xmm8 = mem[0],zero
        vmulsd (%r13,%r8), %xmm8, %xmm8
        vaddsd  %xmm6, %xmm5, %xmm5
 vaddsd  %xmm7, %xmm8, %xmm6
        movq    400(%rsp), %r12 # 8-byte Reload
        vmovsd  8(%r12,%r10,8), %xmm7           # xmm7 = mem[0],zero
        vmulsd  (%r11,%r8), %xmm7, %xmm7
        vaddsd %xmm7, %xmm6, %xmm6
        vaddsd  %xmm6, %xmm5, %xmm5
        vmovsd (%rdi,%r10,8), %xmm6            # xmm6 = mem[0],zero
        vmulsd (%r15,%r8), %xmm6, %xmm6
        vaddsd  %xmm6, %xmm5, %xmm5
 movq    -72(%rsp), %r12                 # 8-byte Reload
        movq %r10, %rcx
        movq    %rax, %r10
        movq    %rbx, %rax
 movq    %rdi, %rbx
        movq    392(%rsp), %rdi                 # 8-byte Reload
        vmovsd  %xmm5, (%r12,%rdi,8)
        movq %rbx, %rdi
        movq    %rax, %rbx
        movq    %r10, %rax
 movq    %rcx, %r10
        movq    8(%rsp), %r12                   # 8-byte Reload
        incq    %r10
        addq    %rsi, %r15
 addq    %rsi, %r11
        addq    %rsi, %r13
        addq    %rsi, %rbp
        addq    %rsi, %rdx
        addq    %rsi, %r14
 addq    %rsi, %r9
        cmpq    %r10, %r12
        jne .LBB1_32
        jmp     .LBB1_11
```


Is there something `x86-isel` can do about this?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsW1tz46jy_zTkpQuXhXzLQx4Se3J2qmbrPzW75-z_LYUQspkg0ACyPfn0p0CyY1vIcS5zah9WNZVRoGmavtE_UKi1Yqk4v0HjOzReXNHarbS5WT_RxxU14irT-c-bP1cchLU1hw21oLQTjOegFXxmXNJHDvOv_4bNihsObsUh44qtSmoewdTKQjJIZ1uwUm-48VQKmC4rIXkOG-FWgCZDXFLDVihdKOrEmqPJENYWNojca3ArYUFXTmg1QMMFGt42P_8M8wkLFKxQS8lBal2BW1G3m3e8mxaROQjlZyqpe3Ci5PZhzZmfp6gV87yhMLr0FJnU7PHBarnmZlCgyRCl7Yz-vfkXfk2mM8g1lChdJIjMVQbJ9Bp-IjKTiMwFIvPviMwfEblG6SLaTO4gmQ3BPwkcP7SlLztjbreIzLrNd61Qs4YTAbqtLuBRJXEuJHBJgf68hItvDpxOuKSBywjo06VcfLPndMhlFLiMgW7LC7iUSUfF48BgAvTnJQx8cxlZzCRwmQJ9upSLby7DYloWU-g8XOW5jvrX3s3BGVEB07Vy3kFV5v1WWOA_airBaRifBIawvtuHojZiKRSV8OXLf36Hz9-gMjqvffRmPz2ve0nVMoSBNk2klTqvJUfpLaDx3VEseF4DKQfLJzReIDJbOVdZHxzkHpH7pXCrOhswXSJyL-V69x-ujP7OmUPkvhCSW0Tuk-E4GaXJEJH7vgl2KkOTIduJKNRaMxpi1WkwvF1KT_7I-IquhTZ90RvYAmYsAez1KzlsZ5OHyQjX6lHpjcJSqHqLl6oGzEvhsM6-A86FpZnkuDCcA2aSU4OpdTjjhTYcZ5Q9cpUDLqlQ2C8YK1pyOFqnlIBLw2W7GlzqnEuoBANcCYYlX3MJpPlFWFwJDrgsDC05rrRQjhu_Uq18M1dBHKWxUIU9alBUWcAFrSqjt9jnOfA_LS04LqlbYZ9US_EUhPCUSuOwGeT4iRttg5DUWs0EdRz8kpmojGZUhvGAi5wrbUoqcVGFJpQuKsMtN2seWCEyP_odcFFUmGnlDGUOpYuCWtfMbHStcqGWO9a-Z_8ulHA7oZX8CbhkWllnaua0wVQKarkNq9sIlWPnVWBRuiCAHTVL7jCrahDNboWDPGbfVXDqasMB0_V2nJCq6PY4u5W5M4-dHkTu2DaZxNotXcU4ZWWMuJlaFCWNslpFm5lhKelOUZR0FCNfV0yWtfyR_4j1VqZgq02sJytFZBYmc15q7xfdEYVd2ozabl-r4qyIqAzTcoudkJFRhnq377bXQrmuHRG5WxZKRBepKxZjVLmNEfG1UO9YfQbLhKNy2eVX6nUuTFcEvBE5f5QxhltL15GpWo31uOtaRdbZDimquF82vT0jyy3uMU4zmVBudoZpo98eB2NaFaKrLO_IcpNFPKysGNvSPO-fsBtgO02ymMf6tBYV7bGO66JPh2W57Q6QmypGa_JKdJeAt7qH2nIeId9Q4arHiKtVhhfcsVXEmhFHaz1zMoro21o-iuaZ1te7ycF7heJMqzU33agKhi1kbVe6ivYGQ53xpmjiQeRuMspElGE7LrJsy42gUjxFksvKb1BRdkKtKxax3X4m1tcXTb-xTBK8rC-o2DbaHNsksHHRfSUrI37B1Q9WRkU3uVER5yu990UX5X1mkPT2RM1H19toe7G10WS-yZQWah0V2EY2GUTu5FMszYck5LfAiPryysRywHrbtycXyaSbY4JElqfRjmUkZ-yid-OiSmSlXp8PkIirr6yLFiqlXme9W_K6IqGytJz1x2pPHDcc4lnfWh53grzPn1LApQcOvizn1GHLqGxKbrHlOebG-JLP4g01SvgSPudZvVxyg13tG1C6WOYZ4DXg_2vLy2aMFKVwkFwDLnTFVVkBLpaqZnjNjRVaoXQxGhDvzQXTUhucC7pU2jrBLOA197WmeOJYal0dNVjpWdE8N9bvb4uHh3_N5w-_3f7n08Pir9tv9-Rhfv_54faP31G6SADrYzSgAW9BGIhBoTguvAATPeS8oLV0wKr64R8s9A8WOsVC29kETzxMqBUPDUuuuPFq_yf4zgZf-PlX_7mlW3EQSnFTauuaI0lhYS9ve-ZpauVEyWGxALbi7NEiMoesdmF4Q7wfq7hHq3zLWe14DhlntLbNSevBwZCwYEsq5QDgzxVvyUNe8PP43op7MhUGBrsaqLQJNLoIrX7GAcBv7cGq2_PhOTCd-4VBpt0KmPex52zS_EznwddQ-um5wRz9lqP001_hUDeuO0Rm3mnCiakfgMh9GLMf2692RGZW6k136G5y32BekO1oOcd2H3y5u0sekmE4GCMpAHylxiv0i7eS7yOw4FUI-6QZ0tJ1KUd7SnJC2aWd7GnTDm2XeranHh1Qo3SB0k-7MeF48LP30Gbcb5zmPove7seO27GlXtscwOsWkbHJtojM_cssHHXOAZHxtixPT679jKEZpQsoeYnGd8NwYDj3mfSZ9arK96yT0etZ-5dn3gcTxYWvojOQ-AzkNcJb8XrW_uW88D_CKX5KdpNUz8wN23aOkT33Gc5-Og7fuNQ0bzm1T6ONlhfbGTJJEZkfS51GRE7PauN5hh9AyOjD5PUqfpfA_uWMjo_kTib_Yz2PImKPLtfzcPa_1nO_wP7lIj0_a4bGU8k4Inxovlwvww_SSy0vs-O4M65qsk7IXwduekYb-Qcm1pj8ueiXPzknPzkw_xn5ry_Kf5fl1pj8ybhffnI8jub5gfxpr_w0zwP_Eyt1udlnbuML6Ya9dKVe02bjaETa0w2P6WpVscewxew0d0q_U-ZwF4FDNL5LGm228Zh0QvBYzP7pj-lIL91ul0qu-3api7Llid5OQo7sTN6MpHn-o1HJaLabaNYRvyUZm2RnDO87R1SsrPZUe07JSTh8Vzz8v6_-jnvLateTnAELsWr0snIzJbtyE5FxU7IPqtWxEC89fvRpmZh2StV3MJt0qtl3MLvulLvvYJaQTjn8Cm5t1Xx5udw-u6hIp9GaIiEvRcW6DYtd9iO7UBh2st9klwcmlyTVdVHSPE9SYvN2lWfS97h3FkRmbeNtmJFcAyJ30N0MdwuZnQKIyErGr9rse1bSAyMmvdM0SxlHljLpMeosWuBebtTZRVY99sR32renvPgAA--1MomWo0mnBPhA1x-fsn2n7_QAxA_wnVPT0zNh8MGmDwXTLzX9KF5xv930lwTItKul6Xu0lLxk-unxNI2WppebvlOI_3p_3hfNJ6p7gz9P46bH02jZ93rT7xgeF2xs208VQmhHf3xkst9odoS9TII1dvRdqjRe1ebirZ59FHvHPh5EOahyI9I-rykXlyhmv6a4ds8phnW1e0h1aa5_UTFCsUPJTgv89mQNWm_urfEPqJII1QlJegmjrLqEKt-el7mLOSNU1_2w5AC8kHO4JD3tfTsu6ZyS-4bjU_3jb1ObmwK-dYbCv75-218ThEsGqTewu9_Z3280H6cq3dx1GE7t8wWEH6G4tT5A3ErXy5Uf9xk2QkpghlPHgYLlFTX-tfkmvdAGvvzxDZHro89gPzuwnJe2-SLccy-pUO2Y9nZDarWEnFdc5Vyxn8BWnkQXcP_7bbiSKbXhet1-QO6ar82l1hVm1BgRPoLnA4DPEG4_eQ5oMtxf6U2G8HxzV0i6bL4xb26Imhu7cNsolBU539_AAFU5LLXzmRiR22RAyLZ5BVtxnuO6CtcdnHc-0VV6N_nHfag78kD7_vw0Ya-4bq-ewk0i3d8ZtUbQsKJrDnaljeMGmBFOMCqh8srRCu6_gtdC3xX1ISA-__TA5filTRcJ913adGFu_6VNF8Weu7SJwNR33tq8gD9fmabXR4d9lwKX15WvR-d9cUA6OXx9M858c-nYSPgC0pwevp6Yoxc5vs0cl9TJs-5iZxct9vB4dBwHQ2fV0wM5Z10TtlNFSu5ec7-MOj8OZU4jHv0Wf-lBlxF_iVv5HGZ8s5WPD9njUHF2-BpzkphrdLzkmHZ61iNOrNwPMP8OgPIkK8SB5BkrHwba9KJc9wqtHyviAgz6Qfm7B3p-zKJ-Dfp8F_SMUEUQ6Cugp09ufxP0-S7oGaGKINBXQE-AX4w-2-cFEPoK9Nml-hUA9PyMo7NivxmA9oNPeL4yOwtAG5wWoJjhYHXJ3UqopQdR29kEC8ulB1GMKsg10Ey3ABKl91f5TZpfp9f0it8kk-loOr0mY3K1uhlf89E1pXTKGWez0WxWzJJkls2ydHp9Pc0nV-KGDEk6TMh0OCTTlAyyvJj6vnE2Hk4SRtBoyEsq5MCjooE2y6uAGW8mw5SQK0kzLm34c2lCFN80gBIRgsaLK3MTkFRWLy0aDaWwzj5zccLJ8HfW_z_zKe7-91s0XsAfXz_NYf7132Q4nCByP0qGg2xD1-HzOrB1Fj5MpdIj0h2yElpd1UbevBrXBVE9sAtL-W8AAAD__0did8w">