This is an archive of the discontinued LLVM Phabricator instance.

[X86] Add a DAG combine for the __builtin_parity idiom used by clang to enable better codegen
ClosedPublic

Authored by craig.topper on Aug 1 2018, 3:59 PM.

Details

Summary

Clang uses "ctpop & 1" to implement __builtin_parity. If the popcnt instruction isn't supported this generates a large amount of code to calculate the population count. Instead we can bisect the data down to a single byte using xor and then check the parity flag.

Even when popcnt is supported, its still a good idea to split 64-bit data on 32-bit targets using an xor in front of a single popcnt. Otherwise we get two popcnts and an add before the and.

I've specifically targeted this at the sizes supported by clang builtins, but we could generalize this if we think that's useful.

I can pre-commit the test cases and show only the changes here if we want.

Diff Detail

Repository
rL LLVM

Event Timeline

craig.topper created this revision.Aug 1 2018, 3:59 PM
RKSimon added inline comments.Aug 2 2018, 7:47 AM
lib/Target/X86/X86ISelLowering.cpp
34720 ↗(On Diff #158656)

isOperationLegal() ?

34732 ↗(On Diff #158656)
if (!isOneConstant(N1))
  return SDValue();

Use isTypeLegal and isOperationLegal

Use isOneConstant

RKSimon accepted this revision.Aug 3 2018, 3:39 AM

LGTM with the test cases pre-committed. Thanks.

This revision is now accepted and ready to land.Aug 3 2018, 3:39 AM
This revision was automatically updated to reflect the committed changes.