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

Support the % N -> & (N - 1) transformation for runtime power-of-two values #58996

Closed
scottmcm opened this issue Nov 15, 2022 · 0 comments · Fixed by #107745
Closed

Support the % N -> & (N - 1) transformation for runtime power-of-two values #58996

scottmcm opened this issue Nov 15, 2022 · 0 comments · Fixed by #107745
Assignees

Comments

@scottmcm
Copy link

I tried sending this to opt

define i16 @src(i16 %x, i16 %y) {
start:
  %0 = tail call i16 @llvm.ctpop.i16(i16 %y)
  %_3 = icmp eq i16 %0, 1
  tail call void @llvm.assume(i1 %_3)
  %_7 = icmp eq i16 %y, 0
  %1 = urem i16 %x, %y
  ret i16 %1
}

expecting it to optimize to something like this

define i16 @tgt(i16 %x, i16 %y) {
start:
  %0 = sub nuw i16 %y, 1
  %1 = and i16 %x, %0
  ret i16 %1
}

but it didn't -- it left the div in the generated assembly.

Alive2 proof that this would be fine: https://alive2.llvm.org/ce/z/irgU2q


If there's a better way to communicate this, then please let me know! Assuming ctpop seemed like the best way, though, since x & (x - 1) == 0 gets normalized down to ctpop <= 1, and thus I assumed that it was the preferred way to tell LLVM the value is a power-of-two.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants