Skip to content

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 llvmbot added llvm:instcombine Covers the InstCombine, InstSimplify and AggressiveInstCombine passes llvm:analysis Includes value tracking, cost tables and constant folding llvm:transforms labels Dec 17, 2024
@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
@github-actions
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.

@dtcxzyw dtcxzyw merged commit 6f8afaf into llvm:main Dec 19, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

llvm:analysis Includes value tracking, cost tables and constant folding llvm:instcombine Covers the InstCombine, InstSimplify and AggressiveInstCombine passes llvm:transforms

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants