[LLVMdev] Odd weak symbol thing on i386

Eli Friedman eli.friedman at gmail.com
Fri Jan 13 15:31:37 PST 2012


On Fri, Jan 13, 2012 at 2:53 PM, Richard Pennington <rich at pennware.com> wrote:
> Hi,
>
> I'm compiling lldiv.c from the NetBSD standard library. It works on ARM, Mips,
> Microblaze,ppc, ppc64, and x86_64. On i386 a very strange thing happens.
> Here's the source:
>
> #include <stdlib.h>
> #define       __weak_alias(sym) __attribute__ ((weak, alias (#sym)))
>
> lldiv_t lldiv(long long int num, long long int denom) __weak_alias(_lldiv);
>
> lldiv_t _lldiv(long long num, long long denom)
> {
>        lldiv_t r;
>        r.quot = num / denom;
>        r.rem = num % denom;
>        if (num >= 0 && r.rem < 0) {
>                r.quot++;
>                r.rem -= denom;
>        }
>        return (r);
> }
>
> I get the following code emitted for the return if the alias line is present:
>
> LBB0_3:                                # %if.end
>        movl    64(%esp), %eax
>        movsd   24(%esp), %xmm0
>        movsd   32(%esp), %xmm1
>        movsd   %xmm1, 8(%eax)
>        movsd   %xmm0, (%eax)
>        addl    $56, %esp
>        popl    %esi
>        ret
> .Ltmp0:
>        .size   _lldiv, .Ltmp0-_lldiv
>
>
>        .weak   lldiv
> lldiv = _lldiv
>
> And this if it isn't:
> LBB0_3:                                # %if.end
>        movl    64(%esp), %eax
>        movsd   24(%esp), %xmm0
>        movsd   32(%esp), %xmm1
>        movsd   %xmm1, 8(%eax)
>        movsd   %xmm0, (%eax)
>        addl    $56, %esp
>        popl    %esi
>        ret     $4
> .Ltmp0:
>        .size   _lldiv, .Ltmp0-_lldiv
>
> Other than the $4 on the return address, the code is otherwise identical. The
> alias version crashes, of course. Is there supposed to be an implicit pop of
> the return structure pointer? What could cause an alias to mess this up?

Bad version:
define void @_lldiv(%struct.lldiv_t* noalias %agg.result, i64 %num,
i64 %denom) nounwind {

Good version:
define void @_lldiv(%struct.lldiv_t* noalias sret %agg.result, i64
%num, i64 %denom) nounwind {

Looks like a bug in clang's IR generation; please file a bug.

-Eli




More information about the llvm-dev mailing list