<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=http://email.email.llvm.org/c/eJy9WV1v2zoS_TXOCyFDlvylhzzYyc1FsOhN0RRJm5eAkiibN7LoFak4-fd7ZijZspP0drfFAoYiUSTnzMyZDyqpyV_P79Ugmj0rkZmNEjKrjbVCVkK9yM22VGK3VrUSl7d_CG2FrjJT1ypz5auo1cY862olLC20ztTKDqILkcnG0rAUdVM5jXeF1GVTq6EQ115UrfImU7nQTjgj3BpTTFmaHS1zyrogk1YN4sUgvByE3XUa-l82iJb041Hr6iZz4k5ll2kZi8GsHRciN00K-N8I0ne6PAzi_UtdlbpS4vFROlfrtHHq8XEQzfHDULmTr_bRT6HhBL9OAk9KWM7s8nfs1sK8rhjo_un70dMDy4wXpM2cpyatWnOemnj96Onhd8BrBZutqiX8OphdYHJmKusOyKfijqb60Z7dBbzrmroirIu74TcBXxFS3H_n-we-73vjl7BaJ53OOsgXZpPiLVDa9yAvmKCno8vOZqcqLDB6gde_CarHSBL3lp0sB5NLLNGVg59z9fIRFN55yp6fLP1MLPytwH6M6mNH_z-g_ancbbO5KW7_3UjOM_N_Jt-BegfifUC7Ln90Fgj-UcAhggOO3IAjNqDw-3kRb5h4g1xY_6zgbyJoF0yWITsMKaE3NmrHHnpjEY-9C5Fu4uO0eruWW9VH0SlxoSqn6pviz1o-a_fa26711ydZr3S1H-_vrV6wdK-H-KIKH7BEvDcmWdBtH_DJ6rtPkAId7z7Jl4M0vv7PWVlcrI2x6rMB_d9z0qWmCqhN1cvRi41paHY_eHvbWVV9dsAHc0dX-IkFnBvNghsweUbbHOpfacwWpRabz5xoqhovUCmBQ7ZLIlypcmqutrLKxe2Xm4V4UmprhXpW9atb00a6AmVWmJQMW0CFqUUb1Rrl5FKEBIluL0RMt76yalKjAwphf6mVdCq_I7lbaS3goGrjqWeIGS0_PHvyMbiWdNBL5lhZ1GYjNmrDWcPzVtz8qwfyYK4JkOAtAe3v3A5eiBDXK8-AbhRR7j3B1ZJJ0b4KOhftqdrGU887B672aJQaU2KSyp44Gg5lhR9Pisp-bNnjxte1zp7erzzXlXbQ7XTyaUHas52NEXSrDlHHINMrKJjfbiQYU_PMQpbUR51M-wsxdG1_NK_F8rlWz3ey5CmjYQjFlnHYm-bVaSffOlk78I4VqBSaSFrmdWfHeM34ljYL4iOBx7nuyFCiI6DX_q4fR9SXciOqLPeRcduIgv3gaLdwiM0pS1OOfoB_hx9Jwt8FSzlOAYcIuBCLYZvbOCntgUA7i9a3LH2bTHkl_5GYJYtZDj_OpKeL7nkFIwx4h6O5uqCI6qiF1jleHPdCDP7eN5J_vPUWqbPfbF9sTokhWgqeJG1Q-f64quw5RGTrOHQ3fLeMHy17h52HLS46Sh4t6dO0nXu85XFcoJnFxGM5x_UQZx4N6EB3MusIa2uio93fSSLdsaWfUxZWVMbRAahi1mYmVwHOXxuQwXaDMgWre8chuI-G3bpW6ojl2HxP0GnIifUwMvxGsrG2P_ad5nFy7g0-8MREwDFClXqjKxoX6SsHmRDLxtGZThU4D1aZEm8lg_mH-sCnuqbirE0T-xHlEcHK2ZrrgvVlwa1R41AbTP2Ks-InaCi2yPvaqvK1U59DzIv-uRj1uNqI7Cqm40MtxqWIA-2oIyOYXHsZxV5NTiuWEsuzLBs8muJEbUC9QZ-BcczcvG_-hGTB5W0V7GBoxLeSOb3cC8yFtGznlcbLuptqjQdmKsZN4Tf0PiGrGFJIuJ2hTLpS7rTawqJvjubB0dm8T8-v6_04yUJN26qK1u3WqqLvBFtNPQk1JNOQehjPOv-C9--_sc0WXgQtrLev72naDuUdYiT0naDwHc5bYVFLntOtLDSvVM-_lW-LbJPBibZoyvK17ZHQ_ZWPrb_IOKmq33Fr2z-xE7jTsp7T29ogr20gTrVNmrfPkErB_Cv5yErtXYx-7GWLJOk9TqvTZgUvVAJ51YiNrHSB-D5SjuRKkeuC-eAOCUAEgTBNLbIGwb-Bu9eSaLM1NYUpqEPtjarZGg4RbJX_dNPffMit3bVIEeCKsgtVrU4j3KIqgD2BxiEOKuWKIusCoB33jnuO7nMRsJG8a-DNxQ54dtqt_SveiSS_zKeP03HQVE-V2VUB3NW8BKuqYTg91rXfhlKEO1nMY6NInyzL8hkUXgWjCNC0C5LRZBysIjWZh6MwCueRP9bM185tLRU_rskrYGnSISiEB9qi_RNA4b8hA4-UczXd9PdK4iIp8DQN02w-HY9iNQ5H2WQ6zeeFpycX-65HJ2_WSvK3rQ3iZoMYkDVbojPe1f31vbcZnOFlEoGffByTkhv-Oga2WuKLIEwzZo9pA7YEL8EG8OdNqHb-gy-QGz0be55YU4bx9N5I5EQfrFdfvxCia_ahyo-sPPZWHk3Hk1GwmshxWoyzKI3j4lfN3N8ry-IoyWfjLMmiyaiYhIWM57NJkudJ2H7S4hzpfLBQQqI4SoYnlZTsb3XOpKTSWcvsiT8krjkp7CqvZ0FlGoZszc-uIB9A91qV6lnSoYHPJKd2mM1ns2BVpFmYxeE8nyTJr5qhv1eh4jgMZTqdjKbTSYi_6XiUzJLxeJq3ZvCFkqvVEqpmCxzl9Iun4i34ogtNZfH1lGLZWlYrjiSElVqjwTRcT0ol-cOt2Zet065CbEuZESVvkWl2tKWuTdWX0k7uqiUxC_gKR2WoB0Hb3tzTbmXfm-wV5FpWtbuSwplrSCZSasFx4nv9Nrn2-oV9NPYLX9tIcanwAdA_x3Hlvvbq1wa1uYsjNgmEU67m1qGzOol9RERanZavj7xwZ-onv-Cg847CEJs9g5REOLQNfH4v3do0q3WbKKgbMFvUYFQYnbUa-8Xk2bP8PM6TOJFnssG6-nz3d42ZZnfW1OX5f009bW1D_fbVBGybna3Pi2kSZ4XKs2QymaYSg7EajTM1HxWRkjI6KyWKhD2nb4FRVKmd4C0GnGrPfh2BPo_CKApHURiO4nE8H6oikqOomM5Ho3mejNLBOCRWlUPaZ4h4PKvPeUu4xeJlCWvYw0v0nXpVKXXuP16eOe1Kdd4_Hvb-TeGtTY0ueSFHgjxjeOeM7T91c8fN>53307</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            DSE removes some stores that are not dead
        </td>
    </tr>

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

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

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

