Missed optimization to or disjoint
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
[GCC bug 127013](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127013)
[Godbolt](https://godbolt.org/z/Gfq3PTPdq)
With -O2, llvm should optimize to or disjoint:
```c
#define TYPE_PREC 32
#define TYPE unsigned _BitInt(TYPE_PREC)
TYPE
src_add (TYPE x, TYPE y)
{
if ((x & y) != 0)
__builtin_unreachable ();
return (x + y);
}
TYPE
src_or (TYPE x, TYPE y)
{
if ((x & y) != 0)
__builtin_unreachable ();
return (x | y);
}
TYPE
src_xor (TYPE x, TYPE y)
{
if ((x & y) != 0)
__builtin_unreachable ();
return (x ^ y);
}
```
```llvm
define dso_local noundef i32 @src_add(i32 noundef %x, i32 noundef %y) local_unnamed_addr {
entry:
%and = and i32 %y, %x
%cmp.not = icmp eq i32 %and, 0
tail call void @llvm.assume(i1 %cmp.not)
%add = add i32 %y, %x
ret i32 %add
}
define dso_local noundef i32 @src_or(i32 noundef %x, i32 noundef %y) local_unnamed_addr {
entry:
%and = and i32 %y, %x
%cmp.not = icmp eq i32 %and, 0
tail call void @llvm.assume(i1 %cmp.not)
%or = or i32 %y, %x
ret i32 %or
}
define dso_local noundef i32 @src_xor(i32 noundef %x, i32 noundef %y) local_unnamed_addr {
entry:
%and = and i32 %y, %x
%cmp.not = icmp eq i32 %and, 0
tail call void @llvm.assume(i1 %cmp.not)
%xor = xor i32 %y, %x
ret i32 %xor
}
declare void @llvm.assume(i1 noundef) #1
```
Contributor guide
Research direction
Start with the C reproducer and the linked Godbolt example, comparing the generated LLVM IR for src_add, src_or, and src_xor at -O2. Trace the optimization handling llvm.assume and the disjoint bitwise condition; done means the three operations are optimized appropriately without changing the shown semantics.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100