Turning on exception handling codegen

Right now llvm-gcc generates exception handling intrinsics,
but actual eh codegen (--enable-eh) is turned off. On
x86-linux, turning it on generates no new failures in the
testsuite, so how about turning it on? The problem is
likely to be PPC which claims to support eh but doesn't
support it completely yet AFAIK. I suggest setting
SupportsExceptionHandling to false for PPC until it is
fixed.

I think it is important to have eh work in the next
release, which means turning on eh codegen in the
near future. I'd rather turn it on sooner than
later, so it gets more testing.

Ciao,

Duncan.

Right now llvm-gcc generates exception handling intrinsics,
but actual eh codegen (--enable-eh) is turned off. On
x86-linux, turning it on generates no new failures in the
testsuite,

yay !

Right now llvm-gcc generates exception handling intrinsics,
but actual eh codegen (--enable-eh) is turned off. On
x86-linux, turning it on generates no new failures in the
testsuite,

Woo hoo!

The problem is likely to be PPC which claims to support eh but doesn't support it completely yet AFAIK. I suggest setting SupportsExceptionHandling to false for PPC until it is fixed.

Done.

so how about turning it on?

It sounds good, but I'm concerned about darwin/x86. Bill, can you see how well darwin/x86 is doing these days? If there are no regressions from turning this on by default, we should do it. :slight_smile:

If there are darwin/x86 failures, we should set SupportsExceptionHandling to true only for the linux/x86 subtarget.

I think it is important to have eh work in the next
release, which means turning on eh codegen in the
near future. I'd rather turn it on sooner than
later, so it gets more testing.

I agree, congrats for getting this working!

-Chris

I'm assuming that this is 4.2? :slight_smile: I'll give it a try.

-bw

I'm trying it on 4.0. On 4.2, I'm getting this problem during bootstrapping:

ccAMeZbg.s:111:non-relocatable subtraction expression,
"___gxx_personality_v0" minus "L0"
ccAMeZbg.s:111:symbol: "___gxx_personality_v0" can't be undefined in a
subtraction expression

for this reduced testcase:

namespace __cxxabiv1 {
  extern "C" void *__cxa_allocate_exception() throw();
}

int bork(void);

namespace __gnu_cxx {
  inline void __throw_concurrence_unlock_error() {
  }

  struct __mutex {
    void unlock() {
      if (bork() != 0)
        __throw_concurrence_unlock_error();
    }
  };
}

__gnu_cxx::__mutex emergency_mutex;

extern "C" void *__cxxabiv1::__cxa_allocate_exception() throw() {
  emergency_mutex.unlock();
}

I've been looking at it, but haven't been able to spend a lot of time on it.

-bw

Hi Bill,

I'm trying it on 4.0. On 4.2, I'm getting this problem during bootstrapping:

ccAMeZbg.s:111:non-relocatable subtraction expression,
"___gxx_personality_v0" minus "L0"
ccAMeZbg.s:111:symbol: "___gxx_personality_v0" can't be undefined in a
subtraction expression

