This is an archive of the discontinued LLVM Phabricator instance.

[RISCV] Sign extend constant arguments to V intrinsics when promoting to XLen.
ClosedPublic

Authored by craig.topper on Dec 17 2020, 12:49 PM.

Details

Summary

The default behavior for any_extend of a constant is to zero extend.
This occurs inside of getNode rather than allowing type legalization
to promote the constant which would sign extend. By using sign extend
with getNode the constant will be sign extended. This gives a better
chance for isel to find a simm5 immediate since all xlen bits are
examined there.

For instructions that use a uimm5 immediate, this change only affects
constants >= 128 for i8 or >= 32768 for i16. Constants that large
already wouldn't have been eligible for uimm5 and would need to use a
scalar register.

If the instruction isn't able to use simm5 or the immediate is
too large, we'll need to materialize the immediate in a register.
As far as I know constants with all 1s in the upper bits should
materialize as well or better than all 0s.

Longer term we should probably have a SEW aware PatFrag to ignore
the bits above SEW before checking simm5.

I updated about half the test cases in some tests to use a negative
constant to get coverage for this.

Diff Detail

Event Timeline

craig.topper created this revision.Dec 17 2020, 12:49 PM
craig.topper requested review of this revision.Dec 17 2020, 12:49 PM
Herald added a project: Restricted Project. · View Herald TranscriptDec 17 2020, 12:49 PM
Herald added a subscriber: MaskRay. · View Herald Transcript

For instructions that use a uimm5 immediate, this change only affects
constants >= 128 for i8 or >= 32768 for i16. Constants that large
already wouldn't have been eligible for uimm5 and would need to use a
scalar register.

Just to make sure I understand this case, this is relevant for negative numbers which at this point of the backend just look like like very large constants (up to XLenVT).

Other than that, LGTM. Thanks @craig.topper

For instructions that use a uimm5 immediate, this change only affects
constants >= 128 for i8 or >= 32768 for i16. Constants that large
already wouldn't have been eligible for uimm5 and would need to use a
scalar register.

Just to make sure I understand this case, this is relevant for negative numbers which at this point of the backend just look like like very large constants (up to XLenVT).

Other than that, LGTM. Thanks @craig.topper

That was me thinking through making sure this wouldn't break shifts and other instructions that use uimm5. If for some reason an SEW=8 shift had 128 as a constant, previously it would have stayed 128 when we extended it to xlenvt. Now it becomes 0xffffffffffffff80. But neither 128 or 0xffffffffffffff80 would be matched by uimm5 so this shouldn't break those instructions.

evandro accepted this revision.Dec 18 2020, 8:50 AM

LGTM

This revision is now accepted and ready to land.Dec 18 2020, 8:50 AM