Extra check when rejoining branches.
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
https://godbolt.org/z/E4GWGTjf6
Code
```c++
#include
__attribute__((cold)) std::pair cold();
inline std::pair sub(const char* ptr) {
if (*ptr < 5) {
return cold();
}
return {ptr, (long)*ptr};
}
long rejoin(const char* ptr) {
auto result = sub(ptr);
auto rptr = std::get<0>(result);
if (!rptr) {
while (true) {}
}
return std::get<1>(result);
}
inline std::pair sub_fix(const char* ptr) {
if (*ptr < 5) {
auto value = cold();
auto rptr = std::get<0>(value);
if (rptr) {
return {ptr + (rptr - ptr), std::get<1>(value)};
} else {
return {nullptr, std::get<1>(value)};
}
}
return {ptr, (long)*ptr};
}
long rejoin_fix(const char* ptr) {
auto result = sub_fix(ptr);
auto rptr = std::get<0>(result);
if (!rptr) {
while (true) {}
}
return std::get<1>(result);
}
```
Assembly
```asm
rejoin(char const*):
movsx rax, byte ptr [rdi]
cmp rax, 4
jle .LBB0_1
test rdi, rdi ; <---
je .LBB0_3
.LBB0_4:
ret
.LBB0_1:
push rax
call cold()@PLT
mov rdi, rax
mov rax, rdx
add rsp, 8
test rdi, rdi
jne .LBB0_4
.LBB0_3:
jmp .LBB0_3
rejoin_fix(char const*):
movsx rax, byte ptr [rdi]
cmp rax, 4
jle .LBB1_1
ret
.LBB1_1:
push rax
call cold()@PLT
test rax, rax
lea rsp, [rsp + 8]
je .LBB1_4
mov rax, rdx
ret
.LBB1_4:
jmp .LBB1_4
```
IR
```llvm
define dso_local noundef i64 @rejoin(char const*)(ptr noundef %ptr) local_unnamed_addr {
entry:
%0 = load i8, ptr %ptr, align 1
%cmp.i = icmp slt i8 %0, 5
br i1 %cmp.i, label %if.then.i, label %if.end.i
if.then.i:
%call.i = tail call { ptr, i64 } @cold()() #2
br label %sub(char const*).exit
if.end.i:
%conv1.i = zext nneg i8 %0 to i64
%1 = insertvalue { ptr, i64 } poison, ptr %ptr, 0
%2 = insertvalue { ptr, i64 } %1, i64 %conv1.i, 1
br label %sub(char const*).exit
sub(char const*).exit: // <--- branches merge
%.fca.1.insert.merged.i = phi { ptr, i64 } [ %call.i, %if.then.i ], [ %2, %if.end.i ]
%3 = extractvalue { ptr, i64 } %.fca.1.insert.merged.i, 0
%tobool.not = icmp eq ptr %3, null // <--- not optimized out
br i1 %tobool.not, label %while.cond, label %if.end
while.cond:
br label %while.cond
if.end:
%4 = extractvalue { ptr, i64 } %.fca.1.insert.merged.i, 1
ret i64 %4
}
```
Contributor guide
Assessment
This issue has not been assessed yet.