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

    <tr>
        <th>Summary</th>
        <td>
            Failure to CSE loads/stores
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            missed-optimization
      </td>
    </tr>

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

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

<pre>
    # Loads

https://godbolt.org/z/55de88Ph6

Each `if` in `src` shares a common prefix of loads with the `if`s above it, but in the resulting assembly, the loads are repeated in the body of each `if` rather than being CSE'd as has been done manually in `tgt`. 

```c
#include <stdint.h>

typedef uint8_t u8;
typedef uint32_t u32;
typedef uint64_t u64;

u32 src(u64 len, uint8_t *xs) {
    if (len == 0) {
        return 0;
    }

    if (len == 1) {
        return xs[0];
    }

    if (len == 2) {
        return xs[0] + xs[1];
    }

    if (len == 3) {
        return xs[0] + xs[1] + xs[2];
    }

    return xs[0] + xs[1] + xs[2] + xs[3];
}

u32 tgt(u64 len, uint8_t *xs) {
    if (len == 0) {
 return 0;
    }

    u8 x0 = xs[0];
    if (len == 1) {
        return x0;
    }

    u8 x1 = xs[1];
    if (len == 2) {
        return x0 + x1;
    }

    u8 x2 = xs[2];
    if (len == 3) {
        return x0 + x1 + x2;
    }

    u8 x3 = xs[3];
    return x0 + x1 + x2 + x3;
}
```

# Stores
https://godbolt.org/z/4G171qhrW

Similarly for stores:
```c
#include <stdint.h>

typedef uint8_t u8;
typedef uint32_t u32;
typedef uint64_t u64;

void src(u64 len, uint8_t *xs, uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3) {
    if (len == 0) {
 return;
    } else if (len == 1) {
        xs[0] = x0;
    } else if (len == 2) {
        xs[0] = x0;
        xs[1] = x1;
    } else if (len == 3) {
        xs[0] = x0;
        xs[1] = x1;
 xs[2] = x2;
    } else {
        xs[0] = x0;
        xs[1] = x1;
 xs[2] = x2;
        xs[3] = x3;
    }
}

void tgt(u64 len, uint8_t *xs, uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3) {
    if (len == 0) {
        return;
    }

    xs[0] = x0;
    if (len == 1) {
        return;
    }

    xs[1] = x1;
    if (len == 2) {
        return;
    }

    xs[2] = x3;
    if (len == 3) {
        return;
    }

    xs[3] = x3;
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMV89zszYQ_WvEZScesbIxHDgkcdxDe-hMDj12BCxGrUCuJFL7--s7Col_BDvBXzvf1OMBL9p9T0hvH1g6pzYdUc4WD2yximTvG2Pzn1uSf6ouKky1zxkK-MXIyjG-Yvx-ODbebx0T9wzXDNcbUxVG-5mxG4brbwzXi0VFafprk5wWPcmyAZZwVbOEg-rCb2fLELhGWnIgoTRtazrYWqrVDkwNOlDD38o34Bs6lDuQhXkhUJ7hIxS9D3ghwZLrtVfdBqRz1BZ6HxLCyIAkbcjZkvRUvdeE-wxcdDZBK31DFnwjOygoID4-PzFcViAdNNJBQdRBZTqCVna91Hr_dlN-41nCZ3B68yzhw7d8i1GortR9RcDEo_OV6vysYeLptMjvt1RRDb3qfPq7hz5l4mE8JDCMCbw4mMzDYDI_DA7HXiCExce0T-agqQvL9M7D8H7nGGbAlm9FAACqBoappg6YWDGxAj5KCR9Lvrcd8ANhuMiWq1P2i3DxZ3A7xxYPnC1WN8PiJFhg-DBE8feQiO8gOUY4gfIWrGMkTpE_oAYJBKn-hxKYuvd9CjseMK7s643amMQXH_lGW3yjaPiwwPEUWjzSjrb5Rhm90w4nnMIujuziI_sV2OEkLqjm3cLOfA0FPHtjyU17Msx_ipfxX4397RTkWbVKS6v3UBsLboAT_1PnfDGq-tI6jxd2_CyKzyI8i8a7P63fPgoBSDua2kMnhhKUMmqlK2CXG-RTsENCfEgYddAVtst98S_YTqwyjIx6aZjHD2M8lIpDgrjS3ud9_irGr0z8B4nxzK2-MqdPV_Im-5_EdE1yNxn_JCa8soM3ef0kpktaGZt1VOWiykQmI8rjJfLFYpGkPGryTBacZ0lCBcUx53Vd8hSzmCgWMi7jOlI5cpzzJc-Q85TzWUEcy7nk85pncVUv2ZxTK5Weaf3SBo-PlHM95VmKMUZaFqTd618LxFY5R9Wd2XrVqm_SK9MxDEsV2TxU3xX9xrE518p5d8TzymvK11Lp3hJ4E17Bhxd5huvhORH1VucfnjrKN30xK03LcB2w3k53W2v-oNIzXL9ONIAMc33J8Z8AAAD__zMKVxw">