llvm / llvm/llvm-project

[BranchFolding] Failure to eliminate redundant branch with EH info

Open
#219,628 1 comment 0 reactions 1 assignee Claimed by @boomanaiden154 View on GitHub
llvm:optimizations missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

If we take the following IR (reduced from `locale.cpp` inside of libc++):
```llvm
; ModuleID = '/tmp/reduced.ll'
source_filename = "/tmp/reduced.ll"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-grtev4-linux-gnu"

define ptr @wombat(i1 %arg) personality ptr null {
bbl:
%invoke = invoke i1 @snork(ptr null, ptr null)
to label %bbl1 unwind label %bbl4

bbl1: ; preds = %bbl
br i1 %arg, label %bbl2, label %bbl5

bbl2: ; preds = %bbl1
%invoke3 = invoke i1 @snork(ptr null, ptr null)
to label %bbl7 unwind label %bbl10

bbl4: ; preds = %bbl
%landingpad = landingpad { ptr, i32 }
cleanup
br label %bbl12

bbl5: ; preds = %bbl1
%invoke6 = invoke i8 @wobble(ptr null)
to label %bbl7 unwind label %bbl8

bbl7: ; preds = %bbl5, %bbl2
ret ptr null

bbl8: ; preds = %bbl5
%landingpad9 = landingpad { ptr, i32 }
cleanup
br label %bbl12

bbl10: ; preds = %bbl2
%landingpad11 = landingpad { ptr, i32 }
cleanup
br label %bbl12

bbl12: ; preds = %bbl10, %bbl8, %bbl4
%phi = phi { ptr, i32 } [ %landingpad11, %bbl10 ], [ %landingpad9, %bbl8 ], [ %landingpad, %bbl4 ]
call void @wobble.1(ptr null)
resume { ptr, i32 } %phi
}

declare i1 @snork(ptr, ptr)

declare i8 @wobble(ptr)

declare void @wobble.1(ptr)
```

and compile with with clang:

```shell
clang /tmp/reduced.ll -c -O3 -S -o -
```

We end up with the following

```asm
.att_syntax
.file "reduced.ll"
.text
.globl wombat # -- Begin function wombat
.prefalign 4, .Lfunc_end0, nop
.type wombat,@function
wombat: # @wombat
.Lfunc_begin0:
.cfi_startproc
# %bb.0: # %bbl
pushq %rbx
.cfi_def_cfa_offset 16
.cfi_offset %rbx, -16
movl %edi, %ebx
.Ltmp0: # EH_LABEL
xorl %edi, %edi
xorl %esi, %esi
callq snork@PLT
.Ltmp1: # EH_LABEL
# %bb.1: # %bbl1
testb $1, %bl
je .LBB0_4
# %bb.2: # %bbl2
.Ltmp6: # EH_LABEL
xorl %edi, %edi
xorl %esi, %esi
callq snork@PLT
.Ltmp7: # EH_LABEL
jmp .LBB0_5
.LBB0_4: # %bbl5
.Ltmp3: # EH_LABEL
xorl %edi, %edi
callq wobble@PLT
.Ltmp4: # EH_LABEL
.LBB0_5: # %bbl7
xorl %eax, %eax
popq %rbx
.cfi_def_cfa_offset 8
retq
.LBB0_6: # %bbl8
.cfi_def_cfa_offset 16
.Ltmp5: # EH_LABEL
jmp .LBB0_8
.LBB0_7: # %bbl10
.Ltmp8: # EH_LABEL
jmp .LBB0_8
.LBB0_3: # %bbl4
.Ltmp2: # EH_LABEL
.LBB0_8: # %bbl12
movq %rax, %rbx
xorl %edi, %edi
callq wobble.1@PLT
movq %rbx, %rdi
callq _Unwind_Resume@PLT
.Lfunc_end0:
.size wombat, .Lfunc_end0-wombat
.cfi_endproc
# -- End function
.section ".note.GNU-stack","",@progbits
.addrsig
.addrsig_sym _Unwind_Resume
```

We end up with subsequent identical unconditional branches meaning one of them is redundant. Looking at the optimization pipeline, it looks like we end up with an empty block (minus EH info) in `.LLB0_7` after branch-folding, but the pass fails to fully eliminate it (presumably due to the presence of EH info). Given these are just landing pads, we should be able to just sink them.

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.