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

    <tr>
        <th>Summary</th>
        <td>
            Clang 19 generates incorrect code for vec_splat of the lower 16 bits of the vec_sum_u128 result on Z14
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
      </td>
    </tr>

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

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

<pre>
    Here is a snippet of C++ code that generates incorrect code when compiled with Clang 19 on Z14 with the `--target=s390x-linux-gnu -O2 -march=z14 -mzvector -std=c++17` options:
```
#include <stdint.h>

#pragma push_macro("vector")
#pragma push_macro("pixel")
#pragma push_macro("bool")

#undef vector
#undef pixel
#undef bool

#include <vecintrin.h>

#pragma pop_macro("vector")
#pragma pop_macro("pixel")
#pragma pop_macro("bool")

typedef int16_t AlignedI16LoadStoreVec
 __attribute__((__vector_size__(16), __aligned__(16), __may_alias__));

extern "C" {
  void ZVectorSumOf8LanesVec(int16_t* dst);
}

void ZVectorSumOf8LanesVec(int16_t* dst) {
  constexpr __vector unsigned short kVecToSum =
    { 1, 2, 4, 8, 16, 32, 64, 128 };
  const __vector signed int zero_vec = vec_splats(0);
  const __vector unsigned long long sums_of_4 =
    vec_sum2(kVecToSum, reinterpret_cast<__vector unsigned short>(zero_vec));
  const __vector signed short sums_of_8 =
 vec_splat(reinterpret_cast<__vector signed short>(vec_sum_u128(
 sums_of_4,
    reinterpret_cast<__vector unsigned long long>(zero_vec))),
    7);

 *reinterpret_cast<AlignedI16LoadStoreVec*>(__builtin_assume_aligned(dst, 16)) =
 reinterpret_cast<AlignedI16LoadStoreVec>(sums_of_8);
}
```

The above code compiles correctly with GCC 12 with the `--target=s390x-linux-gnu -O2 -march=z14 -mzvector -std=c++17` options.

Here is the LLVM IR that is generated when the above C++ snippet is compiled with clang++-19:
```
; ModuleID = 's390x_sum_of_lanes_test_081224_3_sum_routine.cpp'
source_filename = "s390x_sum_of_lanes_test_081224_3_sum_routine.cpp"
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
target triple = "s390x-unknown-linux-gnu"

; Function Attrs: mustprogress nofree nosync nounwind memory(argmem: write, inaccessiblemem: write)
define dso_local void @ZVectorSumOf8LanesVec(ptr noundef %0) local_unnamed_addr #0 {
  %2 = tail call noundef <2 x i64> @llvm.s390.vsumgh(<8 x i16> <i16 1, i16 2, i16 4, i16 8, i16 16, i16 32, i16 64, i16 128>, <8 x i16> zeroinitializer)
  %3 = tail call i128 @llvm.s390.vsumqg(<2 x i64> %2, <2 x i64> zeroinitializer)
  %4 = trunc i128 %3 to i8
  %5 = insertelement <16 x i8> poison, i8 %4, i64 0
  %6 = shufflevector <16 x i8> %5, <16 x i8> poison, <16 x i32> zeroinitializer
  call void @llvm.assume(i1 true) [ "align"(ptr %0, i64 16) ]
  store <16 x i8> %6, ptr %0, align 16, !tbaa !4
  ret void
}

; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write)
declare void @llvm.assume(i1 noundef) #1

; Function Attrs: nofree nosync nounwind memory(none)
declare <2 x i64> @llvm.s390.vsumgh(<8 x i16>, <8 x i16>) #2

; Function Attrs: nofree nosync nounwind memory(none)
declare i128 @llvm.s390.vsumqg(<2 x i64>, <2 x i64>) #2

attributes #0 = { mustprogress nofree nosync nounwind memory(argmem: write, inaccessiblemem: write) "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z14" "target-features"="+transactional-execution,+vector,+vector-enhancements-1" }
attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
attributes #2 = { nofree nosync nounwind memory(none) }

!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{!"Ubuntu clang version 19.1.0 (++20240810103829+866686180a31-1~exp1~20240810103957.18)"}
!4 = !{!5, !5, i64 0}
!5 = !{!"omnipotent char", !6, i64 0}
!6 = !{!"Simple C++ TBAA"}
```

