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] Folding (icmp eq/ne (and X, -P2), INT_MIN) #110880

Closed

Conversation

goldsteinn
Copy link
Contributor

@goldsteinn goldsteinn commented Oct 2, 2024

  • [InstCombine] Add tests for folding (icmp eq/ne (and X, -P2), INT_MIN); NFC
  • [InstCombine] Folding (icmp eq/ne (and X, -P2), INT_MIN)

Folds to (icmp slt/sge X, (INT_MIN + P2))

Proofs: https://alive2.llvm.org/ce/z/vpNFY5

@goldsteinn goldsteinn requested a review from nikic as a code owner October 2, 2024 16:21
@goldsteinn goldsteinn changed the title goldsteinn/fold icmp and signmask [InstCombine] Folding (icmp eq/ne (and X, -P2), INT_MIN) Oct 2, 2024
@goldsteinn goldsteinn requested a review from dtcxzyw October 2, 2024 16:21
@llvmbot
Copy link
Member

llvmbot commented Oct 2, 2024

@llvm/pr-subscribers-llvm-transforms

Author: None (goldsteinn)

Changes
  • [InstCombine] Add tests for folding (icmp eq/ne (and X, -P2), INT_MIN); NFC
  • [InstCombine] Folding (icmp eq/ne (and X, -P2), INT_MIN)

Folds to (icmp slt/sge X, (INT_MIN + P2))

Proofs: https://alive2.llvm.org/ce/z/vpNFY5


Full diff: https://github.com/llvm/llvm-project/pull/110880.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp (+16)
  • (added) llvm/test/Transforms/InstCombine/icmp-signmask.ll (+54)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index b0771ffcc38a83..5e1d9a1c52b2f2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -5015,6 +5015,22 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I,
     }
   }
 
