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

    <tr>
        <th>Summary</th>
        <td>
            [LoopVectorizePass] Miscompilation of default vectorization vs no vectorization
        </td>
    </tr>

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

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

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

<pre>
    https://gcc.godbolt.org/z/4dfjo4z8v

Correct result is 0 0 0 0. Clang-15 started to have 0 3 0 0 which is miscompilation.

We bisected it to https://github.com/llvm/llvm-project/commit/cedfd7a2e536d2ff6da44e89a024baa402dc3e58, adding @fhahn who is the author of the change

Code:

compile flags `-O3 -msse4.2`

```cpp
#include <optional>
#include <string>
#include <string_view>
#include <iostream>

__attribute__((always_inline)) static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b) {
  return ~(((unsigned int)(a - b)) >> 15);
}

__attribute__((noinline)) unsigned char CheckPadding(unsigned char *data, unsigned int length)
{
    unsigned int padding_length = data[length - 1];
    unsigned char res = 0;

 for (unsigned int i = 0; i < length - 1; i++) {
        unsigned char mask = constant_time_ge_8(padding_length, i);
        unsigned char b = data[length - 1 - i];
        res |= mask & (padding_length ^ b);
 }

    return res;
}

__attribute__((noinline)) unsigned char CheckPaddingNoVec(unsigned char *data, unsigned int length)
{
 unsigned int padding_length = data[length - 1];
    unsigned char res = 0;

#pragma clang loop vectorize(disable)
    for (unsigned int i = 0; i < length - 1; i++) {
        unsigned char mask = constant_time_ge_8(padding_length, i);
        unsigned char b = data[length - 1 - i];
        res |= mask & (padding_length ^ b);
 }

    return res;
}

__attribute__((aligned(16))) unsigned char data_length41[41] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03};

__attribute__((aligned(16))) unsigned char data_length40[40] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03};

int main() {
 std::cout << (int)CheckPadding(data_length40, sizeof(data_length40)) << std::endl;
    std::cout << (int)CheckPadding(data_length41, sizeof(data_length41)) << std::endl;
    std::cout << (int)CheckPaddingNoVec(data_length40, sizeof(data_length40)) << std::endl;
    std::cout << (int)CheckPaddingNoVec(data_length41, sizeof(data_length41)) << std::endl;
}
```

If we apply back

```diff
--- a/llvm-project/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm-project/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -419,7 +419,12 @@ void VPlanTransforms::optimizeInductions
 
 VPScalarIVStepsRecipe *Steps = new VPScalarIVStepsRecipe(ID, BaseIV, Step);
     HeaderVPBB->insert(Steps, IP);
-
+    // If there are no vector users of IV, simply update all users to use Step
+    // instead.
+    if (!WideIV->needsVectorIV()) {
+ WideIV->replaceAllUsesWith(Steps);
+      continue;
+    }
     // Update scalar users of IV to use Step instead. Use SetVector to ensure
 // the list of users doesn't contain duplicates.
     SetVector<VPUser *> Users(WideIV->user_begin(), WideIV->user_end());
```

Then it passes
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWFtv47oR_jX0C2FDoiRbfvBDbMeogV6CnhPvo0GJI5snNCmQVNLNQ397MaRvcrw9aDe7RdEmhi4czjdXjWbEnZM7DTAjxZwUywHv_N7YmeBacfuSDiojvs723reOZA-ErQhb7ep6tDOiMsqPjN0RtnonbJWL5jeTv5evJFmS5CEeF8ZaqD214DrlqXQ0if8julBc74ZpQZ3n1oOg3tA9fwWa0CzsedvLeo8sB-lqc2il4l4aPbrG_wK0kg5q5Jc-QPRVlX7fVaPaHAhbKfV6Og1ba36D2hO2qs3hIMMFiEZMOIMiGwvWNGPB8xzKKU9YXnGeJ0zUGRQlYQvKhZB6R0meNHu-1_Rtb1BTvwcaHUhNE-7qPdc76LtEAOp3tRStA9oovnOUjJPhXzI6PDgH-YiRcXK9F2_Dr27b4wrLpK5VJ4CSbGFadBJXJHu8R3beSr37p8Ttq4S3b-yQxnkL_HAhh-N2y723suo8bLeElYSVXL3xr24rtZIaCJsSNsVIe1nTuEY7HTJPoI8srY12nmu_9fIA2x1sEeS8RWpPOTq-t1IhKJnMoxKUWvCd1fTvUYMb_qBDyekwsAXO7JFkjzQt8D47opDJ8ncs06ZnVN-MxR7ql6eYHtcKBCJhD4L7j3Yo0Du_R7yjCmeLaH9jG4G3kYGSbEkDYDE_rgxpSorl2ZgeQFDBggtsycXguLMxqF_f4_K8NVwu6JUUXCNsHn69IMS_vtQDdy8B626U-1ahd-R1RO5DVvetp0Mqbz2Af8HuyQJ5ojJsTD-IpqR4jNlxZr9JhwgVssyC-xFJ82ezgfr7M-cnpQ1hWWv57sBpjeWcKmNa-gq1N1a-A2GlkI5XCs4aIvT_U-2HphpXQXfCynQc0-1jxqExR03ylBRzPCyDmT33Jn9LEnTSJ5__xwRk3zxPljfP0yeEM8FwJj8jnEfg_5bYfRfwvxBDLGcHLnUI33W9cl5g45c91KbzWOSwzhFWxubkpnPoh5QtqJPvYJqPlGMrE8DOEkAL1StM_7bs9Juy08-XfXr5_ceMv6fAd3rgUrBPnft1sqwb-gaUt636Sitev9xt9YVsmrg0HA6xD76dYU6TjawIW_1quXaNsQdH2GpzeRevNk-K6wt1dDVBxJfrHN9In42dJyRP6DBPp4QtJpSwebxMGT3SXo0U9AYgOhKHmYN8h7UWXY1zjTu9K-Np8_RLzRW3680vHlr3V6hlC9gshdtQADW83d9GWLleYmjn3MF6g1dI_dAO_AG4ALt5ms-HJHuU2oH1hJUBCZnWT9csw7NHkTcOoXQdZkELlFug2hwbJNo5sA4HxSjdyQNmQdcK7oFypY4bvMGLqNwdcKmdBy5GPZpsaCg_6RcpYL1BzTWAcDFkKK885e6pPCHnZbeFVvEaHpR6duC-SGyWTjZfDUtRGsVmy0vdwS3lnPz0SuPnaKELMbn2wrWpZ7voM66Aj6rjFtCus3DKhIiJs7aSziNQRBQGnCZs4oNyXGoqulbJmntwoyulztAkW2yenh2EbhsHQ7x2hJUXryDytoLdqbhj2G6ooMXZuRdv3Hv0f92DphK7c-fADcQsE9NsygcwS8eTdDxheT4d7GdlyovppBwznk-KmlUwbbJiCqxKRZoClAM5YwljKWMsSdmETUdlycuac5EUJUyyyZTkCRy4VCN8lEfG7gbSuQ5mxXRcJAPFK1AufP5hDJ-WQCSMkWI5sLNQDapu50ieoIPdBcVLr8J3oz8a056LwRN3DruPP_W-2mBcBDS8U_48H0TCq7s8Ese1QWfV7Ten3_-QE_TGuhTs-kcAAAD__0PtaI4">