[cfe-dev] Code generation for noexcept functions

Richard Smith richard at metafoo.co.uk
Sun May 11 13:57:32 PDT 2014


On Sun, May 11, 2014 at 8:19 AM, Stephan Tolksdorf <st at quanttec.com> wrote:

> Hi,
>
> When clang/LLVM can't prove that a noexcept function only contains
> non-throwing code, it seems to insert an explicit exception handler that
> calls std::terminate. Why doesn't clang leave it to the eh personality
> function to call std::terminate when an exception is thrown inside a
> noexcept function, as GCC does?
>

As far as I can see, this is impossible to represent in LLVM IR. (If there
is a way, I'm sure we'd be happy to make clang emit that IR.)


> For example, GCC generates more efficient code for this test case:
>
>   using FP = void(*)();
>
>   inline void test(FP fp) noexcept {
>     fp();
>   }
>
>   void test2(FP fp) {
>     test(fp);
>     test(fp);
>   }
>
> The code generated by GCC (ToT, -O3, Linux x64) is:
>
> .LHOTB0:
>         .p2align 4,,15
>         .globl  _Z5test2PFvvE
>         .type   _Z5test2PFvvE, @function
> _Z5test2PFvvE:
> .LFB1:
>         .cfi_startproc
>         .cfi_personality 0x3,__gxx_personality_v0
>         .cfi_lsda 0x3,.LLSDA1
>         pushq   %rbx
>         .cfi_def_cfa_offset 16
>         .cfi_offset 3, -16
>         movq    %rdi, %rbx
>         call    *%rdi
>         movq    %rbx, %rax
>         popq    %rbx
>         .cfi_def_cfa_offset 8
>         jmp     *%rax
>         .cfi_endproc
> .LFE1:
>         .globl  __gxx_personality_v0
>         .section        .gcc_except_table,"a", at progbits
> .LLSDA1:
>         .byte   0xff
>         .byte   0xff
>         .byte   0x1
>         .uleb128 .LLSDACSE1-.LLSDACSB1
> .LLSDACSB1:
> .LLSDACSE1:
>         .text
>         .size   _Z5test2PFvvE, .-_Z5test2PFvvE
>         .section        .text.unlikely
>
>
> The code generated by clang (ToT, -O3, Linux x64) is:
>
> .globl  _Z5test2PFvvE
>         .align  16, 0x90
>         .type   _Z5test2PFvvE, at function
> _Z5test2PFvvE:                          # @_Z5test2PFvvE
>         .cfi_startproc
>         .cfi_personality 3, __gxx_personality_v0
> .Leh_func_begin0:
>         .cfi_lsda 3, .Lexception0
> # BB#0:                                 # %entry
>         pushq   %rbx
> .Ltmp6:
>         .cfi_def_cfa_offset 16
> .Ltmp7:
>         .cfi_offset %rbx, -16
>         movq    %rdi, %rbx
> .Ltmp0:
>         callq   *%rbx
> .Ltmp1:
> # BB#1:                                 # %_Z4testPFvvE.exit
> .Ltmp3:
>         callq   *%rbx
> .Ltmp4:
> # BB#2:                                 # %_Z4testPFvvE.exit3
>         popq    %rbx
>         retq
> .LBB0_3:                                # %terminate.lpad.i
> .Ltmp2:
>         movq    %rax, %rdi
>         callq   __clang_call_terminate
> .LBB0_4:                                # %terminate.lpad.i2
> .Ltmp5:
>         movq    %rax, %rdi
>         callq   __clang_call_terminate
> .Ltmp8:
>         .size   _Z5test2PFvvE, .Ltmp8-_Z5test2PFvvE
>         .cfi_endproc
> .Leh_func_end0:
>         .section        .gcc_except_table,"a", at progbits
>         .align  4
> GCC_except_table0:
> .Lexception0:
>         .byte   255                     # @LPStart Encoding = omit
>         .byte   3                       # @TType Encoding = udata4
>         .asciz  "\242\200\200"          # @TType base offset
>         .byte   3                       # Call site Encoding = udata4
>         .byte   26                      # Call site table length
> .Lset0 = .Ltmp0-.Leh_func_begin0        # >> Call Site 1 <<
>         .long   .Lset0
> .Lset1 = .Ltmp1-.Ltmp0                  #   Call between .Ltmp0 and .Ltmp1
>         .long   .Lset1
> .Lset2 = .Ltmp2-.Leh_func_begin0        #     jumps to .Ltmp2
>         .long   .Lset2
>         .byte   1                       #   On action: 1
> .Lset3 = .Ltmp3-.Leh_func_begin0        # >> Call Site 2 <<
>         .long   .Lset3
> .Lset4 = .Ltmp4-.Ltmp3                  #   Call between .Ltmp3 and .Ltmp4
>         .long   .Lset4
> .Lset5 = .Ltmp5-.Leh_func_begin0        #     jumps to .Ltmp5
>         .long   .Lset5
>         .byte   1                       #   On action: 1
>         .byte   1                       # >> Action Record 1 <<
>                                         #   Catch TypeInfo 1
>         .byte   0                       #   No further actions
>                                         # >> Catch TypeInfos <<
>         .long   0                       # TypeInfo 1
>         .align  4
>
>         .section .text.__clang_call_terminate,"
> axG", at progbits,__clang_call_terminate,comdat
>         .hidden __clang_call_terminate
>         .weak   __clang_call_terminate
>         .align  16, 0x90
>         .type   __clang_call_terminate, at function
> __clang_call_terminate:                 # @__clang_call_terminate
> # BB#0:
>         pushq   %rax
>         callq   __cxa_begin_catch
>         callq   _ZSt9terminatev
> .Ltmp9:
>         .size   __clang_call_terminate, .Ltmp9-__clang_call_terminate
>
> - Stephan
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140511/1293f7d0/attachment.html>


More information about the cfe-dev mailing list