+  // (icmp eq/ne (X, -P2), INT_MIN)
+  //	-> (icmp slt/sge X, INT_MIN + P2)
+  if (ICmpInst::isEquality(Pred) && BO0 &&
+      match(I.getOperand(1), m_SignMask())) {
+    Value *X;
+    if (match(BO0, m_And(m_Value(X), m_CheckedInt([](const APInt &C) {
+                           return C.isZero() || C.isNegatedPowerOf2();
+                         })))) {
+      // Will Constant fold.
+      Value *NewC = Builder.CreateSub(I.getOperand(1), BO0->getOperand(1));
+      return new ICmpInst(Pred == ICmpInst::ICMP_EQ ? ICmpInst::ICMP_SLT
+                                                    : ICmpInst::ICMP_SGE,
+                          X, NewC);
+    }
+  }
+
   {
     // Similar to above: an unsigned overflow comparison may use offset + mask:
     // ((Op1 + C) & C) u<  Op1 --> Op1 != 0
diff --git a/llvm/test/Transforms/InstCombine/icmp-signmask.ll b/llvm/test/Transforms/InstCombine/icmp-signmask.ll
new file mode 100644
index 00000000000000..5424f7d7e8021f
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/icmp-signmask.ll
@@ -0,0 +1,54 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+define i1 @cmp_x_and_negp2_with_eq(i8 %x) {
+; CHECK-LABEL: @cmp_x_and_negp2_with_eq(
+; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[X:%.*]], -126
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %andx = and i8 %x, -2
+  %r = icmp eq i8 %andx, 128
+  ret i1 %r
+}
+
+define i1 @cmp_x_and_negp2_with_eq_fail_not_signmask(i8 %x) {
+; CHECK-LABEL: @cmp_x_and_negp2_with_eq_fail_not_signmask(
+; CHECK-NEXT:    [[ANDX:%.*]] = and i8 [[X:%.*]], -2
+; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[ANDX]], -124
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %andx = and i8 %x, -2
+  %r = icmp eq i8 %andx, 132
+  ret i1 %r
+}
+
+define <2 x i1> @cmp_x_and_negp2_with_ne(<2 x i8> %x) {
+; CHECK-LABEL: @cmp_x_and_negp2_with_ne(
+; CHECK-NEXT:    [[R:%.*]] = icmp sgt <2 x i8> [[X:%.*]], <i8 -121, i8 -113>
+; CHECK-NEXT:    ret <2 x i1> [[R]]
+;
+  %andx = and <2 x i8> %x, <i8 -8, i8 -16>
+  %r = icmp ne <2 x i8> %andx, <i8 128, i8 128>
+  ret <2 x i1> %r
+}
+
+define <2 x i1> @cmp_x_and_negp2_with_ne_or_z(<2 x i8> %x) {
+; CHECK-LABEL: @cmp_x_and_negp2_with_ne_or_z(
+; CHECK-NEXT:    [[R:%.*]] = icmp sge <2 x i8> [[X:%.*]], <i8 -128, i8 -112>
+; CHECK-NEXT:    ret <2 x i1> [[R]]
+;
+  %andx = and <2 x i8> %x, <i8 0, i8 -16>
+  %r = icmp ne <2 x i8> %andx, <i8 128, i8 128>
+  ret <2 x i1> %r
+}
+
+define <2 x i1> @cmp_x_and_negp2_with_ne_fail_not_p2(<2 x i8> %x) {
+; CHECK-LABEL: @cmp_x_and_negp2_with_ne_fail_not_p2(
+; CHECK-NEXT:    [[ANDX:%.*]] = and <2 x i8> [[X:%.*]], <i8 -8, i8 -15>
+; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i8> [[ANDX]], <i8 -128, i8 -128>
+; CHECK-NEXT:    ret <2 x i1> [[R]]
+;
+  %andx = and <2 x i8> %x, <i8 -8, i8 -15>
+  %r = icmp ne <2 x i8> %andx, <i8 128, i8 128>
+  ret <2 x i1> %r
+}

Copy link
Member

@dtcxzyw dtcxzyw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG

// -> (icmp slt/sge X, INT_MIN + P2)
if (ICmpInst::isEquality(Pred) && BO0 &&
match(I.getOperand(1), m_SignMask())) {
Value *X;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's already a Value *X declaration above, so you can drop this one and merge both ifs.

@goldsteinn goldsteinn closed this in a646436 Oct 3, 2024
xgupta pushed a commit to xgupta/llvm-project that referenced this pull request Oct 4, 2024
@vitalybuka
Copy link
Collaborator

@eugenis

Looks like this breaks msan
https://lab.llvm.org/buildbot/#/builders/164/builds/3279

And I mean msan itself, not the code.
Similar bot on released compiler, and same code, does not repor https://lab.llvm.org/buildbot/#/builders/169

@goldsteinn
Copy link
Contributor Author

@eugenis

Looks like this breaks msan https://lab.llvm.org/buildbot/#/builders/164/builds/3279

And I mean msan itself, not the code. Similar bot on released compiler, and same code, does not repor https://lab.llvm.org/buildbot/#/builders/169

Hmm? As in MSAN no longer works correctly when compiled with this PR?

@vitalybuka
Copy link
Collaborator

vitalybuka commented Oct 4, 2024

@eugenis
Looks like this breaks msan https://lab.llvm.org/buildbot/#/builders/164/builds/3279
And I mean msan itself, not the code. Similar bot on released compiler, and same code, does not repor https://lab.llvm.org/buildbot/#/builders/169

Hmm? As in MSAN no longer works correctly when compiled with this PR?

Yes, I bisected locally..
Reports looks wrong https://lab.llvm.org/buildbot/#/builders/164/builds/3279/steps/14/logs/stdio

@goldsteinn
Copy link
Contributor Author

@eugenis
Looks like this breaks msan https://lab.llvm.org/buildbot/#/builders/164/builds/3279
And I mean msan itself, not the code. Similar bot on released compiler, and same code, does not repor https://lab.llvm.org/buildbot/#/builders/169

Hmm? As in MSAN no longer works correctly when compiled with this PR?

Yes, I bisected locally.. Reports looks wrong https://lab.llvm.org/buildbot/#/builders/164/builds/3279/steps/14/logs/stdio

Okay, might just be this PR is buggy and causes miscompiles, although its pretty simple and I don't see it.

@eugenis
Copy link
Contributor

eugenis commented Oct 4, 2024

This is a problem with MSan handling of signed comparison - it is not entirely correct as a compromise for performance and code size. Do you mind reverting the change while we figure out how to fix MSan?

@eugenis
Copy link
Contributor

eugenis commented Oct 4, 2024

I can confirm that -msan-handle-icmp-exact=1 avoids this issue, and increases .text size of the clang binary by 2.9%.

@eugenis
Copy link
Contributor

eugenis commented Oct 4, 2024

#111212 to fix MSan.

vitalybuka added a commit that referenced this pull request Oct 5, 2024
…111236)

Reverts #110880 because of exposed issue is Msan instrumentation
#111212.

This reverts commit a646436.
Kyvangka1610 pushed a commit to Kyvangka1610/llvm-project that referenced this pull request Oct 5, 2024
…lvm#111236)

Reverts llvm#110880 because of exposed issue is Msan instrumentation
llvm#111212.

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

Successfully merging this pull request may close these issues.

6 participants