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

    <tr>
        <th>Summary</th>
        <td>
            isSafeToSpeculativelyExecute seems not safe to use from SimplifyCFG
        </td>
    </tr>

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

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

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

<pre>
    The `llvm::isSafeToSpeculativelyExecute` function seems to be only safe to use when not speculating the result of moving instructions, since it may consider attributes that will get discarded during moving it later (e.g. dereferenceable). However, it can be seen that `SimplifyCFG:: dominatesMergePoint` tries to use it exactly in that way. Otherwise, like seen in the small snippet below, that can allow violating the semantics of attributes of the IR which, won't be valid after speculating is done (which is expected to discard those attributes).

The invalid speculation appears to happen here: https://github.com/llvm/llvm-project/blob/b592917eec407a01ef07334af5aafe6c8922c80a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp#L461-L465

This can be observed by running `opt -passes=simplifycfg this.ll` and observing that it returns IR with only basic block, which violates the semantics of `%4` being a conditional load in the original IR specification (%3 is not dereferencable after hoisting for `foldTwoEntryPHINode`):

```llvm
define i64 @julia_collect_81(i1 %0, ptr nonnull align 8 dereferenceable(8) %1) {
top:
  br i1 %0, label %L82, label %L85

L82:
  %2 = load ptr, ptr %1, align 8, !dereferenceable !1, !align !1
  %3 = load i64, ptr %2, align 8
  br label %L85

L85:
  %4 = phi i64 [ %3, %L82 ], [ 0, %top ]
  ret i64 %4
}

!0 = !{}
!1 = !{i64 8}
```

What seems the best course of action to fix this pass mis-speculation? I think LICM and LoopRotationUtils may share same issue, but SpeculativeExecution has a private `AllPrecedingUsesFromBlockHoisted` check that it appears to have been using to avoid this issue (present since that pass was introduced in 154eb5aa1d9c829715d13c9a047d4498be4d2e2a)
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUVt1u4zgPfRrlhmhgK3ZiX-SiP5NvCnS-Hcx0sJcDWaZjThXJkOSkefsF5aR1Z7ELLFDUMWUdkoc8olQItLeIW1HeifJhocbYO789xl9WhX7RuPa8fe4RxDoz5ngQq1uxuqXwXXX47L4PqEejIh3RnD-9oh4jinUG3Wh1JGchIB4CRAcNgrPmDEF1yO9jQDj1aMG6COEKY_cQewSPYTQRXAcHd2Qj2RD9mCCDkPcQyGoEinBQZ9DOBmrRg4rRUzNGDBB7FeFExsAeI7QUtPItttCOnvGusBGMiuhByAqX-yW06LFDj1ajagwKWS_hszvhET27pQhaWc4lINrJiVhn3-kwGOrO97v_TfRA6w5kVcTwBf0evzqykWmJnjBcs6cI-Kp0NGegC9ZJnZfwR-zRnyggezT0cnGWvkEIB2UMBEvDgBEaNO7E36XtHJsyxp3gSG5GZ8CDspF0YEZnJLkuLT9-g1NPumeck7NCbhgYjspQC6pjfuYFogCts8icpW1swNcBdcSWc7uQDbF3AWfumEyRPYjsdvrPTUV28vKG7yyoYUDlE009_7bQo0dmtY9xCMyw3Am521Psx2ap3UHIXWrN6XEzePcLdRRy1xjX8KOsZZ1vEHWRbVSWY5dtVqtCdaVSHa51VUupq0zNcIj3PXtlQ-f8IQi5-xHJ8HNW7KUeBiFXT8U6v3kq1uXH7Chcm8U1Af0RW2jO4EdrmUWxztwQ4WZQIWAQq4dwwdUdF43C0hhuGWXby_6pmipy43iMo7chlY5iP0mrUYE0NMbpl1TKVJypE5IifmsEsc6ELAt20iCDK1ZSS1wEZcA41V6bznnaExsfv6VSUUd6KpaQlZDlinuAhfyuH5bPpXl6RyF1Tuc8e-2caZ9P7pON_vz18-P_XYsplppLO6OQjekvFSWZWuzIItC6AFFkv0ZD6qd2xqCOP6tcyIpyELLMOP8herDO2tEYUIb2Fqq_67uqhKx5S56em7vJT3TDWzAAjYcZrlENGn57quRv7x86gJffMYQsJYjVw8TrEP01xMn3_TVE_ilk_lugbMovS9OHyfCOvXrHpnUxw5Zz7Pd8_jno8mPQRQIeeppIL--StykUZgBE-ZDeyjvILubohmS-oHiM02butsnX5uFDoWWeJTdC5lyCt1WZ5zM7Y1Tvi9fumCP9yfq4zJweocEQQbvRB0xH3zSTooOOXpPIgOUHBwo3sxNIrHbwyMv2BZ4e778kDT45N3xzMX2QjoI0ekKvPEJQBwQKYUxHdjNGmM3FaSqy314FUDB4OqqY5umtMV89amzJ7n8EDDvvDncs38-sGGxZmrpH_fKm-w9n45ETRAtjSEeDA3V01E55pWhYnYPHgDZeJmbCSTmfVACy0bt21JiEnpcFNqVSeVvrStabvGzzla5VVmzaoqirBotWolRC1ot2u2rrVa0WuM03cl1mZZZVi36rm0zWeb4udCfzTa1xg7JbrzCX9aaVebagrcxkkdX5Ol8XK1ktteo62ZR1UeUqL7paFBkeFJkli37p_H6RUtnmWVWVxSL1bUh3FSktnq60S766-G06_5txH0SRGQoxvMNEiga3_3ZxuTROupDMbimddweYnfqL0Zvtfx5FKU6eH5dEjlv5VwAAAP__RMYJXQ">