Skip to content

[InstCombine] Fold negation of calls to ucmp/scmp by swapping its operands #98360

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

Merged
merged 3 commits into from
Jul 10, 2024

Conversation

Poseydon42
Copy link
Contributor

@llvmbot
Copy link
Member

llvmbot commented Jul 10, 2024

@llvm/pr-subscribers-llvm-transforms

Author: None (Poseydon42)

Changes

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


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

3 Files Affected:

  • (modified) llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp (+5)
  • (modified) llvm/test/Transforms/InstCombine/scmp.ll (+12)
  • (modified) llvm/test/Transforms/InstCombine/ucmp.ll (+12)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp b/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
index b3426562a4d87..9ad594a6d7d61 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
@@ -222,6 +222,11 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
     }
     break;
   }
+  case Instruction::Call:
+    if (auto *CI = dyn_cast<CmpIntrinsic>(I))
+      return Builder.CreateIntrinsic(CI->getType(), CI->getIntrinsicID(),
+                                     {CI->getRHS(), CI->getLHS()});
+    break;
   default:
     break; // Other instructions require recursive reasoning.
   }
diff --git a/llvm/test/Transforms/InstCombine/scmp.ll b/llvm/test/Transforms/InstCombine/scmp.ll
index 4f903a79afd5d..80b32e73a757d 100644
--- a/llvm/test/Transforms/InstCombine/scmp.ll
+++ b/llvm/test/Transforms/InstCombine/scmp.ll
@@ -154,3 +154,15 @@ define i1 @scmp_sle_neg_1(i32 %x, i32 %y) {
   %2 = icmp sle i8 %1, -1
   ret i1 %2
 }
+
+; ========== Fold -scmp(x, y) => scmp(y, x) ==========
+define i8 @scmp_negated(i32 %x, i32 %y) {
+; CHECK-LABEL: define i8 @scmp_negated(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[TMP2:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])
+; CHECK-NEXT:    ret i8 [[TMP2]]
+;
+  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
+  %2 = sub i8 0, %1
+  ret i8 %2
+}
diff --git a/llvm/test/Transforms/InstCombine/ucmp.ll b/llvm/test/Transforms/InstCombine/ucmp.ll
index 9ab67560c9117..74313403d7c0c 100644
--- a/llvm/test/Transforms/InstCombine/ucmp.ll
+++ b/llvm/test/Transforms/InstCombine/ucmp.ll
@@ -154,3 +154,15 @@ define i1 @ucmp_sle_neg_1(i32 %x, i32 %y) {
   %2 = icmp sle i8 %1, -1
   ret i1 %2
 }
+
+; ========== Fold -ucmp(x, y) => ucmp(y, x) ==========
+define i8 @ucmp_negated(i32 %x, i32 %y) {
+; CHECK-LABEL: define i8 @ucmp_negated(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[TMP2:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[Y]], i32 [[X]])
+; CHECK-NEXT:    ret i8 [[TMP2]]
+;
+  %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
+  %2 = sub i8 0, %1
+  ret i8 %2
+}

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.

Could you please add multi-use tests? I don't think we'd want to fold in that case, as replacing a negation with another ucmp/scmp doesn't seem profitable.

@Poseydon42
Copy link
Contributor Author

Fixed.

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.

LGTM

@nikic nikic merged commit 8c664a9 into llvm:main Jul 10, 2024
5 of 6 checks passed
aaryanshukla pushed a commit to aaryanshukla/llvm-project that referenced this pull request Jul 14, 2024
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.

3 participants