llvm / llvm/llvm-project

[AggressiveInstCombine] Combine adjacent loads

Open
#187,854 3 comments 0 reactions 0 assignees View on GitHub
llvm:instcombine missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

Adjacent loads used in comparison can be combined into wider load. I have a case where I want to quickly check that two adjacent elements of a char array are both zero.

```llvm
declare void @f(ptr)
define dso_local zeroext i1 @src() local_unnamed_addr #0 {
%1 = alloca [2 x i8], align 2
store i16 0, ptr %1, align 2
call void @f(ptr noundef nonnull %1) #3
%2 = load i8, ptr %1, align 2
%3 = icmp ne i8 %2, 0
%4 = getelementptr inbounds nuw i8, ptr %1, i64 1
%5 = load i8, ptr %4, align 1
%6 = icmp ne i8 %5, 0
%7 = select i1 %3, i1 true, i1 %6
ret i1 %7
}
define dso_local zeroext i1 @tgt() local_unnamed_addr #0 {
%1 = alloca [2 x i8], align 2
store i16 0, ptr %1, align 2
call void @f(ptr noundef nonnull %1) #3
%2 = load i16, ptr %1, align 2
%3 = icmp ne i16 %2, 0
ret i1 %3
}
```

https://alive2.llvm.org/ce/z/uq_vo5

NB: instead of icmp/icmp/select (`c[0] || c[1]`), also or/icmp can be generated from Clang (`c[0] | c[1]`).
Also NB: in my case, the offsets aren't 0/1, but some slightly larger values.

Contributor guide

Open the contributing guide

Research direction

Start by locating the AggressiveInstCombine implementation and related tests for load and comparison transformations. Use the issue's @src and @tgt LLVM IR as the baseline, then verify behavior for adjacent offsets and both the icmp/select and or/icmp forms. Done means the adjacent loads are combined into a wider load while preserving the demonstrated result.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.