[llvm] [ConstraintElim] Extend `checkOrAndOpImpliedByOther` to handle and/or expr trees. (PR #117123)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 21 05:13:29 PST 2024


https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/117123

>From e48a70ea4d633a84748ea57b287b092d1d7fa7a0 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Thu, 21 Nov 2024 14:08:42 +0800
Subject: [PATCH 1/4] [ConstraintElim] Add pre-commit tests. NFC.

---
 .../ConstraintElimination/unreachable-bb.ll   | 36 +++++++++++++++++++
 1 file changed, 36 insertions(+)
 create mode 100644 llvm/test/Transforms/ConstraintElimination/unreachable-bb.ll

diff --git a/llvm/test/Transforms/ConstraintElimination/unreachable-bb.ll b/llvm/test/Transforms/ConstraintElimination/unreachable-bb.ll
new file mode 100644
index 00000000000000..4e65f5ad385b85
--- /dev/null
+++ b/llvm/test/Transforms/ConstraintElimination/unreachable-bb.ll
@@ -0,0 +1,36 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -p constraint-elimination -S %s | FileCheck %s
+
+define void @f(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {
+; CHECK-LABEL: define void @f(
+; CHECK-SAME: i32 noundef [[V0:%.*]], i32 noundef [[V1:%.*]], i32 noundef [[V2:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[V0]], [[V1]]
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2]]
+; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[CMP0]], [[CMP1]]
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
+; CHECK-NEXT:    [[AND2:%.*]] = and i1 [[CMP2]], [[AND1]]
+; CHECK-NEXT:    br i1 [[AND2]], label %[[IF_THEN:.*]], label %[[RETURN:.*]]
+; CHECK:       [[IF_THEN]]:
+; CHECK-NEXT:    call void @side_effect()
+; CHECK-NEXT:    br label %[[RETURN]]
+; CHECK:       [[RETURN]]:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %cmp0 = icmp sge i32 %v0, %v1
+  %cmp1 = icmp sge i32 %v1, %v2
+  %and1 = and i1 %cmp0, %cmp1
+  %cmp2 = icmp slt i32 %v0, %v2
+  %and2 = and i1 %cmp2, %and1
+  br i1 %and2, label %if.then, label %return
+
+if.then:
+  call void @side_effect()
+  br label %return
+
+return:
+  ret void
+}
+
+declare void @side_effect()

>From d5a87434037fb898cebe34f24acee3708036768b Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Thu, 21 Nov 2024 15:25:56 +0800
Subject: [PATCH 2/4] [ConstraintElim] Extend `checkOrAndOpImpliedByOther` to
 handle and/or expr trees

---
 .../Scalar/ConstraintElimination.cpp          | 31 +++++++++++++------
 .../Transforms/ConstraintElimination/or.ll    |  2 +-
 .../ConstraintElimination/unreachable-bb.ll   |  2 +-
 3 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index d03e3a0570cd3f..45cb38ce042f05 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -1511,18 +1511,29 @@ static bool checkOrAndOpImpliedByOther(
   if (OtherOpIdx != 0 && isa<SelectInst>(JoinOp))
     return false;
 
-  if (!match(JoinOp->getOperand(OtherOpIdx),
-             m_ICmp(Pred, m_Value(A), m_Value(B))))
-    return false;
-
-  // For OR, check if the negated condition implies CmpToCheck.
-  bool IsOr = match(JoinOp, m_LogicalOr());
-  if (IsOr)
-    Pred = CmpInst::getInversePredicate(Pred);
-
   // Optimistically add fact from first condition.
   unsigned OldSize = DFSInStack.size();
-  Info.addFact(Pred, A, B, CB.NumIn, CB.NumOut, DFSInStack);
+  // For OR, check if the negated condition implies CmpToCheck.
+  bool IsOr = match(JoinOp, m_LogicalOr());
+  SmallVector<Value *, 4> Worklist({JoinOp->getOperand(OtherOpIdx)});
+  while (!Worklist.empty()) {
+    Value *Val = Worklist.pop_back_val();
+    Value *LHS, *RHS;
+    ICmpInst::Predicate Pred;
+    if (match(Val, m_ICmp(Pred, m_Value(LHS), m_Value(RHS)))) {
+      if (IsOr)
+        Pred = CmpInst::getInversePredicate(Pred);
+      Info.addFact(Pred, LHS, RHS, CB.NumIn, CB.NumOut, DFSInStack);
+      continue;
+    }
+    if (IsOr ? match(Val, m_LogicalOr(m_Value(LHS), m_Value(RHS)))
+             : match(Val, m_LogicalAnd(m_Value(LHS), m_Value(RHS)))) {
+      Worklist.push_back(LHS);
+      Worklist.push_back(RHS);
+      continue;
+    }
+    return false;
+  }
   if (OldSize == DFSInStack.size())
     return false;
 
diff --git a/llvm/test/Transforms/ConstraintElimination/or.ll b/llvm/test/Transforms/ConstraintElimination/or.ll
index 01b8ca973efa56..b401d6f1813695 100644
--- a/llvm/test/Transforms/ConstraintElimination/or.ll
+++ b/llvm/test/Transforms/ConstraintElimination/or.ll
@@ -124,7 +124,7 @@ define i1 @test_or_chain_ule_1(i4 %x, i4 %y, i4 %z, i4 %a, i4 %b) {
 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ule i4 2, [[X]]
 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ule i4 2, [[A:%.*]]
 ; CHECK-NEXT:    [[OR_1:%.*]] = or i1 [[C_1]], [[C_2]]
-; CHECK-NEXT:    [[OR_2:%.*]] = or i1 [[OR_1]], [[C_3]]
+; CHECK-NEXT:    [[OR_2:%.*]] = or i1 [[OR_1]], true
 ; CHECK-NEXT:    [[OR_3:%.*]] = or i1 [[C_4]], [[OR_2]]
 ; CHECK-NEXT:    br i1 [[OR_3]], label [[BB1:%.*]], label [[EXIT:%.*]]
 ; CHECK:       bb1:
diff --git a/llvm/test/Transforms/ConstraintElimination/unreachable-bb.ll b/llvm/test/Transforms/ConstraintElimination/unreachable-bb.ll
index 4e65f5ad385b85..a3cea2e3b7889d 100644
--- a/llvm/test/Transforms/ConstraintElimination/unreachable-bb.ll
+++ b/llvm/test/Transforms/ConstraintElimination/unreachable-bb.ll
@@ -9,7 +9,7 @@ define void @f(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {
 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2]]
 ; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[CMP0]], [[CMP1]]
 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
-; CHECK-NEXT:    [[AND2:%.*]] = and i1 [[CMP2]], [[AND1]]
+; CHECK-NEXT:    [[AND2:%.*]] = and i1 false, [[AND1]]
 ; CHECK-NEXT:    br i1 [[AND2]], label %[[IF_THEN:.*]], label %[[RETURN:.*]]
 ; CHECK:       [[IF_THEN]]:
 ; CHECK-NEXT:    call void @side_effect()

>From a90be3ac98e38415894bea1f2e68c475954b6ec3 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Thu, 21 Nov 2024 16:34:47 +0800
Subject: [PATCH 3/4] [ConstraintElim] Fix miscompilation

---
 .../Scalar/ConstraintElimination.cpp          | 22 +++++++++----------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 45cb38ce042f05..31e9691ecde4c7 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -1498,9 +1498,6 @@ static bool checkOrAndOpImpliedByOther(
     FactOrCheck &CB, ConstraintInfo &Info, Module *ReproducerModule,
     SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
     SmallVectorImpl<StackEntry> &DFSInStack) {
-
-  CmpInst::Predicate Pred;
-  Value *A, *B;
   Instruction *JoinOp = CB.getContextInst();
   CmpInst *CmpToCheck = cast<CmpInst>(CB.getInstructionToSimplify());
   unsigned OtherOpIdx = JoinOp->getOperand(0) == CmpToCheck ? 1 : 0;
@@ -1513,6 +1510,14 @@ static bool checkOrAndOpImpliedByOther(
 
   // Optimistically add fact from first condition.
   unsigned OldSize = DFSInStack.size();
+  auto InfoRestorer = make_scope_exit([&]() {
+    // Remove entries again.
+    while (OldSize < DFSInStack.size()) {
+      StackEntry E = DFSInStack.back();
+      removeEntryFromStack(E, Info, ReproducerModule, ReproducerCondStack,
+                           DFSInStack);
+    }
+  });
   // For OR, check if the negated condition implies CmpToCheck.
   bool IsOr = match(JoinOp, m_LogicalOr());
   SmallVector<Value *, 4> Worklist({JoinOp->getOperand(OtherOpIdx)});
@@ -1537,7 +1542,6 @@ static bool checkOrAndOpImpliedByOther(
   if (OldSize == DFSInStack.size())
     return false;
 
-  bool Changed = false;
   // Check if the second condition can be simplified now.
   if (auto ImpliedCondition =
           checkCondition(CmpToCheck->getPredicate(), CmpToCheck->getOperand(0),
@@ -1551,16 +1555,10 @@ static bool checkOrAndOpImpliedByOther(
           1 - OtherOpIdx,
           ConstantInt::getBool(JoinOp->getType(), *ImpliedCondition));
 
-    Changed = true;
+    return true;
   }
 
-  // Remove entries again.
-  while (OldSize < DFSInStack.size()) {
-    StackEntry E = DFSInStack.back();
-    removeEntryFromStack(E, Info, ReproducerModule, ReproducerCondStack,
-                         DFSInStack);
-  }
-  return Changed;
+  return false;
 }
 
 void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B,

>From cddc2c37f364e0568c425410c376d7d2d29e33b5 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Thu, 21 Nov 2024 21:13:04 +0800
Subject: [PATCH 4/4] [ConstraintElim] Address review comments. NFC.

---
 .../Scalar/ConstraintElimination.cpp          |   5 +-
 .../and-implied-by-operands.ll                | 188 ++++++++++++++++++
 .../ConstraintElimination/unreachable-bb.ll   |  36 ----
 3 files changed, 191 insertions(+), 38 deletions(-)
 delete mode 100644 llvm/test/Transforms/ConstraintElimination/unreachable-bb.ll

diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 31e9691ecde4c7..64c0d3fe6a8dcc 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -1508,7 +1508,6 @@ static bool checkOrAndOpImpliedByOther(
   if (OtherOpIdx != 0 && isa<SelectInst>(JoinOp))
     return false;
 
-  // Optimistically add fact from first condition.
   unsigned OldSize = DFSInStack.size();
   auto InfoRestorer = make_scope_exit([&]() {
     // Remove entries again.
@@ -1518,16 +1517,18 @@ static bool checkOrAndOpImpliedByOther(
                            DFSInStack);
     }
   });
-  // For OR, check if the negated condition implies CmpToCheck.
   bool IsOr = match(JoinOp, m_LogicalOr());
   SmallVector<Value *, 4> Worklist({JoinOp->getOperand(OtherOpIdx)});
+  // Do a traversal of the AND/OR tree to add facts from leaf compares.
   while (!Worklist.empty()) {
     Value *Val = Worklist.pop_back_val();
     Value *LHS, *RHS;
     ICmpInst::Predicate Pred;
     if (match(Val, m_ICmp(Pred, m_Value(LHS), m_Value(RHS)))) {
+      // For OR, check if the negated condition implies CmpToCheck.
       if (IsOr)
         Pred = CmpInst::getInversePredicate(Pred);
+      // Optimistically add fact from the other compares in the AND/OR.
       Info.addFact(Pred, LHS, RHS, CB.NumIn, CB.NumOut, DFSInStack);
       continue;
     }
diff --git a/llvm/test/Transforms/ConstraintElimination/and-implied-by-operands.ll b/llvm/test/Transforms/ConstraintElimination/and-implied-by-operands.ll
index 6bbc73c9c996c8..9b798ea255c0e8 100644
--- a/llvm/test/Transforms/ConstraintElimination/and-implied-by-operands.ll
+++ b/llvm/test/Transforms/ConstraintElimination/and-implied-by-operands.ll
@@ -497,4 +497,192 @@ entry:
   ret i1 %and
 }
 
+define void @and_tree_second_implies_first(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {
+; CHECK-LABEL: @and_tree_second_implies_first(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
+; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[CMP0]], [[CMP1]]
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
+; CHECK-NEXT:    [[AND2:%.*]] = and i1 false, [[AND1]]
+; CHECK-NEXT:    br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    call void @side_effect()
+; CHECK-NEXT:    br label [[RETURN]]
+; CHECK:       return:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %cmp0 = icmp sge i32 %v0, %v1
+  %cmp1 = icmp sge i32 %v1, %v2
+  %and1 = and i1 %cmp0, %cmp1
+  %cmp2 = icmp slt i32 %v0, %v2
+  %and2 = and i1 %cmp2, %and1
+  br i1 %and2, label %if.then, label %return
+
+if.then:
+  call void @side_effect()
+  br label %return
+
+return:
+  ret void
+}
+
+define void @and_tree_second_implies_first_perm1(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {
+; CHECK-LABEL: @and_tree_second_implies_first_perm1(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
+; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[CMP2]], [[CMP1]]
+; CHECK-NEXT:    [[AND2:%.*]] = and i1 false, [[AND1]]
+; CHECK-NEXT:    br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    call void @side_effect()
+; CHECK-NEXT:    br label [[RETURN]]
+; CHECK:       return:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %cmp0 = icmp sge i32 %v0, %v1
+  %cmp1 = icmp sge i32 %v1, %v2
+  %cmp2 = icmp slt i32 %v0, %v2
+  %and1 = and i1 %cmp2, %cmp1
+  %and2 = and i1 %cmp0, %and1
+  br i1 %and2, label %if.then, label %return
+
+if.then:
+  call void @side_effect()
+  br label %return
+
+return:
+  ret void
+}
+
+
+define void @and_tree_second_implies_first_perm2(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {
+; CHECK-LABEL: @and_tree_second_implies_first_perm2(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
+; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[CMP0]], [[CMP2]]
+; CHECK-NEXT:    [[AND2:%.*]] = and i1 false, [[AND1]]
+; CHECK-NEXT:    br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    call void @side_effect()
+; CHECK-NEXT:    br label [[RETURN]]
+; CHECK:       return:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %cmp0 = icmp sge i32 %v0, %v1
+  %cmp1 = icmp sge i32 %v1, %v2
+  %cmp2 = icmp slt i32 %v0, %v2
+  %and1 = and i1 %cmp0, %cmp2
+  %and2 = and i1 %cmp1, %and1
+  br i1 %and2, label %if.then, label %return
+
+if.then:
+  call void @side_effect()
+  br label %return
+
+return:
+  ret void
+}
+
+define void @logical_and_tree_second_implies_first(i32 %v0, i32 %v1, i32 %v2) {
+; CHECK-LABEL: @logical_and_tree_second_implies_first(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
+; CHECK-NEXT:    [[AND1:%.*]] = select i1 [[CMP0]], i1 [[CMP1]], i1 false
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
+; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[CMP2]], i1 [[AND1]], i1 false
+; CHECK-NEXT:    br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    call void @side_effect()
+; CHECK-NEXT:    br label [[RETURN]]
+; CHECK:       return:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %cmp0 = icmp sge i32 %v0, %v1
+  %cmp1 = icmp sge i32 %v1, %v2
+  %and1 = select i1 %cmp0, i1 %cmp1, i1 false
+  %cmp2 = icmp slt i32 %v0, %v2
+  %and2 = select i1 %cmp2, i1 %and1, i1 false
+  br i1 %and2, label %if.then, label %return
+
+if.then:
+  call void @side_effect()
+  br label %return
+
+return:
+  ret void
+}
+
+define void @or_tree_second_implies_first(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {
+; CHECK-LABEL: @or_tree_second_implies_first(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
+; CHECK-NEXT:    [[AND1:%.*]] = or i1 [[CMP0]], [[CMP1]]
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
+; CHECK-NEXT:    [[AND2:%.*]] = or i1 true, [[AND1]]
+; CHECK-NEXT:    br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    call void @side_effect()
+; CHECK-NEXT:    br label [[RETURN]]
+; CHECK:       return:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %cmp0 = icmp sge i32 %v0, %v1
+  %cmp1 = icmp sge i32 %v1, %v2
+  %and1 = or i1 %cmp0, %cmp1
+  %cmp2 = icmp slt i32 %v0, %v2
+  %and2 = or i1 %cmp2, %and1
+  br i1 %and2, label %if.then, label %return
+
+if.then:
+  call void @side_effect()
+  br label %return
+
+return:
+  ret void
+}
+
+define void @negative_and_or_tree_second_implies_first(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {
+; CHECK-LABEL: @negative_and_or_tree_second_implies_first(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
+; CHECK-NEXT:    [[AND1:%.*]] = or i1 [[CMP0]], [[CMP1]]
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
+; CHECK-NEXT:    [[AND2:%.*]] = and i1 [[CMP2]], [[AND1]]
+; CHECK-NEXT:    br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    call void @side_effect()
+; CHECK-NEXT:    br label [[RETURN]]
+; CHECK:       return:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %cmp0 = icmp sge i32 %v0, %v1
+  %cmp1 = icmp sge i32 %v1, %v2
+  %and1 = or i1 %cmp0, %cmp1
+  %cmp2 = icmp slt i32 %v0, %v2
+  %and2 = and i1 %cmp2, %and1
+  br i1 %and2, label %if.then, label %return
+
+if.then:
+  call void @side_effect()
+  br label %return
+
+return:
+  ret void
+}
+
+declare void @side_effect()
 declare void @no_noundef(i1 noundef)
diff --git a/llvm/test/Transforms/ConstraintElimination/unreachable-bb.ll b/llvm/test/Transforms/ConstraintElimination/unreachable-bb.ll
deleted file mode 100644
index a3cea2e3b7889d..00000000000000
--- a/llvm/test/Transforms/ConstraintElimination/unreachable-bb.ll
+++ /dev/null
@@ -1,36 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -p constraint-elimination -S %s | FileCheck %s
-
-define void @f(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {
-; CHECK-LABEL: define void @f(
-; CHECK-SAME: i32 noundef [[V0:%.*]], i32 noundef [[V1:%.*]], i32 noundef [[V2:%.*]]) {
-; CHECK-NEXT:  [[ENTRY:.*:]]
-; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[V0]], [[V1]]
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2]]
-; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[CMP0]], [[CMP1]]
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
-; CHECK-NEXT:    [[AND2:%.*]] = and i1 false, [[AND1]]
-; CHECK-NEXT:    br i1 [[AND2]], label %[[IF_THEN:.*]], label %[[RETURN:.*]]
-; CHECK:       [[IF_THEN]]:
-; CHECK-NEXT:    call void @side_effect()
-; CHECK-NEXT:    br label %[[RETURN]]
-; CHECK:       [[RETURN]]:
-; CHECK-NEXT:    ret void
-;
-entry:
-  %cmp0 = icmp sge i32 %v0, %v1
-  %cmp1 = icmp sge i32 %v1, %v2
-  %and1 = and i1 %cmp0, %cmp1
-  %cmp2 = icmp slt i32 %v0, %v2
-  %and2 = and i1 %cmp2, %and1
-  br i1 %and2, label %if.then, label %return
-
-if.then:
-  call void @side_effect()
-  br label %return
-
-return:
-  ret void
-}
-
-declare void @side_effect()



More information about the llvm-commits mailing list