<pre>
    We've come across an example where DSE is incorrectly removing some stores, causing a runtime failure.  I've reduced it to the following test-case:

```c++
struct VecDbl3 {
  double X, Y, Z;
  inline __attribute__((__always_inline__)) VecDbl3() {}
  inline __attribute__((__always_inline__)) VecDbl3(double InX, double InY, double InZ) : X(InX), Y(InY), Z(InZ) {}
  inline __attribute__((__always_inline__)) double operator|(const VecDbl3& V) const {
    return X*V.X + Y*V.Y + Z*V.Z;
  }
  inline __attribute__((__always_inline__)) static double CombineVecs(const VecDbl3& A, const VecDbl3& B) {
    return A | B;
  }
  inline __attribute__((__always_inline__)) double& operator[](int Index) {
    return (&X)[Index];
  }
  inline __attribute__((__always_inline__)) double operator[](int Index)const {
    return (&X)[Index];
  }
  inline __attribute__((__always_inline__)) double GetSumOfSquares() const {
    return X*X + Y*Y + Z*Z;
  }
  VecDbl3 operator-() const {
    return VecDbl3(-X, -Y, -Z);
  }
  VecDbl3 operator-(const VecDbl3& Other) const {
    return VecDbl3(X - Other[0], Y - Other[1], Z - Other[2]);
  }
};
struct Shape {
  VecDbl3 CenterOfGravity;
  double Margin;
};
extern VecDbl3 RefineVector(const VecDbl3* Vec);
extern VecDbl3 VMin, VMax;

inline __attribute__((__always_inline__)) VecDbl3 ChoosePoint(const VecDbl3& Direction, double Amount) {
 VecDbl3 ChosenPt;  // At '-Os', following loop isn't unrolled (at '-O2' it is, and SROA keeps everything in regs).
 for (int i = 0; i < 3; ++i)  // 'NegatedV' passed to 'Direction'; Direction[1] and [2] loaded from mem ([0] OK).
  ChosenPt[i] = Direction[i] < 0 ? VMin[i] + Amount : VMax[i] - Amount;
 return ChosenPt;
}

bool CheckShapes(const Shape& A, const Shape& B, double ThickA, const VecDbl3& InitDir, double ThickB) {
  VecDbl3 V = -InitDir;
  bool bFoundSmaller = false;
  bool bNextIsSmaller = false;
  double PrevVal = 1.0e+30;
  const double StartingThickness = ThickA + ThickB + 1.0e-3;
  do {
    const VecDbl3 NegatedV = -V;  // DSE removes the 3 stores into NegatedV.{X,Y,Z}.
    const VecDbl3 VecA = ChoosePoint(NegatedV, A.Margin);  // This call is inlined.
    const VecDbl3 VecB = B.CenterOfGravity;
    const VecDbl3 W = VecA - VecB;
    if (VecDbl3::CombineVecs(V, W) > StartingThickness)
      return false;
    V = RefineVector(&W);
    double NextVal = V.GetSumOfSquares();
    bNextIsSmaller = NextVal < PrevVal;
    PrevVal = NextVal;
    bFoundSmaller |= bNextIsSmaller;
  } while (bNextIsSmaller);
  return bFoundSmaller;
}
```

