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] Fold A == MIN_INT ? B != MIN_INT : A < B to A < B #120177

Merged
merged 2 commits into from
Dec 19, 2024

Conversation

veera-sivarajan
Copy link
Contributor

@veera-sivarajan veera-sivarajan commented Dec 17, 2024

This PR folds:
A == MIN_INT ? B != MIN_INT : A < B to A < B
A == MAX_INT ? B != MAX_INT : A > B to A > B

Proof: https://alive2.llvm.org/ce/z/bR6E2s

This helps in optimizing comparison of optional unsigned non-zero types in rust-lang/rust#49892.

Rust compiler's current output: https://rust.godbolt.org/z/9fxfq3Gn8

@llvmbot
Copy link
Member

llvmbot commented Dec 17, 2024

@llvm/pr-subscribers-llvm-transforms

@llvm/pr-subscribers-llvm-analysis

Author: Veera (veera-sivarajan)

Changes

This PR simplifies:
A == MIN_INT ? B != MIN_INT : A &lt; B to A &lt; B
A == MAX_INT ? B != MAX_INT : A &gt; B to A &gt; B

Proof: https://alive2.llvm.org/ce/z/bR6E2s

This helps in optimizing comparison of optional unsigned non-zero types in rust-lang/rust#49892.

Rust compiler's current output: https://rust.godbolt.org/z/9fxfq3Gn8


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

2 Files Affected:

  • (modified) llvm/lib/Analysis/InstructionSimplify.cpp (+43-1)
  • (added) llvm/test/Transforms/InstSimplify/select-with-extreme-eq-cond.ll (+360)
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 3325cd972cf1eb..fcbaaafe69ec48 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4608,6 +4608,45 @@ static Value *simplifySelectWithEquivalence(Value *CmpLHS, Value *CmpRHS,
   return nullptr;
 }
 
+/// `A == MIN_INT ? B != MIN_INT : A < B` --> `A < B`
+/// `A == MAX_INT ? B != MAX_INT : A > B` --> `A > B`
+static Value *foldSelectWithExtremeEqCond(Value *CmpLHS, Value *CmpRHS,
+                                          Value *TrueVal, Value *FalseVal) {
+  CmpPredicate Pred;
+  Value *A, *B;
+
+  if (!match(FalseVal, m_ICmp(Pred, m_Value(A), m_Value(B))))
+    return nullptr;
+
+  // make sure `CmpLHS` is on the LHS of `FalseVal`.
+  if (match(CmpLHS, m_Specific(B))) {
+    std::swap(A, B);
+    Pred = CmpInst::getSwappedPredicate(Pred);
+  }
+
+  APInt C;
+  unsigned NumBits = A->getType()->getScalarSizeInBits();
+
+  if (ICmpInst::isLT(Pred)) {
+    C = CmpInst::isSigned(Pred) ? APInt::getSignedMinValue(NumBits)
+                                : APInt::getMinValue(NumBits);
+  } else if (ICmpInst::isGT(Pred)) {
+    C = CmpInst::isSigned(Pred) ? APInt::getSignedMaxValue(NumBits)
+                                : APInt::getMaxValue(NumBits);
+  } else {
+    return nullptr;
+  }
+
+  if (!match(CmpLHS, m_Specific(A)) || !match(CmpRHS, m_SpecificInt(C)))
+    return nullptr;
+
+  if (!match(TrueVal, m_SpecificICmp(ICmpInst::ICMP_NE, m_Specific(B),
+                                     m_SpecificInt(C))))
+    return nullptr;
+
+  return FalseVal;
+}
+
 /// Try to simplify a select instruction when its condition operand is an
 /// integer comparison.
 static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
@@ -4728,6 +4767,10 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
                                                    Q, MaxRecurse))
         return V;
     }
+
+    if (Value *V =
+            foldSelectWithExtremeEqCond(CmpLHS, CmpRHS, TrueVal, FalseVal))
+      return V;
   }
 
   return nullptr;
@@ -7141,7 +7184,6 @@ static Value *simplifyInstructionWithOperands(Instruction *I,
                             NewOps[1], I->getFastMathFlags(), Q, MaxRecurse);
   case Instruction::Select:
     return simplifySelectInst(NewOps[0], NewOps[1], NewOps[2], Q, MaxRecurse);
