[llvm] [InstCombine] Fold `(trunc X)` into `X & Mask` inside `decomposeBitTestICmp` (PR #171195)

Alexander Kornienko via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 4 10:26:34 PST 2026


alexfh wrote:

Hi @dtcxzyw,

we see a surprising interaction of this optimization and memory sanitizer, which starts complaining about a use of uninitialized value in the code looking roughly like this (https://gcc.godbolt.org/z/M1MKcznhx):
```c++
bool f(std::optional<int> x) {
  return x == 0 || x == 1;
}
```

IIUC, after SROA `std::optional<int>` is represented by an i64 with 33 bits, where bit 33 is the `has_value` bit and the lower 32 bits are `value`. After this commit LLVM translates the code above into two comparisons of lower 33 bits of this integer to constants:
```
  %0 = and i64 %x.coerce, 8589934591 // 0x1ffffffff
  %retval.0.i = icmp eq i64 %0, 4294967296 // 0x100000000
  %1 = and i64 %x.coerce, 8589934591
  %retval.0.i7 = icmp eq i64 %1, 4294967297 // 0x100000001
  %2 = or i1 %retval.0.i, %retval.0.i7
  ret i1 %2
```

And the problem seems to be that the comparisons take into account potentially uninitialized lower 32 bits. Is this a valid thing to do in LLVM IR?

https://github.com/llvm/llvm-project/pull/171195


More information about the llvm-commits mailing list