As noted in the code-comments in the above test-case, the three stores into `NegatedV` (`NegatedV.X`, `NegatedV.Y` and `NegatedV.Z`) are eliminated by DSE   But a reference to `NegatedV` is passed to the function `ChoosePoint`, which loads from that memory.  More precisely, the call to `ChoosePoint(NegatedV, A.Margin)` is inlined, and there is a 3-iteration loop that references these 3 values of `NegatedV`.  One of them (`NegatedV.X`) is not loaded, and instead is referenced as a register, and so that one is fine.  But the other two do get loaded from memory, causing a run-time failure.

The failure is happening when compiled at `-Os` (compiling at `-Os` suppresses loop unrolling in `ChoosePoint`).  If it is compiled at `-O2`, loop unrolling is done, and then SROA successfully keeps _all_ of the members of `NegatedV` in registers, so the problem doesn't happen.  (That said, as expected, the bug can also manifest at `-O2` in a different test-case -- our customer has reported encountering it elsewhere at `-O2`.)  I believe this problem is target-independent, but for reference, the testing I did was with the target `x86_64-unknown-linux-gnu`.

I've bisected this to [llvmorg-12-init-9154-g2e5801020822](https://github.com/llvm/llvm-project/commit/2e580102082293f9f80160bc86413e401c566d8f).  This isn't an area I'm familiar with, but FWIW, that commit looks fine to me.  I suspect it's exposing a latent bug.

