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

    <tr>
        <th>Summary</th>
        <td>
            [SimplifyCFG] Failure to convert switch to arithmetic due to sinking limitation
        </td>
    </tr>

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

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

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

<pre>
    From https://github.com/rust-lang/rust/issues/129131.

CE: https://llvm.godbolt.org/z/6GbhPjhzd

```llvm
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: nonlazybind uwtable
define void @bad(i8 %0, ptr %f) {
start:
  %y = alloca [1 x i8], align 1
  call void @llvm.lifetime.start.p0(i64 1, ptr nonnull %y)
  switch i8 %0, label %default.unreachable [
    i8 0, label %bb4
    i8 1, label %bb3
    i8 2, label %bb2
 ]

default.unreachable:                              ; preds = %start
  unreachable

bb4: ; preds = %start
  store i8 4, ptr %y, align 1
  br label %bb5

bb3:                                              ; preds = %start
  store i8 5, ptr %y, align 1
  br label %bb5

bb2: ; preds = %start
  store i8 6, ptr %y, align 1
  br label %bb5

bb5: ; preds = %bb2, %bb3, %bb4
  call void %f(ptr noalias noundef nonnull readonly align 1 dereferenceable(1) %y)
  call void @llvm.lifetime.end.p0(i64 1, ptr nonnull %y)
  ret void
}
```

We would normally expect the stores to get sunk, and the the switch to be converted into arithmetic.

However, this does not happen due to this special case: https://github.com/llvm/llvm-project/blob/fc1b01963857b5c04980c713145a71d6b858ad8a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp#L1997-L2017

In this case, SROA does not apply because the alloca escapes.

Also, since that special case has been implemented, SROA *has* gained the ability to speculate loads and stores across phis and selects, so we can probably remove this now.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykVlGP46YT_zTkZZTIYOPYD3nI7v5z_0onteq16mOFYRJzi8ECvNnsp6_AyW6yXd31dFGEsWFmfjO_GQYRgj5YxA3hd4Q_LMQUe-c3Vj9queicOm123g3QxzgGUm4J2xG2O-jYT91KuoGwnZ9CXBphD-c5YTsdwoSBsB1lLS3pihQPpNjO4_3_SLl9p8-Yp2F1cKpzJq6cT5peCNvVn7r-t6_9i7qWJ3Ux_5PQ_CkKf8AISkRhxMlNEUj5AIQxXA6k3OJyZOuClNuS5SG90tvXNKurPCz164SyhpRbyprlvinOM5s_1Rfxulp-SdsYu4ESvR4NXmA8N_XfdbWc7KN1R7s02k7Py4OdXqXOY3kHu8nKqJ2FbYw-BQiss0a8nDptFUzHKDqD83aFe20RnpxWQKqiE4qwRjdAGC8Iu4cx-jTfE9YCWd_NQiEKH1Pc8xukDacMUxjjpADC7yg8g24If0hKhNEHC_SyXQpjXi1m1ozeY9QDrrLm1VgkEHUF9ALBOmsnY7IlwtqLpnDUUfZwhdeIDvM2hXsxmbiarEch--RxwnWRhCR0K9F11c0qfbda3qyyd6tnEiC5fEXHBzASH9_8JQpHjyqcqedzvM_WrzVdGUroy-13ZEN0HhP66orb0wcUdf7aN35rqPyuBz_m0Ssq_jOo2A-4X_-MIf6hoQSA3V8y5TKrPsj5XE3NnNXCaBHAuskq3L9muUehnDWnCyxQ6HGPHq3EzDtraC7I22r4Rl2hVf-9qjzGrObs9vrh3Zl5HY6_EI5uMgqs84Mw5gT4PKKMEHuc4x0gOkjHWZjsY461VXk175gLODroEKSzT-gjKtA2OhBex37AqOXN0f9_d8Qn9ElT7HUA5TBFMEIvxhEtqAmTvrwWRpRaGJAi4L8bxk0Dyo1gfixH776iTD2oM64jbLeXtCtoW5cNX3dcFlXbFHJNS1pxsaaq7hreCNWIKz06yf3hhQ1754fUxv6M2qTnFz2MRu9P97tPKzmOhJWfaduul59ZQdfXnv5iZy8yenYPX37_dfvmrhhHc4IOpZjCHMzz6YtBihHDTdC2JrikImgr02YRb2IDvQjQIVpI2HBAG1G9miRs24tA2BYOQluc2ROdNjqeUqiTpsmIiGCcUCETfKZeSO9CgDG5kT-jQRlDhuLgiCCFhdG7TnTmBB4H94Sz09YdVwu1KVVbtmKBG7pm5bpta8oX_YYr3u6rkgrG9ly2nDblnjc1XwvBkTdqoTesYFXR0LpoaVnyleC8rQrKVK1wLWlDqgIHoc0q14nzh0W-bmxoUfF6vcjVH_J1hrFBh4Bq6caoB_0iUmdNTZc_LPwm50s3HUIqOR1ieFMYdTT5RnRFOOEPsBPaTD4n6Tnjr8rgLekviRy0fdT2AEYPOmbji8mbzQ-n8tt1anbxacP-CQAA___20OB0">