Legalizing truncating store using atomic load.


Our target only has native support for i32 and f32 types. For data
types smaller than these, I have to custom lowering truncating store
using two atomic load instruction (which have the same semantics as
ISD::ATOMIC_LOAD_AND and ATOMIC_LOAD_OR, respectively). I run into a
problem during the legalization process, where the legalizer complains
that ISD::STORE and ISD::ATOMIC_LOAD_OR (generated at step 3 in the
following list) has different types.

Here is the lowering steps:
1. Calculate a bitmask (e.g. 0xFFFF0000 for i16) indicating where to
write the data;
2. Using atomic_load_and and the negated bitmask to clear the bits to
be written;
3. Using atomic_load_or and the bitmask writing the result into the
corresponding position.

I'm not sure whether this could be done using custom lowering, so I'm
writing to ask whether I'm on the right track:
1. If so, how to solve the type difference problem mentioned above;
2. If not, what is the right approach to solve this kind of problem.

Any pointers and guidance are welcomed and appreciated. Thanks!

Lei Mou

Problem solved by returning the second result of the ATOMIC_LOAD_OR node...

Hi Lei,

Problem solved by returning the second result of the ATOMIC_LOAD_OR node...

You got the chain instead of the loaded value.

IMHO, a better solution would have been to add a Pat<> rule to match truncstores and expand them into target store/load/and/or.
Pat : <(truncstore16 GPR:$val, MEM:$mem),
     (store MEM:$mem,
             (and (load MEM:$mem), (i32 0xffff0000))
             , GPR:$val

And you can also write a custom rule for truncstore8 if necessary. See other target BE's for examples.


Hi Ivan,

Thank you for your suggestion. I'll try that!

Lei Mou