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

    <tr>
        <th>Summary</th>
        <td>
            `assume`s prevent deletion of dead code
        </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>
    # Rust example
`src` contains dead branches that are not removed:
https://godbolt.org/z/MabExKqET
```rust
#[no_mangle]
pub fn src(s: &str) -> bool {
 s.chars().next().is_none()
}

#[no_mangle]
pub fn tgt(s: &str) -> bool {
    s.len() == 0
}
```

```asm
src:
        cbz x1, .LBB0_2
        ldrsb   w8, [x0]
        tbnz    w8, #31, .LBB0_3
.LBB0_2:
        cmp     x1, #0
        cset    w0, eq
 ret
.LBB0_3:
        and     w8, w8, #0xff
        cmp     w8, #224
        cmp     x1, #0
        cset    w0, eq
 ret

tgt:
        cmp     x1, #0
        cset    w0, eq
 ret
```

# C example
The same example, translated to C
https://godbolt.org/z/Yn3Esa37M
```c
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

typedef uint8_t u8;
typedef uint32_t u32;
typedef size_t usize;

#if ASSUME == 1
#define assume(cond) __builtin_assume(cond)
#else
#define assume(cond) (cond)
#endif

const u32 NONE = -1;

inline u32 next_codepoint(u8* bytes, usize len) {
    if (len == 0) {
 return NONE;
    }

    assume(len != 0);
    u8 b0 = bytes[0];
    if (b0 < 0x80) {
        return b0;
    }

 assume(len != 1);
    u8 b1 = bytes[1];
    u32 b0_b1 = (b0 & 0x1F) << 6 | (b1 & 0x3F);
    if (b0 < 0xE0) {
        return b0_b1;
 }

    assume(len != 2);
    u8 b2 = bytes[2];
    u32 b0_b1_b2 = (b0_b1 << 6) | (b2 & 0x3F);
    if (b0 < 0xF0) {
        return b0_b1_b2;
    }

    assume(len != 3);
    u8 b3 = bytes[3];
 u32 b0_b1_b2_b3 = (b0_b1_b2 << 6) | (b3 & 0x3F);
    return b0_b1_b2_b3 & 0x1F'FF'FF;
}

bool src(u8* bytes, usize len) { return next_codepoint(bytes, len) == NONE; }

bool tgt(u8* bytes, usize len) { return len == 0; }
```

If `assume` is defined as a no-op instead as `__builtin_assume`, the dead code is able to be deleted.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysVl9v4rgX_TTm5arIsYGEhzwUCtJP85tZaWf2YZ8iO74p3k1sJna6TD_9ykkITaBTtBpUkeJz_5xz43tt4Zx-NogpWW7I8mkmGn-wdfqpQvG3NjNp1Y-UMA6_N84DnkR1LJHQJ0IfyYq6OicrCrk1XmjjQKFQIGth8gM68AfhQdQIxnqosbIvqAh_7LwP3h9d-MX2hO2frZK29HNbPxO2fyVs_1nI3enT9923IVn3VzfO90uMk-XG2KwS5rlEsnzq1o-NhMJA4MaSkAIIWzlfE7aGB8J3IK0tgcSbzhzcPD-I2hGWELaeGzz5_l_tMmMNdr_6nHGf5C4K_tnfRwEA3LxE06UCwp8IfwI6zXmuwYjCeVG4qlsJws9Vhv6Ty1c4RYRtYf7_zYZmbAyXqnYSAP5JgglZbk500HK28dK8wsWGcf4mHu9sz8Gv0lfH9tlRIIzTCe7Qt7FpwPF7j9bo38blV3GFUXDhNDCjp6K4TWAwYWzxayl23-GN_2rxt18747Ad9-O3A4ITFQ6rbAu-FsaVwqMCb2F7X-v9afjOCR5_nuTPh9Ta5GWjEAjfOq_CZp4fCN-9gyssfgZr49_CXR1_HFFhAY02Psk8NAnhm2uIs4BxdgU6_YoBCs8BvOQv4PHr1z8-786dFg2QwkIbBOFcU4XOz61RoSWzTDa69NpkU2hwxdLhh3Fu-Rmli7cMc2tcKwu-_Pal5QgP0USFNmWIH4zCxMpyq_BotQkDp0kIewT5w6MLe6AtArTTZT2eOboIfEo0l4kzMqnRN7VpWQzpg99kCradeBbaRmPROdrIr0lA0lZPR265accMv6LUWm2BnhJ6RTp8emKS_pTWLU7RLU7RiFM05RSKLGnWm_X02AroKdp343ob2K6AxNsWjnqY76fZJvJ2H8jL5OW931t1dkshGylk7yrMesuWZKe409bx7OSxe-XtP5aXSfZftha_JZKPRPKRyLcKs97yLLITfa2Tv6tzoiAbTMOGiPf919CxY03t2d_dTj7o1HOeqw4fPM62Xfv2jTotYpuwu4vcmXA0EkYBb51F_yugvX-0r2lFQYeLYBh_CoQDAcY-2CNo43y4HgoXrK_m6ao9_fwBu0tkUBsCCVliOLpkWC_Ro5rPVMrVmq_FDNMoZsuELSlNZodUUCaVErnkuJTreKGWMU_WKo7FarGOYznTKaNsQdc0idbBZ87kaiE5K7CIksVCJWRBsRK6nJflSxVOxJl2rsE0onEcL2alkFi69qbMWKWdQ_Vgj15X-lV4bQ1hobNmdRrcH2Tz7MiCltp5dwnotS8xfVsvB8caX9D4TqG2BmxxqcKsqct0cmRrf2jkPLcVYfsQuX88HGv7F-aesH3L2xG276m_pOzfAAAA__-4PSph">