Re: [cfe-dev] Code generation for noexcept functions

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] Code generation for noexcept functions

Richard Smith-33
On Sun, May 11, 2014 at 8:19 AM, Stephan Tolksdorf <[hidden email]> 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",@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,@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",@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",@progbits,__clang_call_terminate,comdat
        .hidden __clang_call_terminate
        .weak   __clang_call_terminate
        .align  16, 0x90
        .type   __clang_call_terminate,@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
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] Code generation for noexcept functions

Stephan Tolksdorf
On 2014-05-11 Richard Smith wrote:

> On Sun, May 11, 2014 at 8:19 AM, Stephan Tolksdorf <[hidden email]
> <mailto:[hidden email]>> 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.)

Thanks for the reply! Do you or maybe somebody else have an opinion on
what the best way would be to efficiently support this case in LLVM IR?

- Stephan

>
>     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",@__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,@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",@__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",@progbits,__clang_call___terminate,comdat
>              .hidden __clang_call_terminate
>              .weak   __clang_call_terminate
>              .align  16, 0x90
>              .type   __clang_call_terminate,@__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
>     [hidden email] <mailto:[hidden email]>
>     http://lists.cs.uiuc.edu/__mailman/listinfo/cfe-dev
>     <http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev>
>
>
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] Code generation for noexcept functions

Richard Smith-33
On Tue, May 13, 2014 at 12:36 PM, Stephan Tolksdorf <[hidden email]> wrote:
On 2014-05-11 Richard Smith wrote:
On Sun, May 11, 2014 at 8:19 AM, Stephan Tolksdorf <[hidden email]
<mailto:[hidden email]>> 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.)

Thanks for the reply! Do you or maybe somebody else have an opinion on what the best way would be to efficiently support this case in LLVM IR?

Here's a reduced testcase:

void f();
void g() noexcept { f(); }

One obvious approach would be to emit the call to 'f' as a 'call', not an 'invoke', with some attribute indicating that the program is terminated if it unwinds. (We can't use 'nounwind' for this, because that gives us UB on unwind, not a call to terminate.)

Not-very-well-thought-through strawman: add a function attribute to indicate that that the function does not return if a call unwinds (and pass it the personality function so that we can generate the right CFI stuff).

call void @_Z1fv() terminateonunwind(i32 (...)* @__gxx_personality_v0)

This would result in a call that is not covered by any range in the call site table in the calling function's LSDA.


Another case:

void h() noexcept { try { f(); } catch (int) {} }

Here, I don't think there's a better representation than the one we're currently using (though we should at least omit the pointless __cxa_begin_catch immediately before our synthesized call to std::terminate).

    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",@__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,@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",@__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",@progbits,__clang_call___terminate,comdat

             .hidden __clang_call_terminate
             .weak   __clang_call_terminate
             .align  16, 0x90
             .type   __clang_call_terminate,@__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
    [hidden email] <mailto:[hidden email]>
    http://lists.cs.uiuc.edu/__mailman/listinfo/cfe-dev
    <http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev>




_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] Code generation for noexcept functions

Stephan Tolksdorf
On 2014-05-13 23:26, Richard Smith wrote:

> On Tue, May 13, 2014 at 12:36 PM, Stephan Tolksdorf <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     On 2014-05-11 Richard Smith wrote:
>
>         On Sun, May 11, 2014 at 8:19 AM, Stephan Tolksdorf
>         <[hidden email] <mailto:[hidden email]>
>         <mailto:[hidden email] <mailto:[hidden email]>>> 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.)
>
>
>     Thanks for the reply! Do you or maybe somebody else have an opinion
>     on what the best way would be to efficiently support this case in
>     LLVM IR?
>
>
> Here's a reduced testcase:
>
> void f();
> void g() noexcept { f(); }
>
> One obvious approach would be to emit the call to 'f' as a 'call', not
> an 'invoke', with some attribute indicating that the program is
> terminated if it unwinds. (We can't use 'nounwind' for this, because
> that gives us UB on unwind, not a call to terminate.)
>
> Not-very-well-thought-through strawman: add a function attribute to
> indicate that that the function does not return if a call unwinds (and
> pass it the personality function so that we can generate the right CFI
> stuff).
>
> call void @_Z1fv() terminateonunwind(i32 (...)* @__gxx_personality_v0)
>
> This would result in a call that is not covered by any range in the call
> site table in the calling function's LSDA.

I suppose the principal alternative would be to introduce a "terminate"
clause to the landingpad instruction.

One difficulty of implementing either approach seems to be that LLVM
will need to synthesize an actual terminate call when it inlines a
"terminateonunwind" call to a function that contains an invoke without a
catch-all clause and there's no direct way to represent the terminate
action in the LSDA.

> Another case:
>
> void h() noexcept { try { f(); } catch (int) {} }
>
> Here, I don't think there's a better representation than the one we're
> currently using (though we should at least omit the pointless
> __cxa_begin_catch immediately before our synthesized call to
> std::terminate).

If landingpad had a terminate clause, you could leave the synthesizing
of the terminate call to LLVM in this case too.

The call to __cxa_begin_catch seems to be due to llvm.org/PR11893. The
libsupc++ and libc++abi personality functions also call
__cxa_begin_catch before calling std::terminate when possible.

One (ugly) way to prevent clang/LLVM from generating bloated code for
noexcept functions that contain calls to functions which are known to be
non-throwing for the specified arguments but which aren't annotated as
noexcept is to move the calls to an inline wrapper function with
__attribute__((nothrow)). I'll probably resort to this workaround for my
code.

- Stephan

>
>              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",@____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,@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",@____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",@progbits,__clang_call_____terminate,comdat
>
>                       .hidden __clang_call_terminate
>                       .weak   __clang_call_terminate
>                       .align  16, 0x90
>                       .type   __clang_call_terminate,@____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
>         [hidden email] <mailto:[hidden email]>
>         <mailto:[hidden email] <mailto:[hidden email]>>
>         http://lists.cs.uiuc.edu/____mailman/listinfo/cfe-dev
>         <http://lists.cs.uiuc.edu/__mailman/listinfo/cfe-dev>
>              <http://lists.cs.uiuc.edu/__mailman/listinfo/cfe-dev
>         <http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev>>
>
>
>
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev