[LLVMbugs] [Bug 20300] New: _Unwind_Resume() call in landingpad for C++ EH is sometimes dead code

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Mon Jul 14 14:31:20 PDT 2014


            Bug ID: 20300
           Summary: _Unwind_Resume() call in landingpad for C++ EH is
                    sometimes dead code
           Product: tools
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: llc
          Assignee: unassignedbugs at nondot.org
          Reporter: mseaborn at chromium.org
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

This is an opportunity for reducing the size of generated code for C++ source
that catches exceptions.

When I compile the following function, LLVM/Clang generates an unnecessary call
to _Unwind_Resume() in the landingpad code:

void external_func();
extern int caught;

void foo() {
  try {
  } catch (int) {
    caught = 123;

$ clang cxx_exception_catch1.cc -S -o - -O2
// Landingpad for call to external_func():
        movq    %rdx, %rcx
        movq    %rax, %rdi
        cmpl    $1, %ecx  // Check exception type ID
        jne     .LBB0_4
# BB#3:
        callq   __cxa_begin_catch
        movl    $123, caught(%rip)
        popq    %rax
        jmp     __cxa_end_catch         # TAILCALL
        callq   _Unwind_Resume

Since the landingpad will only ever be entered with an exception type ID of 1
(representing the "int" type), the call to _Unwind_Resume() is dead code and
could be omitted.  Similarly, the check for the exception type ID could be
omitted too.

The reason is that the LLVM IR for this function contains the following:

$ clang cxx_exception_catch1.cc -S -o - -O2 -emit-llvm
; Landingpad:
  %2 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)*
@__gxx_personality_v0 to i8*)
          catch i8* bitcast (i8** @_ZTIi to i8*)
  %3 = extractvalue { i8*, i32 } %2, 1
  %4 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #3
  %5 = icmp eq i32 %3, %4
  br i1 %5, label %6, label %10

; Handle exception:
; <label>:6                                       ; preds = %1
  %7 = extractvalue { i8*, i32 } %2, 0
  %8 = tail call i8* @__cxa_begin_catch(i8* %7) #3
  store i32 123, i32* @caught, align 4, !tbaa !1
  tail call void @__cxa_end_catch() #3
  ret void

; Resume unwinding from exception:
; <label>:10                                      ; preds = %1
  resume { i8*, i32 } %2

Since the "landingpad" IR instruction contains only a single "catch" clause
(for "int") and no "cleanup" clause, the standard C++ personality routine will
only enter the landingpad if the exception being thrown matches the "catch"

The IR needs to contain the "resume" instruction and the typeid check in case
this function gets inlined.  However, once this code reaches the LLVM backend,
we know that the backend is not going to inline the function.  The backend
could simplify the code given that %3 will always be 1.  Maybe this could be
added as an optimisation to lib/CodeGen/DwarfEHPrepare.cpp?

You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20140714/7acb1a87/attachment.html>

More information about the llvm-bugs mailing list