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

[InstCombine] Generalise ((x1 ^ y1) | (x2 ^ y2)) == 0 transform to more than two pairs of variables #57831

Closed
Kmeakin opened this issue Sep 19, 2022 · 2 comments

Comments

@Kmeakin
Copy link
Contributor

Kmeakin commented Sep 19, 2022

InstCombine currently recognises ((x1 ^ y1) | (x2 ^ y2)) == 0 as an idiom for x1 == y1 && x2 == y2, but this idiom detection does not work when more than 2 pairs of variables are being compared:

This function

bool xor2(uint64_t x1, uint64_t y1, uint64_t x2, uint64_t y2) {
    return ((x1 ^ y1) | (x2 ^ y2)) == 0;
}

is simplified to

define i1 @xor2(i64 %0, i64 %1, i64 %2, i64 %3) {
  %5 = icmp eq i64 %0, %1
  %6 = icmp eq i64 %2, %3
  %7 = and i1 %5, %6
  ret i1 %7
}

But these two functions are not:

bool xor3(uint64_t x1, uint64_t y1, uint64_t x2, uint64_t y2, uint64_t x3,
          uint64_t y3) {
    return ((x1 ^ y1) | (x2 ^ y2) | (x3 ^ y3)) == 0;
}

bool xor4(uint64_t x1, uint64_t y1, uint64_t x2, uint64_t y2, uint64_t x3,
          uint64_t y3, uint64_t x4, uint64_t y4) {
    return ((x1 ^ y1) | (x2 ^ y2) | (x3 ^ y3) | (x4 ^ y4)) == 0;
}
define i1 @xor3(i64 %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5) {
  %7 = xor i64 %1, %0
  %8 = xor i64 %3, %2
  %9 = or i64 %8, %7
  %10 = xor i64 %5, %4
  %11 = or i64 %9, %10
  %12 = icmp eq i64 %11, 0
  ret i1 %12
}

define i1 @xor4(i64 %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5, i64 %6, i64 %7) {
  %9 = xor i64 %1, %0
  %10 = xor i64 %3, %2
  %11 = or i64 %10, %9
  %12 = xor i64 %5, %4
  %13 = or i64 %11, %12
  %14 = xor i64 %7, %6
  %15 = or i64 %13, %14
  %16 = icmp eq i64 %15, 0
  ret i1 %16
}

godbolt

@kitaisreal
Copy link
Contributor

Patch for the generalization: https://reviews.llvm.org/D154306.

goldsteinn pushed a commit that referenced this issue Jul 15, 2023
Generalise ((x1 ^ y1) | (x2 ^ y2)) == 0 transform to more than two pairs of variables #57831.
Depends D154384.

Reviewed By: goldstein.w.n, nikic

Differential Revision: https://reviews.llvm.org/D154306
@kitaisreal kitaisreal self-assigned this Jul 21, 2023
@kitaisreal
Copy link
Contributor

Closed in da822ce.

veselypeta pushed a commit to veselypeta/cherillvm that referenced this issue Sep 6, 2024
Generalise ((x1 ^ y1) | (x2 ^ y2)) == 0 transform to more than two pairs of variables llvm/llvm-project#57831.
Depends D154384.

Reviewed By: goldstein.w.n, nikic

Differential Revision: https://reviews.llvm.org/D154306
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants