[llvm] [Analysis][ValueTracking] Unify most of the tracking between AssumptionCache and DomConditionCache (PR #83161)

via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 27 11:16:11 PST 2024


https://github.com/goldsteinn updated https://github.com/llvm/llvm-project/pull/83161

>From 84fa096366450b35a60b9687a1982e14f0421720 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Mon, 26 Feb 2024 15:54:04 -0600
Subject: [PATCH 1/3] [Analysis] Move `DomConditionCache::findAffectedValues`
 to a new file; NFC

---
 .../llvm/Analysis/ConditionCacheUtil.h        | 82 +++++++++++++++++++
 llvm/lib/Analysis/DomConditionCache.cpp       | 67 +--------------
 2 files changed, 85 insertions(+), 64 deletions(-)
 create mode 100644 llvm/include/llvm/Analysis/ConditionCacheUtil.h

diff --git a/llvm/include/llvm/Analysis/ConditionCacheUtil.h b/llvm/include/llvm/Analysis/ConditionCacheUtil.h
new file mode 100644
index 00000000000000..87bcad3e3d2c4c
--- /dev/null
+++ b/llvm/include/llvm/Analysis/ConditionCacheUtil.h
@@ -0,0 +1,82 @@
+#ifndef LLVM_ANALYSIS_CONDITIONCACHEUTIL_H
+#define LLVM_ANALYSIS_CONDITIONCACHEUTIL_H
+
+#include "llvm/IR/PatternMatch.h"
+#include <functional>
+
+namespace llvm {
+
+static void addValueAffectedByCondition(
+    Value *V, function_ref<void(Value *, int)> InsertAffected, int Idx = -1) {
+  using namespace llvm::PatternMatch;
+  assert(V != nullptr);
+  if (isa<Argument>(V) || isa<GlobalValue>(V)) {
+    InsertAffected(V, Idx);
+  } else if (auto *I = dyn_cast<Instruction>(V)) {
+    InsertAffected(V, Idx);
+
+    // Peek through unary operators to find the source of the condition.
+    Value *Op;
+    if (match(I, m_PtrToInt(m_Value(Op)))) {
+      if (isa<Instruction>(Op) || isa<Argument>(Op))
+        InsertAffected(Op, Idx);
+    }
+  }
+}
+
+static void
+findValuesAffectedByCondition(Value *Cond, bool IsAssume,
+                              function_ref<void(Value *, int)> InsertAffected) {
+  using namespace llvm::PatternMatch;
+  auto AddAffected = [&InsertAffected](Value *V) {
+    addValueAffectedByCondition(V, InsertAffected);
+  };
+
+  assert(!IsAssume);
+  SmallVector<Value *, 8> Worklist;
+  SmallPtrSet<Value *, 8> Visited;
+  Worklist.push_back(Cond);
+  while (!Worklist.empty()) {
+    Value *V = Worklist.pop_back_val();
+    if (!Visited.insert(V).second)
+      continue;
+
+    CmpInst::Predicate Pred;
+    Value *A, *B;
+    if (match(V, m_LogicalOp(m_Value(A), m_Value(B)))) {
+      Worklist.push_back(A);
+      Worklist.push_back(B);
+    } else if (match(V, m_ICmp(Pred, m_Value(A), m_Constant()))) {
+      AddAffected(A);
+
+      if (ICmpInst::isEquality(Pred)) {
+        Value *X;
+        // (X & C) or (X | C) or (X ^ C).
+        // (X << C) or (X >>_s C) or (X >>_u C).
+        if (match(A, m_BitwiseLogic(m_Value(X), m_ConstantInt())) ||
+            match(A, m_Shift(m_Value(X), m_ConstantInt())))
+          AddAffected(X);
+      } else {
+        Value *X;
+        // Handle (A + C1) u< C2, which is the canonical form of
+        // A > C3 && A < C4.
+        if (match(A, m_Add(m_Value(X), m_ConstantInt())))
+          AddAffected(X);
+        // Handle icmp slt/sgt (bitcast X to int), 0/-1, which is supported by
+        // computeKnownFPClass().
+        if ((Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGT) &&
+            match(A, m_ElementWiseBitCast(m_Value(X))))
+          InsertAffected(X, -1);
+      }
+    } else if (match(Cond, m_CombineOr(m_FCmp(Pred, m_Value(A), m_Constant()),
+                                       m_Intrinsic<Intrinsic::is_fpclass>(
+                                           m_Value(A), m_Constant())))) {
+      // Handle patterns that computeKnownFPClass() support.
+      AddAffected(A);
+    }
+  }
+}
+
+} // namespace llvm
+
+#endif // LLVM_ANALYSIS_CONDITIONCACHEUTIL_H
diff --git a/llvm/lib/Analysis/DomConditionCache.cpp b/llvm/lib/Analysis/DomConditionCache.cpp
index da05e02b4b57f7..fadd0a6f22953b 100644
--- a/llvm/lib/Analysis/DomConditionCache.cpp
+++ b/llvm/lib/Analysis/DomConditionCache.cpp
@@ -7,75 +7,14 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Analysis/DomConditionCache.h"
-#include "llvm/IR/PatternMatch.h"
+#include "llvm/Analysis/ConditionCacheUtil.h"
 
 using namespace llvm;
-using namespace llvm::PatternMatch;
 
-// TODO: This code is very similar to findAffectedValues() in
-// AssumptionCache, but currently specialized to just the patterns that
-// computeKnownBits() supports, and without the notion of result elem indices
-// that are AC specific. Deduplicate this code once we have a clearer picture
-// of how much they can be shared.
 static void findAffectedValues(Value *Cond,
                                SmallVectorImpl<Value *> &Affected) {
-  auto AddAffected = [&Affected](Value *V) {
-    if (isa<Argument>(V) || isa<GlobalValue>(V)) {
-      Affected.push_back(V);
-    } else if (auto *I = dyn_cast<Instruction>(V)) {
-      Affected.push_back(I);
-
-      // Peek through unary operators to find the source of the condition.
-      Value *Op;
-      if (match(I, m_PtrToInt(m_Value(Op)))) {
-        if (isa<Instruction>(Op) || isa<Argument>(Op))
-          Affected.push_back(Op);
-      }
-    }
-  };
-
-  SmallVector<Value *, 8> Worklist;
-  SmallPtrSet<Value *, 8> Visited;
-  Worklist.push_back(Cond);
-  while (!Worklist.empty()) {
-    Value *V = Worklist.pop_back_val();
-    if (!Visited.insert(V).second)
-      continue;
-
-    CmpInst::Predicate Pred;
-    Value *A, *B;
-    if (match(V, m_LogicalOp(m_Value(A), m_Value(B)))) {
-      Worklist.push_back(A);
-      Worklist.push_back(B);
-    } else if (match(V, m_ICmp(Pred, m_Value(A), m_Constant()))) {
-      AddAffected(A);
-
-      if (ICmpInst::isEquality(Pred)) {
-        Value *X;
-        // (X & C) or (X | C) or (X ^ C).
-        // (X << C) or (X >>_s C) or (X >>_u C).
-        if (match(A, m_BitwiseLogic(m_Value(X), m_ConstantInt())) ||
-            match(A, m_Shift(m_Value(X), m_ConstantInt())))
-          AddAffected(X);
-      } else {
-        Value *X;
-        // Handle (A + C1) u< C2, which is the canonical form of
-        // A > C3 && A < C4.
-        if (match(A, m_Add(m_Value(X), m_ConstantInt())))
-          AddAffected(X);
-        // Handle icmp slt/sgt (bitcast X to int), 0/-1, which is supported by
-        // computeKnownFPClass().
-        if ((Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGT) &&
-            match(A, m_ElementWiseBitCast(m_Value(X))))
-          Affected.push_back(X);
-      }
-    } else if (match(Cond, m_CombineOr(m_FCmp(Pred, m_Value(A), m_Constant()),
-                                       m_Intrinsic<Intrinsic::is_fpclass>(
-                                           m_Value(A), m_Constant())))) {
-      // Handle patterns that computeKnownFPClass() support.
-      AddAffected(A);
-    }
-  }
+  auto InsertAffected = [&Affected](Value *V, int) { Affected.push_back(V); };
+  findValuesAffectedByCondition(Cond, /*IsAssume*/ false, InsertAffected);
 }
 
 void DomConditionCache::registerBranch(BranchInst *BI) {

>From 56cee12f5fc67c645dcd920843ee3948cc1b2db1 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Mon, 26 Feb 2024 16:19:48 -0600
Subject: [PATCH 2/3] [Analysis] Share `findAffectedValues` between
 DomConditionCache and AssumptionCache; NFC

---
 .../llvm/Analysis/ConditionCacheUtil.h        | 83 +++++++++++++------
 llvm/lib/Analysis/AssumptionCache.cpp         | 75 +++--------------
 2 files changed, 70 insertions(+), 88 deletions(-)

diff --git a/llvm/include/llvm/Analysis/ConditionCacheUtil.h b/llvm/include/llvm/Analysis/ConditionCacheUtil.h
index 87bcad3e3d2c4c..10e05eb06b02d7 100644
--- a/llvm/include/llvm/Analysis/ConditionCacheUtil.h
+++ b/llvm/include/llvm/Analysis/ConditionCacheUtil.h
@@ -32,7 +32,6 @@ findValuesAffectedByCondition(Value *Cond, bool IsAssume,
     addValueAffectedByCondition(V, InsertAffected);
   };
 
-  assert(!IsAssume);
   SmallVector<Value *, 8> Worklist;
   SmallPtrSet<Value *, 8> Visited;
   Worklist.push_back(Cond);
@@ -42,35 +41,67 @@ findValuesAffectedByCondition(Value *Cond, bool IsAssume,
       continue;
 
     CmpInst::Predicate Pred;
-    Value *A, *B;
-    if (match(V, m_LogicalOp(m_Value(A), m_Value(B)))) {
+    Value *A, *B, *X;
+
+    if (IsAssume)
+      AddAffected(V);
+
+    if (IsAssume && match(V, m_Not(m_Value(X))))
+      AddAffected(X);
+    if (!IsAssume && match(V, m_LogicalOp(m_Value(A), m_Value(B)))) {
       Worklist.push_back(A);
       Worklist.push_back(B);
-    } else if (match(V, m_ICmp(Pred, m_Value(A), m_Constant()))) {
-      AddAffected(A);
+    } else if (match(V, m_Cmp(Pred, m_Value(A), m_Value(B))) &&
+               (IsAssume || isa<ICmpInst>(V))) {
+      if (IsAssume || match(B, m_Constant())) {
+        AddAffected(A);
+        if (IsAssume)
+          AddAffected(B);
+
+        if (IsAssume ? (Pred == ICmpInst::ICMP_EQ)
+                     : ICmpInst::isEquality(Pred)) {
+          if (match(B, m_ConstantInt())) {
+            // (X & C) or (X | C) or (X ^ C).
+            // (X << C) or (X >>_s C) or (X >>_u C).
+            if (match(A, m_BitwiseLogic(m_Value(X), m_ConstantInt())) ||
+                match(A, m_Shift(m_Value(X), m_ConstantInt())))
+              AddAffected(X);
+          }
+        } else {
+          if (Pred == ICmpInst::ICMP_NE)
+            if (match(A, m_And(m_Value(X), m_Power2())) && match(B, m_Zero()))
+              AddAffected(X);
+
+          if (!IsAssume || Pred == ICmpInst::ICMP_ULT) {
+            // Handle (A + C1) u< C2, which is the canonical form of
+            // A > C3 && A < C4.
+            if (match(A, m_Add(m_Value(X), m_ConstantInt())) &&
+                match(B, m_ConstantInt()))
+              AddAffected(X);
+          }
+          if (!IsAssume) {
+            // Handle icmp slt/sgt (bitcast X to int), 0/-1, which is supported
+            // by computeKnownFPClass().
+            if ((Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGT) &&
+                match(A, m_ElementWiseBitCast(m_Value(X))))
+              InsertAffected(X, -1);
+          }
 
-      if (ICmpInst::isEquality(Pred)) {
-        Value *X;
-        // (X & C) or (X | C) or (X ^ C).
-        // (X << C) or (X >>_s C) or (X >>_u C).
-        if (match(A, m_BitwiseLogic(m_Value(X), m_ConstantInt())) ||
-            match(A, m_Shift(m_Value(X), m_ConstantInt())))
-          AddAffected(X);
-      } else {
-        Value *X;
-        // Handle (A + C1) u< C2, which is the canonical form of
-        // A > C3 && A < C4.
-        if (match(A, m_Add(m_Value(X), m_ConstantInt())))
-          AddAffected(X);
-        // Handle icmp slt/sgt (bitcast X to int), 0/-1, which is supported by
-        // computeKnownFPClass().
-        if ((Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGT) &&
-            match(A, m_ElementWiseBitCast(m_Value(X))))
-          InsertAffected(X, -1);
+          if (IsAssume && CmpInst::isFPPredicate(Pred)) {
+            // fcmp fneg(x), y
+            // fcmp fabs(x), y
+            // fcmp fneg(fabs(x)), y
+            if (match(A, m_FNeg(m_Value(A))))
+              AddAffected(A);
+            if (match(A, m_FAbs(m_Value(A))))
+              AddAffected(A);
+          }
+        }
       }
-    } else if (match(Cond, m_CombineOr(m_FCmp(Pred, m_Value(A), m_Constant()),
-                                       m_Intrinsic<Intrinsic::is_fpclass>(
-                                           m_Value(A), m_Constant())))) {
+    } else if ((!IsAssume &&
+                match(Cond, m_FCmp(Pred, m_Value(A), m_Constant()))) ||
+               match(Cond, m_Intrinsic<Intrinsic::is_fpclass>(m_Value(A),
+                                                              m_Value(B)))) {
       // Handle patterns that computeKnownFPClass() support.
       AddAffected(A);
     }
diff --git a/llvm/lib/Analysis/AssumptionCache.cpp b/llvm/lib/Analysis/AssumptionCache.cpp
index 1b7277df0e0cd0..4c0e0db7f9d19e 100644
--- a/llvm/lib/Analysis/AssumptionCache.cpp
+++ b/llvm/lib/Analysis/AssumptionCache.cpp
@@ -16,6 +16,7 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Analysis/AssumeBundleQueries.h"
+#include "llvm/Analysis/ConditionCacheUtil.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "llvm/IR/BasicBlock.h"
@@ -61,20 +62,8 @@ findAffectedValues(CallBase *CI, TargetTransformInfo *TTI,
   // Note: This code must be kept in-sync with the code in
   // computeKnownBitsFromAssume in ValueTracking.
 
-  auto AddAffected = [&Affected](Value *V, unsigned Idx =
-                                               AssumptionCache::ExprResultIdx) {
-    if (isa<Argument>(V) || isa<GlobalValue>(V)) {
-      Affected.push_back({V, Idx});
-    } else if (auto *I = dyn_cast<Instruction>(V)) {
-      Affected.push_back({I, Idx});
-
-      // Peek through unary operators to find the source of the condition.
-      Value *Op;
-      if (match(I, m_PtrToInt(m_Value(Op)))) {
-        if (isa<Instruction>(Op) || isa<Argument>(Op))
-          Affected.push_back({Op, Idx});
-      }
-    }
+  auto InsertAffected = [&Affected](Value *V, int Idx) {
+    Affected.push_back({V, Idx < 0 ? AssumptionCache::ExprResultIdx : Idx});
   };
 
   for (unsigned Idx = 0; Idx != CI->getNumOperandBundles(); Idx++) {
@@ -82,64 +71,26 @@ findAffectedValues(CallBase *CI, TargetTransformInfo *TTI,
     if (Bundle.getTagName() == "separate_storage") {
       assert(Bundle.Inputs.size() == 2 &&
              "separate_storage must have two args");
-      AddAffected(getUnderlyingObject(Bundle.Inputs[0]), Idx);
-      AddAffected(getUnderlyingObject(Bundle.Inputs[1]), Idx);
+      addValueAffectedByCondition(getUnderlyingObject(Bundle.Inputs[0]),
+                                  InsertAffected, Idx);
+      addValueAffectedByCondition(getUnderlyingObject(Bundle.Inputs[1]),
+                                  InsertAffected, Idx);
     } else if (Bundle.Inputs.size() > ABA_WasOn &&
                Bundle.getTagName() != IgnoreBundleTag)
-      AddAffected(Bundle.Inputs[ABA_WasOn], Idx);
+      addValueAffectedByCondition(Bundle.Inputs[ABA_WasOn], InsertAffected,
+                                  Idx);
   }
 
-  Value *Cond = CI->getArgOperand(0), *A, *B;
-  AddAffected(Cond);
-  if (match(Cond, m_Not(m_Value(A))))
-    AddAffected(A);
-
-  CmpInst::Predicate Pred;
-  if (match(Cond, m_Cmp(Pred, m_Value(A), m_Value(B)))) {
-    AddAffected(A);
-    AddAffected(B);
-
-    if (Pred == ICmpInst::ICMP_EQ) {
-      if (match(B, m_ConstantInt())) {
-        Value *X;
-        // (X & C) or (X | C) or (X ^ C).
-        // (X << C) or (X >>_s C) or (X >>_u C).
-        if (match(A, m_BitwiseLogic(m_Value(X), m_ConstantInt())) ||
-            match(A, m_Shift(m_Value(X), m_ConstantInt())))
-          AddAffected(X);
-      }
-    } else if (Pred == ICmpInst::ICMP_NE) {
-      Value *X;
-      // Handle (X & pow2 != 0).
-      if (match(A, m_And(m_Value(X), m_Power2())) && match(B, m_Zero()))
-        AddAffected(X);
-    } else if (Pred == ICmpInst::ICMP_ULT) {
-      Value *X;
-      // Handle (A + C1) u< C2, which is the canonical form of A > C3 && A < C4,
-      // and recognized by LVI at least.
-      if (match(A, m_Add(m_Value(X), m_ConstantInt())) &&
-          match(B, m_ConstantInt()))
-        AddAffected(X);
-    } else if (CmpInst::isFPPredicate(Pred)) {
-      // fcmp fneg(x), y
-      // fcmp fabs(x), y
-      // fcmp fneg(fabs(x)), y
-      if (match(A, m_FNeg(m_Value(A))))
-        AddAffected(A);
-      if (match(A, m_FAbs(m_Value(A))))
-        AddAffected(A);
-    }
-  } else if (match(Cond, m_Intrinsic<Intrinsic::is_fpclass>(m_Value(A),
-                                                            m_Value(B)))) {
-    AddAffected(A);
-  }
+  Value *Cond = CI->getArgOperand(0);
+  findValuesAffectedByCondition(Cond, /*IsAssume*/ true, InsertAffected);
 
   if (TTI) {
     const Value *Ptr;
     unsigned AS;
     std::tie(Ptr, AS) = TTI->getPredicatedAddrSpace(Cond);
     if (Ptr)
-      AddAffected(const_cast<Value *>(Ptr->stripInBoundsOffsets()));
+      addValueAffectedByCondition(
+          const_cast<Value *>(Ptr->stripInBoundsOffsets()), InsertAffected);
   }
 }
 

>From c32b70e496df05146d86eeba73f9e9c6ecb7ce64 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Mon, 26 Feb 2024 16:30:39 -0600
Subject: [PATCH 3/3] [Analysis] Unify most of the tracking between
 AssumptionCache and DomConditionCache

This helps cover some missing cases in both and hopefully serves as
creating an easier framework for extending general condition based
analysis.
---
 .../llvm/Analysis/ConditionCacheUtil.h        | 105 ++++++++++--------
 llvm/lib/Analysis/ValueTracking.cpp           |   6 +-
 .../ValueTracking/numsignbits-from-assume.ll  |   2 +-
 .../InstCombine/fpclass-from-dom-cond.ll      |   5 +-
 .../Transforms/InstSimplify/assume_icmp.ll    |  12 +-
 5 files changed, 65 insertions(+), 65 deletions(-)

diff --git a/llvm/include/llvm/Analysis/ConditionCacheUtil.h b/llvm/include/llvm/Analysis/ConditionCacheUtil.h
index 10e05eb06b02d7..34349a38b1ad48 100644
--- a/llvm/include/llvm/Analysis/ConditionCacheUtil.h
+++ b/llvm/include/llvm/Analysis/ConditionCacheUtil.h
@@ -1,6 +1,20 @@
+//===- llvm/Analysis/ConditionCacheUtil.h -----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Shared by DomConditionCache and AssumptionCache. Holds common operation of
+// finding values potentially affected by an assumed/branched on condition.
+//
+//===----------------------------------------------------------------------===//
+
 #ifndef LLVM_ANALYSIS_CONDITIONCACHEUTIL_H
 #define LLVM_ANALYSIS_CONDITIONCACHEUTIL_H
 
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/IR/PatternMatch.h"
 #include <functional>
 
@@ -43,65 +57,58 @@ findValuesAffectedByCondition(Value *Cond, bool IsAssume,
     CmpInst::Predicate Pred;
     Value *A, *B, *X;
 
-    if (IsAssume)
+    if (IsAssume) {
       AddAffected(V);
+      if (match(V, m_Not(m_Value(X))))
+        AddAffected(X);
+    }
 
-    if (IsAssume && match(V, m_Not(m_Value(X))))
-      AddAffected(X);
-    if (!IsAssume && match(V, m_LogicalOp(m_Value(A), m_Value(B)))) {
+    if (match(V, m_LogicalOp(m_Value(A), m_Value(B)))) {
       Worklist.push_back(A);
       Worklist.push_back(B);
-    } else if (match(V, m_Cmp(Pred, m_Value(A), m_Value(B))) &&
-               (IsAssume || isa<ICmpInst>(V))) {
-      if (IsAssume || match(B, m_Constant())) {
+    } else if (match(V, m_Cmp(Pred, m_Value(A), m_Value(B)))) {
+      if (IsAssume) {
+        AddAffected(A);
+        AddAffected(B);
+      } else if (match(B, m_Constant()))
         AddAffected(A);
-        if (IsAssume)
-          AddAffected(B);
 
-        if (IsAssume ? (Pred == ICmpInst::ICMP_EQ)
-                     : ICmpInst::isEquality(Pred)) {
-          if (match(B, m_ConstantInt())) {
-            // (X & C) or (X | C) or (X ^ C).
-            // (X << C) or (X >>_s C) or (X >>_u C).
-            if (match(A, m_BitwiseLogic(m_Value(X), m_ConstantInt())) ||
-                match(A, m_Shift(m_Value(X), m_ConstantInt())))
-              AddAffected(X);
-          }
-        } else {
-          if (Pred == ICmpInst::ICMP_NE)
-            if (match(A, m_And(m_Value(X), m_Power2())) && match(B, m_Zero()))
-              AddAffected(X);
+      if (ICmpInst::isEquality(Pred)) {
+        if (match(B, m_ConstantInt())) {
+          // (X & C) or (X | C) or (X ^ C).
+          // (X << C) or (X >>_s C) or (X >>_u C).
+          if (match(A, m_BitwiseLogic(m_Value(X), m_ConstantInt())) ||
+              match(A, m_Shift(m_Value(X), m_ConstantInt())))
+            AddAffected(X);
+        }
+      } else {
+        // Handle (A + C1) u< C2, which is the canonical form of
+        // A > C3 && A < C4.
+        if (match(A, m_Add(m_Value(X), m_ConstantInt())) &&
+            match(B, m_ConstantInt()))
+          AddAffected(X);
 
-          if (!IsAssume || Pred == ICmpInst::ICMP_ULT) {
-            // Handle (A + C1) u< C2, which is the canonical form of
-            // A > C3 && A < C4.
-            if (match(A, m_Add(m_Value(X), m_ConstantInt())) &&
-                match(B, m_ConstantInt()))
-              AddAffected(X);
-          }
-          if (!IsAssume) {
-            // Handle icmp slt/sgt (bitcast X to int), 0/-1, which is supported
-            // by computeKnownFPClass().
-            if ((Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGT) &&
-                match(A, m_ElementWiseBitCast(m_Value(X))))
-              InsertAffected(X, -1);
-          }
+        // Handle icmp slt/sgt (bitcast X to int), 0/-1, which is supported
+        // by computeKnownFPClass().
+        if (match(A, m_ElementWiseBitCast(m_Value(X)))) {
+          if (Pred == ICmpInst::ICMP_SLT && match(B, m_Zero()))
+            InsertAffected(X, -1);
+          else if (Pred == ICmpInst::ICMP_SGT && match(B, m_AllOnes()))
+            InsertAffected(X, -1);
+        }
 
-          if (IsAssume && CmpInst::isFPPredicate(Pred)) {
-            // fcmp fneg(x), y
-            // fcmp fabs(x), y
-            // fcmp fneg(fabs(x)), y
-            if (match(A, m_FNeg(m_Value(A))))
-              AddAffected(A);
-            if (match(A, m_FAbs(m_Value(A))))
-              AddAffected(A);
-          }
+        if (CmpInst::isFPPredicate(Pred)) {
+          // fcmp fneg(x), y
+          // fcmp fabs(x), y
+          // fcmp fneg(fabs(x)), y
+          if (match(A, m_FNeg(m_Value(A))))
+            AddAffected(A);
+          if (match(A, m_FAbs(m_Value(A))))
+            AddAffected(A);
         }
       }
-    } else if ((!IsAssume &&
-                match(Cond, m_FCmp(Pred, m_Value(A), m_Constant()))) ||
-               match(Cond, m_Intrinsic<Intrinsic::is_fpclass>(m_Value(A),
-                                                              m_Value(B)))) {
+    } else if (match(V, m_Intrinsic<Intrinsic::is_fpclass>(m_Value(A),
+                                                           m_Value()))) {
       // Handle patterns that computeKnownFPClass() support.
       AddAffected(A);
     }
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index e591ac504e9f05..39d358b45d9021 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -806,15 +806,13 @@ void llvm::computeKnownBitsFromContext(const Value *V, KnownBits &Known,
     if (Depth == MaxAnalysisRecursionDepth)
       continue;
 
-    ICmpInst *Cmp = dyn_cast<ICmpInst>(Arg);
-    if (!Cmp)
+    if (!isa<ICmpInst>(Arg) && !match(Arg, m_LogicalOp(m_Value(), m_Value())))
       continue;
 
     if (!isValidAssumeForContext(I, Q.CxtI, Q.DT))
       continue;
 
-    computeKnownBitsFromCmp(V, Cmp->getPredicate(), Cmp->getOperand(0),
-                            Cmp->getOperand(1), Known, Q);
+    computeKnownBitsFromCond(V, Arg, Known, /*Depth*/ 0, Q, /*Invert*/ false);
   }
 
   // Conflicting assumption: Undefined behavior will occur on this execution
diff --git a/llvm/test/Analysis/ValueTracking/numsignbits-from-assume.ll b/llvm/test/Analysis/ValueTracking/numsignbits-from-assume.ll
index 00c66eeb599572..95ac98532da621 100644
--- a/llvm/test/Analysis/ValueTracking/numsignbits-from-assume.ll
+++ b/llvm/test/Analysis/ValueTracking/numsignbits-from-assume.ll
@@ -51,7 +51,7 @@ define i32 @computeNumSignBits_sub1(i32 %in) {
 
 define i32 @computeNumSignBits_sub2(i32 %in) {
 ; CHECK-LABEL: @computeNumSignBits_sub2(
-; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[IN:%.*]], -1
+; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[IN:%.*]], -1
 ; CHECK-NEXT:    [[COND:%.*]] = icmp ult i32 [[SUB]], 43
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[COND]])
 ; CHECK-NEXT:    [[SH:%.*]] = shl nuw nsw i32 [[SUB]], 3
diff --git a/llvm/test/Transforms/InstCombine/fpclass-from-dom-cond.ll b/llvm/test/Transforms/InstCombine/fpclass-from-dom-cond.ll
index d40cd7fd503ecc..d6706d76056eea 100644
--- a/llvm/test/Transforms/InstCombine/fpclass-from-dom-cond.ll
+++ b/llvm/test/Transforms/InstCombine/fpclass-from-dom-cond.ll
@@ -185,10 +185,9 @@ define i1 @test8(float %x) {
 ; CHECK-NEXT:    [[COND:%.*]] = fcmp oeq float [[ABS]], 0x7FF0000000000000
 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
 ; CHECK:       if.then:
-; CHECK-NEXT:    [[RET1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 575)
-; CHECK-NEXT:    ret i1 [[RET1]]
+; CHECK-NEXT:    ret i1 true
 ; CHECK:       if.else:
-; CHECK-NEXT:    [[RET2:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 575)
+; CHECK-NEXT:    [[RET2:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 59)
 ; CHECK-NEXT:    ret i1 [[RET2]]
 ;
   %abs = call float @llvm.fabs.f32(float %x)
diff --git a/llvm/test/Transforms/InstSimplify/assume_icmp.ll b/llvm/test/Transforms/InstSimplify/assume_icmp.ll
index 9ac3f468ab604f..2ebb3b23a9b883 100644
--- a/llvm/test/Transforms/InstSimplify/assume_icmp.ll
+++ b/llvm/test/Transforms/InstSimplify/assume_icmp.ll
@@ -93,14 +93,10 @@ define void @and(i32 %x, i32 %y, i32 %z) {
 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 [[Z:%.*]], [[Y]]
 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[AND]])
-; CHECK-NEXT:    [[CMP3:%.*]] = icmp ugt i32 [[X]], [[Y]]
-; CHECK-NEXT:    call void @use(i1 [[CMP3]])
-; CHECK-NEXT:    [[CMP4:%.*]] = icmp uge i32 [[X]], [[Y]]
-; CHECK-NEXT:    call void @use(i1 [[CMP4]])
-; CHECK-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[Z]], [[Y]]
-; CHECK-NEXT:    call void @use(i1 [[CMP5]])
-; CHECK-NEXT:    [[CMP6:%.*]] = icmp uge i32 [[Z]], [[Y]]
-; CHECK-NEXT:    call void @use(i1 [[CMP6]])
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    call void @use(i1 true)
 ; CHECK-NEXT:    ret void
 ;
   %cmp1 = icmp ugt i32 %x, %y



More information about the llvm-commits mailing list