This is an archive of the discontinued LLVM Phabricator instance.

GlobalISel: Lower scalarizing unmerge of a vector to shifts
ClosedPublic

Authored by arsenm on Jul 30 2019, 6:33 AM.

Details

Summary

AMDGPU sometimes has legal s16 and <2 x s16> operations, but all
registers are really 32-bit. An unmerge destination really should ben
widened to a 32-bit register. If widening a scalarizing vector with a
target size that matches the vector size, bitcast to integer and
extract the relevant bits with shifts.

I'm not sure if this is the right place for this. This could arguably
be part of widenScalar for the result. I also have a growing feeling
that we're missing a bitcast legalize action.

Diff Detail

Event Timeline

arsenm created this revision.Jul 30 2019, 6:33 AM
dsanders accepted this revision.Jul 30 2019, 6:58 PM

This makes sense to me. LGTM

I also have a growing feeling that we're missing a bitcast legalize action.

I assume the definition of that would be something like:

%1:(x) = OP %0:(x)

to

%2:(y) = G_BITCAST %0:(x)
%3:(y) = NEW_OP %2:(y)
%1:(x) = G_BITCAST %3:(y)

and is somewhat similar in principle to lower but sidesteps instead of simplifying, or alternatively is somewhat like libcall but injects code inline instead of calling.

I can't think of a place I'd want to use it over one of the current actions but it sounds like it ought to be useful. Maybe for doing pointer operations using scalar operations? Do you have anything specific in mind?

This revision is now accepted and ready to land.Jul 30 2019, 6:58 PM

This makes sense to me. LGTM

I also have a growing feeling that we're missing a bitcast legalize action.

I assume the definition of that would be something like:

%1:(x) = OP %0:(x)

to

%2:(y) = G_BITCAST %0:(x)
%3:(y) = NEW_OP %2:(y)
%1:(x) = G_BITCAST %3:(y)

and is somewhat similar in principle to lower but sidesteps instead of simplifying, or alternatively is somewhat like libcall but injects code inline instead of calling.

I can't think of a place I'd want to use it over one of the current actions but it sounds like it ought to be useful. Maybe for doing pointer operations using scalar operations? Do you have anything specific in mind?

I’m specifically thinking of load and store. I want to treat these as blindly loading bits, and never splitting them up to get legal types. I can get pretty far treating all loads as legal and unmerge should naturally do the right thing, but it’s awkward for store since it implies a lot of strange truncates will need to be handled

This makes sense to me. LGTM

I also have a growing feeling that we're missing a bitcast legalize action.

I assume the definition of that would be something like:

%1:(x) = OP %0:(x)

to

%2:(y) = G_BITCAST %0:(x)
%3:(y) = NEW_OP %2:(y)
%1:(x) = G_BITCAST %3:(y)

and is somewhat similar in principle to lower but sidesteps instead of simplifying, or alternatively is somewhat like libcall but injects code inline instead of calling.

I can't think of a place I'd want to use it over one of the current actions but it sounds like it ought to be useful. Maybe for doing pointer operations using scalar operations? Do you have anything specific in mind?

I’m specifically thinking of load and store. I want to treat these as blindly loading bits, and never splitting them up to get legal types.
I can get pretty far treating all loads as legal and unmerge should naturally do the right thing, but it’s awkward for store since it implies a lot of strange truncates will need to be handled

That makes sense. I can see that case for a Bitcast action being useful for quite a few targets with the notable exceptions being the rare few where G_BITCAST isn't a nop (only big-endian MIPS MSA and big-endian ARM NEON that I know of).

arsenm closed this revision.Aug 1 2019, 12:10 PM

r367604 with different test changes due to rebasing to be independent of my other unmerge legalization patches