Here is the expected LLVM IR code that should be generated for the above function:
```
; ModuleID = 's390x_sum_of_lanes_test_081224_3_sum_routine.cpp'
source_filename = "s390x_sum_of_lanes_test_081224_3_sum_routine.cpp"
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
target triple = "s390x-unknown-linux-gnu"

; Function Attrs: mustprogress nofree nosync nounwind memory(argmem: write, inaccessiblemem: write)
define dso_local void @ZVectorSumOf8LanesVec(ptr noundef %0) local_unnamed_addr #0 {
  %2 = tail call noundef <2 x i64> @llvm.s390.vsumgh(<8 x i16> <i16 1, i16 2, i16 4, i16 8, i16 16, i16 32, i16 64, i16 128>, <8 x i16> zeroinitializer)
  %3 = tail call i128 @llvm.s390.vsumqg(<2 x i64> %2, <2 x i64> zeroinitializer)
  %4 = bitcast i128 %3 to <8 x i16>
  %5 = shufflevector <8 x i16> %4, <8 x i16> %4, <8 x i32> <i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7>
  call void @llvm.assume(i1 true) [ "align"(ptr %0, i64 16) ]
  store <8 x i16> %5, ptr %0, align 16, !tbaa !4
  ret void
}

; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write)
declare void @llvm.assume(i1 noundef) #1

; Function Attrs: nofree nosync nounwind memory(none)
declare <2 x i64> @llvm.s390.vsumgh(<8 x i16>, <8 x i16>) #2

; Function Attrs: nofree nosync nounwind memory(none)
declare i128 @llvm.s390.vsumqg(<2 x i64>, <2 x i64>) #2

attributes #0 = { mustprogress nofree nosync nounwind memory(argmem: write, inaccessiblemem: write) "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z14" "target-features"="+transactional-execution,+vector,+vector-enhancements-1" }
attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
attributes #2 = { nofree nosync nounwind memory(none) }

!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{!"Ubuntu clang version 19.1.0 (++20240810103829+866686180a31-1~exp1~20240810103957.18)"}
!4 = !{!5, !5, i64 0}
!5 = !{!"omnipotent char", !6, i64 0}
!6 = !{!"Simple C++ TBAA"}
```

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWUmP47gV_jWsCyFDpGRZPvjgpStpoAYTpCd9mItAS88WpyVS4eJaDvPbA1KLJbtcXZ2kkRwKKEg0-fg2vuVjiWnNjwJgheYbNN_dMWtKqVZ_yFI0FTNG3-1l8bz6KyjAXGOGteBNAwbLA94iukF0g3NZADYlM_gIAhQzoDEXuVQKctOuPpYgcC7rhldQ4EduSrytmDhissRS4N9J3E6aEjBKwiAwTB3BoGino2X4FFRc2KfgKCwOfqU4qJnKSxTtXkiMg_rlBLmRCgfaFCja5a1aZIGSEMvGcCk0itYo3KFwjZKw-2t_0oiLvLIFYBRttSm4MLMSRZ-65Z6oUexYM9xYXWY1y5VENEWUtoIRpYguv0fb8Ceo3ke6l3JK2dNbUcABd1Knky376ZznM-UwsvYEORdGcfGWwbJ5t71T0rfMnVK-bq15bsDZwIUhSWbwunJxWnwmyYNkxRcjFXyFvKXFWcaMUXxvDWSZ55pmWatspvlLO0kSJ4JuHXXL7HK6Zs9uiWm3sHR_0WasEzwZUAIjSreIUowW3SrGJ8kL_PtXL_GLrX89pA9MgHYa0rQzAdE1LrSZsF3sxvx_jMtYfi6FNvDUKNzbja3wmV1gXUpl8LevkP8mv9gao2jXb8OOBybOeuoesXuk7uG8ssWRn038NKEpdvpGU6FngZ04Lgx-ASXdtJPlwjXTrphoRNNwbP4Vi0HnSopj-9C21pk8ZPFUb8_U1hTRdLDMaamACwOqUWCynGmDou0Nj7iYp2mv6cV53zKu9WWvUzrSabAS0fQtJa5V6EzJLPGB2_Eb7EZ0ezb7XeYNznvVRB_sZ46L6zDHiK5fEXQjA-m6FZNle8srw0XGtLY19EmGaOrjtY2ppQ_cwWvvF-NlDI5_PYkuart__lYCZnt5grYRdT1I4649Vc9t4_nL1kX4z21Cs7FefUd1wh4evv6CP_-97aFcD220aPumGUzoO27fhLm-aKq5a6otUUCWN7tetMG_yMJW8HnnUxTRhTfRx6E8ZJUrO5kBbbIwJZTGWeSXlLSGC5jlTYPoomWmpVU5ZAdegWA1dPzoj_OjXeH3TscFM6xiz9KanuOnoEbRGgJOULROUbQmScDT0TiJUbRO4uDgEsmPTsOInelERP3cpUSjeFNN9Q-s-Cbkozgf_bDp7Ml7K3J3vnhtjHJIA9dWm0bJowKtsZAHBYCF1M8ix0Ja8chFgWuopXpGNGXqWIOzDD8qbsAlChcsz0Frvq9guta1yAIOXAAutMwqmbOq7T8oDm81j8YoL9p1VETnrgpjvzOzwp1akbGiUBjRKBy3FUTn1DvEMF7hnFXVmUu0pfgJe6d_cqKr6lTPnNdmJ23rY-lKWbRNHQ1JPE205SRpu40b0H4Q94O0H7Tdx42igSoZyPyhfnK_pgJcoeOCG84q_gJq8Ja3I7qwg_t-dqn2P4-t2mPT6Jx2skazb8qKW1nKiryT4-QbiXk6opp7Ki40KAPuoIUL9S1JnBRnIW4k11J4sz2P1gNJjMMRm8Sz0aU9HCroitCUjZPVWfAq82HeJca1aX1DdF7r48x7ra3zDpoQZyz40j7fuOzxtd-DOh96bci1uvsugNF8aObalfhrlX0IjDd7nl1oIErMnjH3jns-CozX71Vo9a5EdSbuWf7tVs4-8qpSYKwS5_R9R67mFVNw23VdRnmv0Ih8X-vvVRQhxbX4H87Xq_zqFHxH_fu3FHxvQl7l4mt6DdcB3dU0V9QXm59ZmV3YCxkYxZqGi2NQM1O6DIh2iNI2PahvLIbl34JGSeNzNdjbwwFU4K4pA3na0badKcgbOyy9kHi6eABmrAI9UCC6MYoJzfypsCqAJ8itGzvgRzf9Je48DkCUTOS-BOmAtHeb3WueJLc8-V9OnVvy6SD_nTGGL-sAJT7Aag9_ZoeKHXXX8olrfJSEXX0h3ZueOXR7edGW6tGm6FpMOKLgEcU9P0TpY16y9mLqj2vrKi-Ox3LIxeb0vPlvn7f4AU7d5brdO9GRXuxdjPd-entvNDULUfqPvRXGtsASn0Bpl-lkOSOzEPubtsOaNKRxmJKQhFHqIP4mTZIkTUgasogE5E94asifI6LlfDEjHsTTifh4Kn7eaT4_970R8fxKV1kL3kjjTsd5uDMS0Q5OXDJIrhh84bWDgD3M_m2zXk80fO2CMQby8NRA7nB7j-jP_xrTpbRVgfcwQvcHqUbg_tDV0Q_U_oHaP1D7_wq177nJmTZT3D7FQZcQ_gp7j93Xofa3Z1vg7Vzd1-v_ZHBW8edj9qlR8w_M_oHZPzD7B2b_wOwfmP3_ErPfFauoWEZLdgcrsqBRvKCLRXhXrpI9sJQtSZTQIo1puFzOF_t5mBaE0Xy_z-_4qnMGJTFNSDhbJvM0ZGEaR2kcLckBxSHUjFczH3BSHe-41hZWJKRLQu4qtodK99_Z1cpRBXt71K5-cm30eZ_hpoLV8IH85ld1d38YvjthefCXiUo-gsIkcUhG95Pjb0xYgbaV6b6731lVrUpjGv-NnN4jen_kprT7WS5rRO-dUt3LFcA_IDeI3nvLNKL3nXGnFf1XAAAA__8R6m80">