llvm / llvm/llvm-project

[CIR] Match OGCG's epilogue codegen

Open
#180,587 1 comment 0 reactions 0 assignees View on GitHub
ClangIR
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

Currently the original LLVMIR codegen for a simple C++ source program:
```c
int test(int a, int b) { return (a - 1) + b; }
```
is
```llvm
...
define i32 @test(i32 noundef %a, i32 noundef %b) #0 {
entry:
%a.addr = alloca i32, align 4
%b.addr = alloca i32, align 4
store i32 %a, ptr %a.addr, align 4
store i32 %b, ptr %b.addr, align 4
%0 = load i32, ptr %a.addr, align 4
%sub = sub nsw i32 %0, 1
%1 = load i32, ptr %b.addr, align 4
%add = add nsw i32 %sub, %1
ret i32 %add
}
...
}
```
However, currently in the lowering from CIR to LLVMIR we get:
```llvm
...
define i32 @test(i32 %0, i32 %1) #0 {
%3 = alloca i32, i64 1, align 4
%4 = alloca i32, i64 1, align 4
%5 = alloca i32, i64 1, align 4
store i32 %0, ptr %3, align 4
store i32 %1, ptr %4, align 4
%6 = load i32, ptr %3, align 4
%7 = sub nsw i32 %6, 1
%8 = load i32, ptr %4, align 4
%9 = add nsw i32 %7, %8
store i32 %9, ptr %5, align 4
%10 = load i32, ptr %5, align 4
ret i32 %10
}

...
```
Basically we have a superfluous store-load pair and an extra alloca for the variable stored into in the LLVMIR lowered from CIR.
In the OGCG these pair are elided see: https://github.com/llvm/llvm-project/blob/48f53422fe7f627fcdace90bd7c3c5ee056bc0a6/clang/lib/CodeGen/CGCall.cpp#L4090-L4106. This is possible because we have [AbIArgInfo](https://github.com/llvm/llvm-project/blob/cd47ae9f8ff9afa46209806e94bfadb0056049c5/clang/include/clang/CodeGen/CGFunctionInfo.h#L32) as part of [CGFunctionInfo](https://github.com/llvm/llvm-project/blob/cd47ae9f8ff9afa46209806e94bfadb0056049c5/clang/include/clang/CodeGen/CGFunctionInfo.h#L596).
This allow us to know if this a direct return or the value will be returned indirectly in an output parameter or it's an "InAlloca"...etc
In the even of a direct return where the return value is dominated by the store to the return value, we can safely elide and delete the store operation.

So looks to me like we need to have this information at the CIR level to be able to pass it down and utilise it when we are doing the lowering to LLVMIR.

Contributor guide

Open the contributing guide

Research direction

Start by reading the cited return handling in clang/lib/CodeGen/CGCall.cpp and the ABI structures in clang/include/clang/CodeGen/CGFunctionInfo.h. Then trace how CIR lowering represents return values and passes that information to LLVM IR. Done means the sample direct-return function no longer has the extra return alloca or store-load pair.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.