Issue 171750
Summary shl nuw + zext adds unnecessary masking
Labels new issue
Assignees
Reporter purplesyringa
    [Godbolt](https://godbolt.org/z/jGcYTYv3d)

```cpp
#include <stdint.h>

uint32_t f(uint16_t x) {
    if (x >= 8192) {
 __builtin_unreachable();
    }
    return (uint16_t)(x << 3);
}

uint32_t g(uint16_t x) {
    if (x >= 8192) {
 __builtin_unreachable();
    }
    return (uint16_t)(x << 3) | ((uint32_t)x << 16);
}
```

Expected behavior: `x` fits in 13 bits, so `x << 3` fits in 16 bits and the cast can be optimized out. Current lowering:

```asm
f(unsigned short):
        shl     edi, 3
 movzx   eax, di ; unnecessary
        ret

g(unsigned short):
        mov eax, edi
        and     eax, 8191 ; unnecessary
        shl     edi, 16
        lea     eax, [rdi + 8*rax]
        ret
```

IR recognizes shift as non-wrapping with `shl nuw`, so this is just a missed opt in isel.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to