ARM EABI and modulo

Hi all,
one issue found during the NetBSD/ARM tests is the following.
Consider this input for EARM:

    int f(int a, int b) { return a % b; }
    unsigned int g(unsigned int a, unsigned int b) { return a % b; }

At the moment, this will call __modsi3 and __umodsi3, even though those
functions are not part of AAPCS. Should this be considered a lowering
bug in the ARM target?

Joerg

Hi Joerg,

At the moment, this will call __modsi3 and __umodsi3, even though those
functions are not part of AAPCS. Should this be considered a lowering
bug in the ARM target?

LLVM actually supports both variants, depending on the target. The
__aeabi_* functions are part of the ARM "runtime ABI" and largely
independent of AAPCS. For whatever reason, Linux (& Darwin) ended up
not adopting it and using those GNU functions instead.

If NetBSD uses the aeabi ones instead, it probably needs some extra
checks added to the code. I believe ELF targets currently decide based
on whether the final part of the triple is "-eabi" or not (as opposed
to "-gnueabi", ...), though I haven't looked at the code recently.

Cheers.

Tim.

Hi Tim,

You are correct, the target triple must contain "eabi", not "gnueabi".
If you are using this on your target triple, than it's a front-end
bug, not a lowering one.

Also, note that GNU tools support the whole AEABI, so not using
gnueabi doesn't mean that it'll be incompatible with GNU tools, just
that the ARM EABI will be used instead of the GNU one.

Also note that, for 64-bit types, we still have a lowering bug where
the GNU variant is used for modulo.

This is open here:

http://llvm.org/bugs/show_bug.cgi?id=17881

and here:

http://llvm.org/bugs/show_bug.cgi?id=17193

Weiming is working on it, if this is important for you, please add
yourself to the bugs and let us know your concerns.

cheers,
--renato

Part of the concern is that the same code using / does call __aeabi_idiv
and __aeabi_uidiv.

Joerg

Part of the concern is that the same code using / does call __aeabi_idiv
and __aeabi_uidiv.

Ah, then that's definitely a bug, one way or the other. Odd, a very
quick test of mine gave __aeabi_imod.

Cheers.

Tim.

Hi Joerg,

I can see the error, and it's just a bad selection of choices. I was
wrong in assuming that the "eabi" at the end would always force it:

$ clang -target arm-elf-eabi -S mod.c -o - | grep mod
.file "mod.c"
bl __modsi3
bl __umodsi3

$ clang -target arm-none-eabi -S mod.c -o - | grep mod
.file "mod.c"
bl __aeabi_idivmod
bl __aeabi_uidivmod

This is clearly a bug and should be fixed. Please file a bug in
bugzilla and I'll have a look at it.

cheers,
--renato

I was discussing this with Tim on IRC and he raised the valid question
of a pure mod operation being faster when emulated as it doesn't have to
keep track of the quotient. So it really boils down to whether it has a
fancy enough dress to be called a feature.

Joerg

...but it should be using __aeabi_*mod in that case.

Joerg

This is not just about being faster, but also compliant. If you have
to follow the EABI, then you cannot guarantee that you'll have the
__umodsi3 anywhere in any library. If you follow the GNU EABI, than
you have no guarantee that __aeabi_uidivmod will.

Regardless of the performance discussion, I opened this bug:

http://llvm.org/bugs/show_bug.cgi?id=18187

because of its inconsistency. If you want to call __umodsi3 instead of
__uidivmod, than you should use GNUEABI.

When you need both, calling the EABI variant is faster (only one
function call), but I don't think we should mix the two variants in
EABI mode. If the GNUEABI wants to do that, I don't think it's wrong,
but lets not do this on EABI mode.

cheers,
--renato

There are no __aeabi_*mod variants.

EABI 4.3.1:

Aside: Separate modulo functions would have little value because
modulo on its own is rare. Division by a constant and
constant modulo can be inlined efficiently using (64-bit)
multiplication. For implementations in C, __value_in_regs can be
emulated by tail-calling an assembler function that receives the
values to be returned as arguments and, itself, returns
immediately.

cheers,
--renato