llvm / llvm/llvm-project

[InstCombine] If a is in (0,1), then (2 >> a) to (2 - a) and (2 >> !a) to (a + 1)

Open
#207,089 3 comments 0 reactions 1 assignee Claimed by @iamaayushrivastava View on GitHub
llvm:instcombine missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

[Godbolt](https://godbolt.org/z/5nccedzj1)
```c
int
test1 (int a)
{
if (a < 0 || a > 1)
__builtin_unreachable ();
return (2 >> a) == (2 - a);
}

int
test2 (int a)
{
if (a < 0 || a > 1)
__builtin_unreachable ();
return (2 >> !a) == (a + 1);
}
```

Should optimize to return 1 with -O2

```llvm
define dso_local range(i32 0, 2) i32 @test1(i32 noundef %a) local_unnamed_addr {
entry:
%or.cond = icmp ult i32 %a, 2
tail call void @llvm.assume(i1 %or.cond)
%shr = lshr exact i32 2, %a
%sub = sub nuw nsw i32 2, %a
%cmp2 = icmp eq i32 %shr, %sub
%conv = zext i1 %cmp2 to i32
ret i32 %conv
}

define dso_local range(i32 0, 2) i32 @test2(i32 noundef %a) local_unnamed_addr {
entry:
%or.cond = icmp ult i32 %a, 2
tail call void @llvm.assume(i1 %or.cond)
%shr = shl nuw nsw i32 1, %a
%add = add nuw nsw i32 %a, 1
%cmp2 = icmp eq i32 %shr, %add
%conv = zext i1 %cmp2 to i32
ret i32 %conv
}

declare void @llvm.assume(i1 noundef) #1
```

See Commit [1bbd613](https://github.com/llvm/llvm-project/commit/1bbd613e6267ea0a08994b56adc73cc7b2b5d07d) for reference.

[GCC counterpart patch](https://gcc.gnu.org/pipermail/gcc-patches/2026-July/722433.html).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.