The problem still happens with the head of `main` (FTR, I tested [llvmorg-14-init-16451-g5a4bf4c2b33f](https://github.com/llvm/llvm-project/commit/5a4bf4c2b33fcc329d74c9c251f50fa38759dd90), and it also failed).

As an aside, in tracking this down, I found a commit that looked relevant ([llvmorg-14-init-7877-gfbc0c308d599](https://github.com/llvm/llvm-project/commit/fbc0c308d599fe3300ab6516650b65b41979446d), which is a BasicAA fix).  Specifically, that commit changed the behavior, leaving one of the three stores in place.  Somewhat ironically, the store that remains after that commit is the store into `NegatedV.X`, which is the one that is actually safe to remove, as that memory isn't loaded from in the loop of `CheckShapes`.  If the root problem of this bug is in BasicAA, _possibly_ the work of that commit will provide a clue (although I'm not optimistic that it will).
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy9WFtP40oS_jXhpeXIsXPzAw8JHI7Qag6jYQQzvKC23U764Liz7jaBf79fVduJE2DO7M5oJRTsvtVXVV9d2qnJX8_v1SCaPSuRmY0SMquNtUJWQr3IzbZUYrdWtRKXt38IbYWuMlPXKnPlq6jVxjzraiUsbbTO1MoOoguRycbSsBR1UzmNuULqsqnVUIhrL6pWeZOpXGgnnBFujSWmLM2OtjllXZBJqwbxYhBeDsLudxr6v2wQLemPR62rm8yJO5VdpmUsBrN2XIjcNCngfyNI3-nnYRDvJ3VV6kqJx0fpXK3TxqnHx0E0xx-Gyp18tY9-CQ0n-Osk8KKE5cwuf8dpLczrioHu374fvT2wzHhB2sx5adKqNeelideP3h5-B7xWsNmqWsKvg9kFFmemsu6AfCruaKkf7dldwLuuqSvCurgbfhPwFSHF83d-fuDnvjd-Cat10umsg3xhNilmgdK-B3nBBD0dXXY2O1VhgdELTP8mqB4jSdxbdrIcTC6xRVcOfs7Vy0dQ-OQpe36y9Cux8bcC-zGqjx39_4D2p3K3zeamuP13IznPzP-ZfAfqHYj3Ae26_NFZIPhHAYcIDjhyA47YgMLv50W8YeINcmH9s4K_iaDdMFmG7DCkhN7YqB176I1FPPYuRHqIj9Pq7VpuVR9Fp8SFqpyqb4o_a_ms3WvvuNZfn2S90tV-vH-2esHWvR7iiyp8wBLx3phkQY99wCe77z5BCnS8-yRfDtL493_OyuJibYxVnw3o_56TLjVVQG2qXo5ebExDq_vB2zvOquqzAz6YO7rCn1jAudEsuAGTZ3TMof6VxmxRanH4zImmqjGBSgkcst0S4Zcqp-ZqK6tc3H65WYgnpbZWqGdVv7o1HaQrUGaFRcmwBVSYWrRRrVFOLkVIkOjxQsT06CurJjU6oBD2l1pJp_I7kruV1gIOqjbeeoaY0fbDuycfg2tJB71kjp1FbTZiozacNTxvxc2_eiAP5poACWYJaP_kdvBChPi98gzoRhHl3hNcLZkU7VTQuWhP1Taeet45cLVHo9SYEotU9sTRcCgr_HpSVPZjyx43vq519vR-5bmutINup4tPC9Ke7WyMoNt1iDoGmV5Bwfx2I8GYmlcWsqQ-6mTZX4iha_ujdS2Wz7V6vpMlLxkNQyi2jMPeMq9Ou_jWydqBd6xApdBE0javOzvGa8aPdFgQHwk8znVHhhIdAb32d_04or6UG1FluY-M20YU7AdHu41DHE5ZmnL0A_w7_EgS_i9YynEKOETAhVgM29zGSWkPBNpZtL5l6dtkyiv5j8QsWcxy-HEmPd10zzsYYcAnHK3VBUVURy20zvHiuBdi8Pe-kfzjrbdInf1h-2JzSgzRUvAkaYPK98dVZc8hIlvHobvhu2X8aNs77DwccdFR8mhLn6bt2uMjj-MCzSwWHss5roe482hAB7qTVUdYWxMdnf5OEumuLf2csrCiMo4uQBWzNjO5CnD_2oAMthuUKVjduw7BfTTs1rVSRyzH4XuCTkNOrIeR4TeSjb39se-0jpNzb_CBFyYCjhGq1Btd0bhIXznIhFg2ju50qsB9sMqUeCsZzD_UB77VNRVnbVrYjyiPCFbO1lwXrC8Lbo0ah9pg6lfcFT9BQ7FF3tdWla-d-hxiXvTPxajH1UZkVzEdX2oxLkUcaEcdGcHk2sso9mpyWrGUWJ5l2eDVFCdqA-oN-gyMY-XmffMnJAsub6tgB0MjvpXMaXIvMBfSsp1XGpN1t9QaD8xUjJvCb-h9QlYxpJBwO0OZdKXcabWFRd9czYOju3mfnl_X-3GShZq2VRXt261VRd8Jtpp6EmpIpiH1MJ51foLP78_YZgsvghbW29f3NG2H8g4xEvpOUPgO562wqCXP6VEWmleq59_Kt0W2yeBEWzRl-dr2SOj-ysfWX2ScVNXvuLXtn9gJ3GlZz-ltbZDXNhCn2ibN22dIpWD-lXxkpfYuRj_2skWS9B6n3WmzghcqgbxqxEZWukB8HylHcqXIdcF8cIcEIIJAmKYWWYPg38Dda0m02ZqawhTUofZG1WwNhwi2yn-66R8-5NbuWqQIcEXZhapWpxEeURXAnkDjEgeVckWRdQHQjnvHPUf3uQjYSN418OZiBzw77dZ-ik8iyS_z6eN0HDTVU2V2VQB3NS_BqmoYTo917behFOFOFvPYKNIny7J8BoVXwSgCNO2CZDQZB6tITebhKIzCeeSvNfO1c1tLxY9r8gpYmnQICuGFjmj_BVD4b8jAK-VcTQ_9s5K4SAq8TcM0m0_Ho1iNw1E2mU7zeeHpycW-69HJm7WS_G1rg7jZIAZkzZbojHd1f33vbQZneJlE4Ccfx6Tkhr-Oga2W-CII04zZY9qALcFLsAH8eROqnf_gC-RGz8aeJ9aUYTy9NxI50Qfr1dcvhOiafajyIyuPvZVH0_FkFKwmcpwW4yxK47j4VTP3z8qyOEry2ThLsmgyKiZhIeP5bJLkeRK2n7Q4RzofLJSQKI6S4UklJftbnTMpqXTWMnviD4lrTgq7yutZUJmGIVvzsyvIB9C9VqV6lnRp4DvJqR1m89ksWBVpFmZxOM8nSfKrZuifVag4DkOZTiej6XQS4n86HiWzZDye5q0ZfKHkarWEqtkCVzn94ql4C77oQlNZfD2lWLaW1YojCWGl1mgwDdeTUkn-cGv2Zeu0qxDbUmZEyVtkmh0dqWtT9aW0i7tqScwCvsJRGepB0La39rRb2fcmewW5llXtqaRw5hqSiZRacJz4Xr9Nrr1-YR-N_cLXNlJcKnwA9O9xXLmvvfq1QW3u4ohNAuGUq7l16KxOYh8RkVan5esjb9yZ-slvOOi8ozDEYc8gJREObQPf30u3Ns1q3SYK6gbMFjUYFUZnrcZ-M3n2LD-P8yRO5JnTrlTn_YtO74O730ctG52XI9TPmro8_6-pqa1tqB-_moCNs7P1-Vil0WyaZgrRGo1nxVRFYTRN5mqmRkk2Sc9KiSJiz-lbYRRVaif4iAGn4jN9jtVROIrCcBSP4_lQFZEcRcV0PhrN82SUDsYhcaYcEo4hou2sPmdIMLrFZAmr2MMkukq9qpQ6958mz2QDW9bnu79rrDO7M5Z9ztj_A0v-sdU">