this is the darwin assembler that barfs, right? It looks like it doesn't
like the way the personality function is output in the assembler. If so,
you should see exactly the same problem with llvm-gcc-4.0 for any code
containing eh constructs. I think Anton is the guy to look into this (CC'd).

Ciao,

Duncan.

PS: 32 bit or 64 bit?

In my experience, you can work around this sort of errors on Darwin using the following trick (also employed by gcc normally):

  .set L$set$4,Lj93-Lj95
         .long L$set$4

(the .set can also come after the use of the set expression). I've never really understood the reason for the requirement of this detour.

Jonas

Hi Duncan,

> I'm trying it on 4.0. On 4.2, I'm getting this problem during bootstrapping:
>
> ccAMeZbg.s:111:non-relocatable subtraction expression,
> "___gxx_personality_v0" minus "L0"
> ccAMeZbg.s:111:symbol: "___gxx_personality_v0" can't be undefined in a
> subtraction expression

this is the darwin assembler that barfs, right? It looks like it doesn't
like the way the personality function is output in the assembler. If so,
you should see exactly the same problem with llvm-gcc-4.0 for any code
containing eh constructs. I think Anton is the guy to look into this (CC'd).

Yeah, I'm seeing this in 4.0 as well. It looks as if the personality
function isn't being output into the .s file. So we get something
along the lines of this:

Leh_frame_common_begin1:
        .long 0x0
        .byte 0x1
        .asciz "zPLR"
        .byte 0x1
        .byte 0x7c
        .byte 0x8
  .byte 0x7
        .byte 0x1b
        .long ___gxx_personality_v0-.
        .byte 0x10
  .byte 0x10
        .byte 0xc
        .byte 0x4
        .byte 0x4
        .byte 0x88
        .byte 0x1
  .align 2
Leh_frame_common_end1:

with no ___gxx_personality_v0. Have you or Anton come across this
before? If so, is there a place I can start looking? :slight_smile:

PS: 32 bit or 64 bit?

It's 64-bit, which Anton says doesn't work. But I'm not sure if this
is a 64-bit specific bug.

-bw

Hi Jonas,

> this is the darwin assembler that barfs, right? It looks like it
> doesn't
> like the way the personality function is output in the assembler.
> If so,
> you should see exactly the same problem with llvm-gcc-4.0 for any code
> containing eh constructs. I think Anton is the guy to look into
> this (CC'd).

In my experience, you can work around this sort of errors on Darwin
using the following trick (also employed by gcc normally):

        .set L$set$4,Lj93-Lj95
         .long L$set$4

(the .set can also come after the use of the set expression). I've
never really understood the reason for the requirement of this detour.

That got the assembler to accept it. I'll fix the asm printer and see
if that will get EH on Darwin to work.

Thanks!
-bw

Hi Bill,

> > I'm trying it on 4.0. On 4.2, I'm getting this problem during bootstrapping:
> >
> > ccAMeZbg.s:111:non-relocatable subtraction expression,
> > "___gxx_personality_v0" minus "L0"
> > ccAMeZbg.s:111:symbol: "___gxx_personality_v0" can't be undefined in a
> > subtraction expression
>
> this is the darwin assembler that barfs, right? It looks like it doesn't
> like the way the personality function is output in the assembler. If so,
> you should see exactly the same problem with llvm-gcc-4.0 for any code
> containing eh constructs. I think Anton is the guy to look into this (CC'd).
>
Yeah, I'm seeing this in 4.0 as well. It looks as if the personality
function isn't being output into the .s file. So we get something
along the lines of this:

Leh_frame_common_begin1:
        .long 0x0
        .byte 0x1
        .asciz "zPLR"
        .byte 0x1
        .byte 0x7c
        .byte 0x8
  .byte 0x7
        .byte 0x1b
        .long ___gxx_personality_v0-.
        .byte 0x10
  .byte 0x10
        .byte 0xc
        .byte 0x4
        .byte 0x4
        .byte 0x88
        .byte 0x1
  .align 2
Leh_frame_common_end1:

with no ___gxx_personality_v0. Have you or Anton come across this
before? If so, is there a place I can start looking? :slight_smile:

gcc outputs the following additional line:
.globl __gxx_personality_v0
Presumably we should too but it was never noticed because the linux
assembler works fine without it. In general, the thing to do with
this kind of problem is to compile the program using mainline gcc
(use the -dA options, it adds comments to the assembler) and compare
the assembler output with that of llvm-gcc/llc.

Ciao,

Duncan.

Hi Bill,

> PS: 32 bit or 64 bit?
>
It's 64-bit, which Anton says doesn't work. But I'm not sure if this
is a 64-bit specific bug.

there are a couple of 32 bit assumptions in EmitExceptionTable.
A quick scan gives:

(a)
      SizeSites += M*(sizeof(int32_t) + // Site start.
                      sizeof(int32_t) + // Site length.
                      sizeof(int32_t) + // Landing pad.

This might be correct for 64 bit targets - not sure.

(b)
    unsigned SizeAlign = (4 - TotalSize) & 3;
This is used to align the typeinfos. Since these have size
TAI->getAddressSize(), presumably 4 -> 8 and 3 -> 7 on 64 bit
targets.

(c)
    O << "GCC_except_table" << SubprogramCount << ":\n";
    Asm->EmitAlignment(2);
This is also part of the logic to align the typeinfos. I don't
know what "2" means here, but this needs to result in an alignment
that is OK for a typeinfo (which has size TAI->getAddressSize()).

(d)
    Asm->EmitAlignment(2);
This is the last line of the function. I don't know what it is for.

If you send me the assembler produced by gcc for your machine, it
should be easy to work out what the right values are here.

Ciao,

Duncan.

Actually both - neither creates additional failures in the LLVM testsuite.
However the 4.2 version doesn't have *any* gcc eh testsuite failures (except
for one that is pending on PR1146) while the 4.0 version does have a few.
That said, not all LLVM eh tests pass due to a bug exposed by LTO, but I've
just fixed that.

Ciao,

Duncan.