Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

__builtin_popcount(~a) & 1 - > __builtin_popcount(a) & 1 #49440

Closed
davidbolvansky opened this issue Apr 23, 2021 · 6 comments
Closed

__builtin_popcount(~a) & 1 - > __builtin_popcount(a) & 1 #49440

davidbolvansky opened this issue Apr 23, 2021 · 6 comments
Labels
bugzilla Issues migrated from bugzilla

Comments

@davidbolvansky
Copy link
Collaborator

Bugzilla Link 50096
Resolution FIXED
Resolved on Apr 23, 2021 10:52
Version trunk
OS Linux
CC @RKSimon,@rotateright
Fixed by commit(s) rGe10d7d455d4e

Extended Description


define i32 @​src(i32 %0) noread nowrite nofree {
%1:
%2 = xor i32 %0, 4294967295
%3 = ctpop i32 %2
%4 = and i32 %3, 1
ret i32 %4
}
=>
define i32 @​tgt(i32 %0) noread nowrite nofree {
%1:
%2 = ctpop i32 %0
%3 = and i32 %2, 1
ret i32 %3
}
Transformation seems to be correct!

https://godbolt.org/z/hGoxxYYd6

@davidbolvansky
Copy link
Collaborator Author

Hm...

If we have this transformation:


define i8 @​src(i8 %0) {
%1:
%2 = xor i8 %0, 255
%3 = ctpop i8 %2
ret i8 %3
}
=>
define i8 @​tgt(i8 %0) {
%1:
%2 = ctpop i8 %0
%3 = sub i8 8, %2
ret i8 %3
}
Transformation seems to be correct!

Then

int tgt(unsigned int a)
{
return (32 -__builtin_popcount(a)) & 1;
}

is nicely optimised to

tgt(unsigned int): # @​tgt(unsigned int)
popcnt eax, edi
and eax, 1
ret

@​spatel, replace xor with sub, WDYT?

@davidbolvansky
Copy link
Collaborator Author

int A(unsigned int a)
{
return (32 -__builtin_popcount(a));
}

int B(unsigned int a)
{
return (__builtin_popcount(~a)) ;
}

A(unsigned int): # @​A(unsigned int)
popcnt ecx, edi
mov eax, 32
sub eax, ecx
ret
B(unsigned int): # @​B(unsigned int)
not edi
popcnt eax, edi
ret

@rotateright
Copy link
Contributor

int tgt(unsigned int a)
{
return (32 -__builtin_popcount(a)) & 1;
}

is nicely optimised to

tgt(unsigned int): # @​tgt(unsigned int)
popcnt eax, edi
and eax, 1
ret
@​spatel, replace xor with sub, WDYT?

We really should have this folding to "not" in IR:
https://alive2.llvm.org/ce/z/uuo8xa

...because a 'not' is better for analysis than a 'sub'.

If that causes a regression on the parity pattern, we should add another fold for that. I'll take a look.

@rotateright
Copy link
Contributor

https://reviews.llvm.org/rGe10d7d455d4e

Please check if that solves the motivating cases.

We probably still want the sub->not transform, but if it is not showing up, it may not be that important - can either keep this open to track that or open another report.

@davidbolvansky
Copy link
Collaborator Author

Thanks.

I will close this PR and create new one.

@davidbolvansky
Copy link
Collaborator Author

mentioned in issue llvm/llvm-bugzilla-archive#50104

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 11, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla
Projects
None yet
Development

No branches or pull requests

2 participants