<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - _Unwind_Resume() call in landingpad for C++ EH is sometimes dead code"
   href="http://llvm.org/bugs/show_bug.cgi?id=20300">20300</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>_Unwind_Resume() call in landingpad for C++ EH is sometimes dead code
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>tools
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>llc
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>mseaborn@chromium.org
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>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 {
    external_func();
  } 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
.LBB0_4:
        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"
clause.

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?</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>