This is an archive of the discontinued LLVM Phabricator instance.

[RISCV] When matching SROIW, check all 64 bits of the OR mask
ClosedPublic

Authored by craig.topper on Nov 6 2020, 11:30 AM.

Details

Summary

We need to make sure the upper 32 bits are all ones to ensure the result is properly sign extended. Previously we only checked the lower 32 bits of the mask. I've also added a check that the shift amount is less than 32. Without that the original code asserts if the SROI check is removed or the SROIW pattern is checked first. I've refactored the code to use early outs to reduce nesting.

I've also updated SLOIW matching with the same changes, but I couldn't find a broken test case with the existing code.

Diff Detail

Event Timeline

craig.topper created this revision.Nov 6 2020, 11:30 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 6 2020, 11:30 AM
craig.topper requested review of this revision.Nov 6 2020, 11:30 AM
craig.topper edited the summary of this revision. (Show Details)

Update SelectSLOIW in the same way. Check all bits of the mask and check the shift amount is less than 32. I haven't been able to produce any incorrect tests for sloiw though.

frasercrmck accepted this revision.Nov 16 2020, 6:47 AM

Apart from my nits, this makes sense to me. The only thing I don't fully get it where/why the original code asserted if the shift amount was >= 32.

Regarding SLOIW I'm not sure you'll find a test case where the mask isn't wholly contained in the 32 lower bits since the or and the shl are i32 operations. But I don't think it hurts to check all 64 bits.

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
317–318

Your changes to SROIW also mention the constraint VC2 < 32 so I reckon it should be stated here too

321–344

Comment here should say "SLOIW"

This revision is now accepted and ready to land.Nov 16 2020, 6:47 AM

Apart from my nits, this makes sense to me. The only thing I don't fully get it where/why the original code asserted if the shift amount was >= 32.

The assert is inside maskLeadingOnes<uint32_t>. There's a check that the bit count passed in is <= that size of the type passed as the template parameter.

Regarding SLOIW I'm not sure you'll find a test case where the mask isn't wholly contained in the 32 lower bits since the or and the shl are i32 operations. But I don't think it hurts to check all 64 bits.