This is an archive of the discontinued LLVM Phabricator instance.

[X86] When promoting i16 compare with immediate to i32, try to use sign_extend for eq/ne if the input is truncated from a type with enough sign its.
ClosedPublic

Authored by craig.topper on Jun 7 2019, 3:50 PM.

Details

Summary

Our default behavior is to use sign_extend for signed comparisons and zero_extend for everything. But for equality we have the freedom to use either extension. If we can prove the input has been truncated from something with enough sign bits, we can use sign_extend instead and let DAG combine optimize it out. A similar rule is used by type legalization in LegalizeIntegerTypes.

This gets rid of the movzx in PR42189. The immediate will still take 4 bytes instead of the 2 bytes plus 0x66 prefix a cmp di, 32767 would get, but it avoids a length changing prefix.

I refactored this code to handle floating point first to remove one level indentation in the integer path. I can pre-commit some of the refactoring if reviewers want.

Diff Detail

Repository
rL LLVM

Event Timeline

craig.topper created this revision.Jun 7 2019, 3:50 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 7 2019, 3:50 PM
Herald added a subscriber: hiraditya. · View Herald Transcript
xbolva00 accepted this revision.Jun 8 2019, 4:57 PM

Thanks for the implementation

This revision is now accepted and ready to land.Jun 8 2019, 4:57 PM

Maybe similar opportunity? But not sure if improvement..

char c() {

return 11;

}

Clang
mov al, 11
GCC and ICC
mov eax 11

Maybe similar opportunity? But not sure if improvement..

char c() {

return 11;

}

Clang
mov al, 11
GCC and ICC
mov eax 11

I think the icc/gcc version is 6 bytes. clang's version is 3 bytes. But its a partial register update which on Sandybridge and later has a false dependency on the previous writer of al/ax/eax to merge the upper bits.

This revision was automatically updated to reflect the committed changes.