Trunc Load

Hello!

I have the following simple IR:

Hi Johannes, what processor are you targeting? Is it little-endian or
big-endian?

Ciao, Duncan.

Hi Johannes, what processor are you targeting? Is it little-endian or
big-endian?

Little-endian. (The truth: you can set it manually, but it is set to little endian, for sure.) The processor is a TI TMS320C64x.

Follow-up: I discovered that the "guilty" method is DAGCombiner::ReduceLoadWidth. The error is introduced because the offset is not calculated correctly.

The first problem is that the pointer I get for loading does not point to the address of the low word, but to the address of the high word.
The second problem is that this is apparently correct as long as lddw is used instead of ldw.

Do you have any ideas on this?

(The third problem is that the creation of the pointer is not my doing. I'm just extending our backend to support i64 additionally (instead of just i32 and smaller). Doing this turns out to be trickier than expected.)

Cheers,
Johannes

This is contradictory: on a little-endian processor, the address for
loading a 64-bit value is same as the address of the low word. Are
you sure you're modeling the semantics of your lddw and stddw
instructions correctly?

-Eli

This is contradictory: on a little-endian processor, the address for
loading a 64-bit value is same as the address of the low word. Are
you sure you're modeling the semantics of your lddw and stddw
instructions correctly?

... I thought so until now. Because I implemented stdw (store doubleword) completely analogous to lddw: Just print out stdw with the given pointer and the register pair, just like lddw. (This seems obvious.)

Well, ****. I just read the documentation very carefully (yeah I know. I'm sorry) and it seems that stdw doesn't care about the big/little endian setting, it always writes the regpair into memory in big endian. lddw, however, DOES care about the setting - if little endian is enabled, the result register pair gets switched. What kind of confusion could have provoked the TI engineers to create such a horrible instruction set?

OK, thanks for the hints. I'll try to sort this out.

Cheers!
Johannes

To finally sort this out, and perhaps save my reputation should anyone read this:

I discovered the error, and it has nothing to do with endianness. In the generated assembler, the global variable was declared like this: ".bss _m, 8", and it should have been declared like this: ".bss, _m, 8, 8". Really. That's it.

I still don't know exactly how stdw behaves, because the documentation really implies that stdw doesn't care about the endian setting, while lddw does, but apparently you don't have to care. Using stdw and lddw in analogous fashion is OK, at least in little endian mode. So much for confusion.

Regards,
Johannes