mpz_{eq,lt,gt}_{ui,si}_p macros?

Marc Glisse marc.glisse at inria.fr
Wed Feb 13 09:28:59 CET 2013


On Wed, 13 Feb 2013, bodrato at mail.dm.unipi.it wrote:

> Ciao Marc,
>
> Il Lun, 11 Febbraio 2013 12:42 am, Marc Glisse ha scritto:
>> Could we have inline functions instead of macros? I'd rather avoid macros
>
> Are inline functions as portable as macros?

Not quite, but I don't know any current compiler that doesn't support 
them. Besides, I thought we were talking about __builtin_constant_p, and 
thus gcc (or compatible compilers).

> If a compiler does not inline the function corresponding to:
>
>>> #define mpz_lt_ui_p(Z,UI) (_mpz_cmp_ui (Z,UI) < 0)
>
> then we will have two function calls instead of one.

If the compiler is bad, there are many bad things that can happen...

>> I am wondering (true question) how much this gains compared to refining
>> the existing mpz_cmp_[su]i macros.
>
> I don't know exactly, I didn't try. The _cmp_ functions return three
> possible values. The compiler should be able to select.
> We can define _cmp_ui (z,0) as (SIZ(z)>0)-(SIZ(z)<0), will the compiler
> detect that this expression is >0 iif SIZ(z) is? and <0 iif SIZ(z) is? and
> ==0 iif SIZ(z)==0?

I tried with gcc-4.8, it optimized this just fine.

> Even worse for cmp_ui (z,limb), it is hard to write a branchless expression.

Branches may actually make it easier for the compiler to understand the 
code and thus remove useless branches, as opposed to clever but obscure 
branchless expressions.

> Assume we write cmp_ui (z,limb) as gt()?1:lt()?-1:0, it is "easy" for the
> compiler to understand that the expression >0 iif gt(), but what about >0?

I tested (i>0?1:i<0?-1:0)<0 (and >0 and ==0) and gcc optimized it to just 
i<0 (resp. i>0, i==0).

> If UI always fits in a LIMB, we can write (even for non-gcc compilers)
>
> #define mpz_gt_ui_p(Z,UI) (SIZ(Z) > (PTR(Z)[0] <= (UI)))
> #define mpz_lt_ui_p(Z,UI) (SIZ(Z) <= (PTR(Z)[0] < (UI)) - ((UI) == 0))
> #define mpz_eq_ui_p(Z,UI) (SIZ(Z) == ((UI) != 0) && (((UI) == 0) ||
> (PTR(Z)[0] == (UI)))
>
> Can you suggest a definition for cmp_ui to obtain something similar?

OK, that looks harder...

>>> If you like the idea, then please read carefully the lt_si and gt_si
>>> variants, I'm not sure I'm handling correctly the negative constants.
>>
>> -(SI) seems wrong, you need to cast to an unsigned type before taking the
>> opposite, or LONG_MIN gives you undefined behavior.
>
> ... you are right ... I don't know if I'll be able to write a shortcut for
> negative numbers...

Why not? If -(SI) is the only issue, then -(unsigned long)(SI) should 
work, no?

-- 
Marc Glisse


More information about the gmp-devel mailing list