arithmetical operands signedness

Hi,

my target handles operands of multiplying instructions differently based on signedness.

I wonder then how I would do instruction selection based on the operands signs?

The mul instruction sets a nsw for signed, but when i try unsigned ops, there is no wrap flag at all. I’m not sure this is enough information to work with, or?

Jonas

Hi Jonas,

my target handles operands of multiplying instructions differently based on
signedness.

since the result of a multiply doesn't depend on the signedness, I find it
strange that your target differentiates between them. What I'm saying is
that if you have (say) two i32 numbers a and b and you do a signed multiply:
   c = a *s b
and an unsigned multiply
   d = a *u b
then c and d are the same number (exactly the same bits set).

I wonder then how I would do instruction selection based on the operands signs?

The mul instruction sets a nsw for signed,

No it doesn't. nsw doesn't mean signed, it means that if the multiplication
would overflow as a signed multiplication then the result is undefined which
is completely different.

  but when i try unsigned ops, there is

no wrap flag at all. I'm not sure this is enough information to work with, or?

No information is needed, see above.

Ciao, Duncan.

At least two architectures I know about have size-extending multiplication, for which your statement is not true:

- Motorola MC68K has i16 x 16 -> i32 instructions in signed and unsigned forms

- Itanium has signed and unsigned multiplications with i64 x i64 -> i64 where you can take the high or low part of the resulting i128. While xma.lu is a pseudo-op since it's the same as xma.lu, xma.hu and xma.h (unsigned and signed) are distinct.

I'm pretty sure there are other similar architectures.

Regards
Christophe

Hi Christophe,

since the result of a multiply doesn't depend on the signedness, I find it
strange that your target differentiates between them. What I'm saying is
that if you have (say) two i32 numbers a and b and you do a signed multiply:
   c = a *s b
and an unsigned multiply
   d = a *u b
then c and d are the same number (exactly the same bits set).

At least two architectures I know about have size-extending multiplication, for which your statement is not true:

yup, and that's why LLVM codegen has the SMUL_LOHI/UMUL_LOHI etc nodes. However
that's not relevant to ordinary multiplication (codegen MUL node) which is what
I understand the question to be about.

Ciao, Duncan.

First of all, Sorry for waking up this zombie thread from jan 2011, but i’m investigating incremental compilation
and i haven’t found much else besides this.

As a question to Christophe, but also to anyone that might help; are your functions being
evicted from the final module after LTO even if the functions are created with External Linkage?

notice the following points:

  1. my understanding is that a function with external linkage should be always available. That is
    how libraries export their symbols after all.

  2. my understanding also (and this is the crucial point) is that LTO as a optimization phase should
    be equally applicable to final executables or libraries. Libraries always should have their

export/external symbols available even if they seem to not be called from inside the available code.
(libraries would be very useless objects after all!). This does not (or should not) preclude
LTO optimization of the library dependencies

am i making sense here?

thanks!