-    break;
   case Instruction::GetElementPtr: {
     auto *GEPI = cast<GetElementPtrInst>(I);
     return simplifyGEPInst(GEPI->getSourceElementType(), NewOps[0],
diff --git a/llvm/test/Transforms/InstSimplify/select-with-extreme-eq-cond.ll b/llvm/test/Transforms/InstSimplify/select-with-extreme-eq-cond.ll
new file mode 100644
index 00000000000000..3fa9468035cb7a
--- /dev/null
+++ b/llvm/test/Transforms/InstSimplify/select-with-extreme-eq-cond.ll
@@ -0,0 +1,360 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+define i1 @compare_unsigned_min(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @compare_unsigned_min(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+start:
+  %2 = icmp eq i8 %0, 0
+  %3 = icmp ne i8 %1, 0
+  %4 = icmp ult i8 %0, %1
+  %result = select i1 %2, i1 %3, i1 %4
+  ret i1 %result
+}
+
+define i1 @compare_signed_min(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @compare_signed_min(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp slt i8 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP4]]
+;
+start:
+  %2 = icmp eq i8 %0, -128
+  %3 = icmp ne i8 %1, -128
+  %4 = icmp slt i8 %0, %1
+  %result = select i1 %2, i1 %3, i1 %4
+  ret i1 %result
+}
+
+define i1 @compare_unsigned_max(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @compare_unsigned_max(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp ugt i8 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP4]]
+;
+start:
+  %2 = icmp eq i8 %0, 255
+  %3 = icmp ne i8 %1, 255
+  %4 = icmp ugt i8 %0, %1
+  %result = select i1 %2, i1 %3, i1 %4
+  ret i1 %result
+}
+
+define i1 @compare_signed_max(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @compare_signed_max(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp sgt i8 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP4]]
+;
+start:
+  %2 = icmp eq i8 %0, 127
+  %3 = icmp ne i8 %1, 127
+  %4 = icmp sgt i8 %0, %1
+  %result = select i1 %2, i1 %3, i1 %4
+  ret i1 %result
+}
+
+define i1 @relational_cmp_unsigned_min(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @relational_cmp_unsigned_min(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i8 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP4]]
+;
+start:
+  %2 = icmp ule i8 %0, 0
+  %3 = icmp ugt i8 %1, 0
+  %4 = icmp ult i8 %0, %1
+  %result = select i1 %2, i1 %3, i1 %4
+  ret i1 %result
+}
+
+define i1 @relational_cmp_signed_min(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @relational_cmp_signed_min(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp slt i8 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP4]]
+;
+start:
+  %2 = icmp sle i8 %0, -128
+  %3 = icmp sgt i8 %1, -128
+  %4 = icmp slt i8 %0, %1
+  %result = select i1 %2, i1 %3, i1 %4
+  ret i1 %result
+}
+
+define i1 @relational_cmp_unsigned_max(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @relational_cmp_unsigned_max(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp ugt i8 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP4]]
+;
+start:
+  %2 = icmp uge i8 %0, 255
+  %3 = icmp ult i8 %1, 255
+  %4 = icmp ugt i8 %0, %1
+  %result = select i1 %2, i1 %3, i1 %4
+  ret i1 %result
+}
+
+define i1 @relational_cmp_signed_max(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @relational_cmp_signed_max(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp sgt i8 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP4]]
+;
+start:
+  %2 = icmp sge i8 %0, 127
+  %3 = icmp slt i8 %1, 127
+  %4 = icmp sgt i8 %0, %1
+  %result = select i1 %2, i1 %3, i1 %4
+  ret i1 %result
+}
+
+declare void @use(i1)
+
+define i1 @compare_signed_max_multiuse(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @compare_signed_max_multiuse(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp sgt i8 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    call void @use(i1 [[TMP4]])
+; CHECK-NEXT:    ret i1 [[TMP4]]
+;
+start:
+  %2 = icmp eq i8 %0, 127
+  %3 = icmp ne i8 %1, 127
+  %4 = icmp sgt i8 %0, %1
+  call void @use(i1 %4)
+  %result = select i1 %2, i1 %3, i1 %4
+  ret i1 %result
+}
+
+define i1 @compare_signed_min_samesign(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @compare_signed_min_samesign(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp samesign slt i8 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP4]]
+;
+start:
+  %2 = icmp eq i8 %0, -128
+  %3 = icmp ne i8 %1, -128
+  %4 = icmp samesign slt i8 %0, %1
+  %result = select i1 %2, i1 %3, i1 %4
+  ret i1 %result
+}
+
+define i1 @compare_flipped(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @compare_flipped(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp ugt i8 [[TMP1]], [[TMP0]]
+; CHECK-NEXT:    ret i1 [[TMP4]]
+;
+start:
+  %2 = icmp eq i8 %0, 0
+  %3 = icmp ne i8 %1, 0
+  %4 = icmp ugt i8 %1, %0
+  %result = select i1 %2, i1 %3, i1 %4
+  ret i1 %result
+}
+
+define i1 @compare_swapped(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @compare_swapped(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    [[RESULT:%.*]] = icmp ult i8 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+start:
+  %2 = icmp ne i8 %0, 0
+  %3 = icmp ne i8 %1, 0
+  %4 = icmp ult i8 %0, %1
+  %result = select i1 %2, i1 %4, i1 %3
+  ret i1 %result
+}
+
+define i1 @compare_swapped_flipped_unsigned_max(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @compare_swapped_flipped_unsigned_max(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[TMP0]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+start:
+  %2 = icmp ne i8 %0, 255
+  %3 = icmp ne i8 %1, 255
+  %4 = icmp ult i8 %1, %0
+  %result = select i1 %2, i1 %4, i1 %3
+  ret i1 %result
+}
+
+define i1 @compare_unsigned_min_illegal_type(i9 %0, i9 %1) {
+; CHECK-LABEL: define i1 @compare_unsigned_min_illegal_type(
+; CHECK-SAME: i9 [[TMP0:%.*]], i9 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i9 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+start:
+  %2 = icmp eq i9 %0, 0
+  %3 = icmp ne i9 %1, 0
+  %4 = icmp ult i9 %0, %1
+  %result = select i1 %2, i1 %3, i1 %4
+  ret i1 %result
+}
+
+define <2 x i1> @compare_vector(<2 x i8> %x, <2 x i8> %y) {
+; CHECK-LABEL: define <2 x i1> @compare_vector(
+; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult <2 x i8> [[X]], [[Y]]
+; CHECK-NEXT:    ret <2 x i1> [[TMP1]]
+;
+  %2 = icmp eq <2 x i8> %x, <i8 0, i8 0>
+  %3 = icmp ne <2 x i8> %y, <i8 0, i8 0>
+  %4 = icmp ult <2 x i8> %x, %y
+  %result = select <2 x i1> %2, <2 x i1> %3, <2 x i1> %4
+  ret <2 x i1> %result
+}
+
+define i1 @compare_float_negative(half %0, half %1) {
+; CHECK-LABEL: define i1 @compare_float_negative(
+; CHECK-SAME: half [[TMP0:%.*]], half [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fcmp oeq half [[TMP0]], 0xH0000
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp one half [[TMP1]], 0xH0000
+; CHECK-NEXT:    [[TMP4:%.*]] = fcmp ult half [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    [[RESULT:%.*]] = select i1 [[TMP2]], i1 [[TMP3]], i1 [[TMP4]]
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+start:
+  %2 = fcmp oeq half %0, 0.0
+  %3 = fcmp one half %1, 0.0
+  %4 = fcmp ult half %0, %1
+  %result = select i1 %2, i1 %3, i1 %4
+  ret i1 %result
+}
+
+define i1 @compare_unsigned_max_swapped_lhs_rhs_negative(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @compare_unsigned_max_swapped_lhs_rhs_negative(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[TMP0]], -1
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp ne i8 [[TMP1]], -1
+; CHECK-NEXT:    [[RESULT:%.*]] = select i1 [[DOTNOT]], i1 [[TMP2]], i1 false
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+start:
+  %2 = icmp eq i8 %0, 255
+  %3 = icmp ne i8 %1, 255
+  %4 = icmp ugt i8 %0, %1
+  %result = select i1 %3, i1 %2, i1 %4
+  ret i1 %result
+}
+
+define i1 @compare_signed_min_negative(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @compare_signed_min_negative(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[TMP0]], -127
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i8 [[TMP1]], -127
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp slt i8 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    [[RESULT:%.*]] = select i1 [[TMP2]], i1 [[TMP3]], i1 [[TMP4]]
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+start:
+  %2 = icmp eq i8 %0, -127
+  %3 = icmp ne i8 %1, -127
+  %4 = icmp slt i8 %0, %1
+  %result = select i1 %2, i1 %3, i1 %4
+  ret i1 %result
+}
+
+define i1 @compare_unsigned_max_negative(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @compare_unsigned_max_negative(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[TMP0]], -1
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i8 [[TMP1]], -1
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i8 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    [[RESULT:%.*]] = select i1 [[TMP2]], i1 [[TMP3]], i1 [[TMP4]]
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+start:
+  %2 = icmp eq i8 %0, 255
+  %3 = icmp ne i8 %1, 255
+  %4 = icmp ult i8 %0, %1
+  %result = select i1 %2, i1 %3, i1 %4
+  ret i1 %result
+}
+
+define i1 @non_strict_op_negative(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @non_strict_op_negative(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[TMP0]], 0
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i8 [[TMP1]], 0
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp ule i8 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    [[RESULT:%.*]] = select i1 [[TMP2]], i1 [[TMP3]], i1 [[TMP4]]
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+start:
+  %2 = icmp eq i8 %0, 0
+  %3 = icmp ne i8 %1, 0
+  %4 = icmp ule i8 %0, %1
+  %result = select i1 %2, i1 %3, i1 %4
+  ret i1 %result
+}
+
+define i1 @compare_poison_negative(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @compare_poison_negative(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    ret i1 poison
+;
+start:
+  %2 = icmp eq i8 %0, 0
+  %3 = icmp ne i8 poison, 0
+  %4 = icmp ult i8 %0, poison
+  %result = select i1 %2, i1 %3, i1 %4
+  ret i1 %result
+}
+
+define i1 @compare_cond_poison_negative(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @compare_cond_poison_negative(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    ret i1 poison
+;
+start:
+  %2 = icmp eq i8 %0, poison
+  %3 = icmp ne i8 %1, 0
+  %4 = icmp ult i8 %0, %1
+  %result = select i1 %2, i1 %3, i1 %4
+  ret i1 %result
+}
+
+define i1 @compare_true_poison_negative(i8 %0, i8 %1) {
+; CHECK-LABEL: define i1 @compare_true_poison_negative(
+; CHECK-SAME: i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) {
+; CHECK-NEXT:  [[START:.*:]]
+; CHECK-NEXT:    ret i1 poison
+;
+start:
+  %2 = icmp eq i8 %0, poison
+  %3 = icmp ne i8 %1, 0
+  %4 = icmp ult i8 %0, %1
+  %result = select i1 %2, i1 poison, i1 %4
+  ret i1 %result
+}

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.

It is incorrect to preserve samesign flag: https://alive2.llvm.org/ce/z/2NdTWW

You should either implement this fold and drop the flag in InstCombine or bail out on icmps with samesign in InstSimplify.

@nikic
Copy link
Contributor

nikic commented Dec 17, 2024

You should either implement this fold and drop the flag in InstCombine or bail out on icmps with samesign in InstSimplify.

The first option is preferred.

@veera-sivarajan veera-sivarajan changed the title [InstSimplify] A == MIN_INT ? B != MIN_INT : A < B to A < B [InstCombine] A == MIN_INT ? B != MIN_INT : A < B to A < B Dec 18, 2024
Copy link

github-actions bot commented Dec 18, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@antoniofrighetto antoniofrighetto changed the title [InstCombine] A == MIN_INT ? B != MIN_INT : A < B to A < B [InstCombine] Fold A == MIN_INT ? B != MIN_INT : A < B to A < B Dec 18, 2024
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.

LGTM. Thank you!

@veera-sivarajan
Copy link
Contributor Author

Please merge it for me. I don't have commit access yet.

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.

5 participants