Skip to content

Commit c32b70e

Browse files
committed
[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.
1 parent 56cee12 commit c32b70e

File tree

5 files changed

+65
-65
lines changed

5 files changed

+65
-65
lines changed

llvm/include/llvm/Analysis/ConditionCacheUtil.h

Lines changed: 56 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
1+
//===- llvm/Analysis/ConditionCacheUtil.h -----------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Shared by DomConditionCache and AssumptionCache. Holds common operation of
10+
// finding values potentially affected by an assumed/branched on condition.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
114
#ifndef LLVM_ANALYSIS_CONDITIONCACHEUTIL_H
215
#define LLVM_ANALYSIS_CONDITIONCACHEUTIL_H
316

17+
#include "llvm/ADT/SmallVector.h"
418
#include "llvm/IR/PatternMatch.h"
519
#include <functional>
620

@@ -43,65 +57,58 @@ findValuesAffectedByCondition(Value *Cond, bool IsAssume,
4357
CmpInst::Predicate Pred;
4458
Value *A, *B, *X;
4559

46-
if (IsAssume)
60+
if (IsAssume) {
4761
AddAffected(V);
62+
if (match(V, m_Not(m_Value(X))))
63+
AddAffected(X);
64+
}
4865

49-
if (IsAssume && match(V, m_Not(m_Value(X))))
50-
AddAffected(X);
51-
if (!IsAssume && match(V, m_LogicalOp(m_Value(A), m_Value(B)))) {
66+
if (match(V, m_LogicalOp(m_Value(A), m_Value(B)))) {
5267
Worklist.push_back(A);
5368
Worklist.push_back(B);
54-
} else if (match(V, m_Cmp(Pred, m_Value(A), m_Value(B))) &&
55-
(IsAssume || isa<ICmpInst>(V))) {
56-
if (IsAssume || match(B, m_Constant())) {
69+
} else if (match(V, m_Cmp(Pred, m_Value(A), m_Value(B)))) {
70+
if (IsAssume) {
71+
AddAffected(A);
72+
AddAffected(B);
73+
} else if (match(B, m_Constant()))
5774
AddAffected(A);
58-
if (IsAssume)
59-
AddAffected(B);
6075

61-
if (IsAssume ? (Pred == ICmpInst::ICMP_EQ)
62-
: ICmpInst::isEquality(Pred)) {
63-
if (match(B, m_ConstantInt())) {
64-
// (X & C) or (X | C) or (X ^ C).
65-
// (X << C) or (X >>_s C) or (X >>_u C).
66-
if (match(A, m_BitwiseLogic(m_Value(X), m_ConstantInt())) ||
67-
match(A, m_Shift(m_Value(X), m_ConstantInt())))
68-
AddAffected(X);
69-
}
70-
} else {
71-
if (Pred == ICmpInst::ICMP_NE)
72-
if (match(A, m_And(m_Value(X), m_Power2())) && match(B, m_Zero()))
73-
AddAffected(X);
76+
if (ICmpInst::isEquality(Pred)) {
77+
if (match(B, m_ConstantInt())) {
78+
// (X & C) or (X | C) or (X ^ C).
79+
// (X << C) or (X >>_s C) or (X >>_u C).
80+
if (match(A, m_BitwiseLogic(m_Value(X), m_ConstantInt())) ||
81+
match(A, m_Shift(m_Value(X), m_ConstantInt())))
82+
AddAffected(X);
83+
}
84+
} else {
85+
// Handle (A + C1) u< C2, which is the canonical form of
86+
// A > C3 && A < C4.
87+
if (match(A, m_Add(m_Value(X), m_ConstantInt())) &&
88+
match(B, m_ConstantInt()))
89+
AddAffected(X);
7490

75-
if (!IsAssume || Pred == ICmpInst::ICMP_ULT) {
76-
// Handle (A + C1) u< C2, which is the canonical form of
77-
// A > C3 && A < C4.
78-
if (match(A, m_Add(m_Value(X), m_ConstantInt())) &&
79-
match(B, m_ConstantInt()))
80-
AddAffected(X);
81-
}
82-
if (!IsAssume) {
83-
// Handle icmp slt/sgt (bitcast X to int), 0/-1, which is supported
84-
// by computeKnownFPClass().
85-
if ((Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGT) &&
86-
match(A, m_ElementWiseBitCast(m_Value(X))))
87-
InsertAffected(X, -1);
88-
}
91+
// Handle icmp slt/sgt (bitcast X to int), 0/-1, which is supported
92+
// by computeKnownFPClass().
93+
if (match(A, m_ElementWiseBitCast(m_Value(X)))) {
94+
if (Pred == ICmpInst::ICMP_SLT && match(B, m_Zero()))
95+
InsertAffected(X, -1);
96+
else if (Pred == ICmpInst::ICMP_SGT && match(B, m_AllOnes()))
97+
InsertAffected(X, -1);
98+
}
8999

90-
if (IsAssume && CmpInst::isFPPredicate(Pred)) {
91-
// fcmp fneg(x), y
92-
// fcmp fabs(x), y
93-
// fcmp fneg(fabs(x)), y
94-
if (match(A, m_FNeg(m_Value(A))))
95-
AddAffected(A);
96-
if (match(A, m_FAbs(m_Value(A))))
97-
AddAffected(A);
98-
}
100+
if (CmpInst::isFPPredicate(Pred)) {
101+
// fcmp fneg(x), y
102+
// fcmp fabs(x), y
103+
// fcmp fneg(fabs(x)), y
104+
if (match(A, m_FNeg(m_Value(A))))
105+
AddAffected(A);
106+
if (match(A, m_FAbs(m_Value(A))))
107+
AddAffected(A);
99108
}
100109
}
101-
} else if ((!IsAssume &&
102-
match(Cond, m_FCmp(Pred, m_Value(A), m_Constant()))) ||
103-
match(Cond, m_Intrinsic<Intrinsic::is_fpclass>(m_Value(A),
104-
m_Value(B)))) {
110+
} else if (match(V, m_Intrinsic<Intrinsic::is_fpclass>(m_Value(A),
111+
m_Value()))) {
105112
// Handle patterns that computeKnownFPClass() support.
106113
AddAffected(A);
107114
}

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -806,15 +806,13 @@ void llvm::computeKnownBitsFromContext(const Value *V, KnownBits &Known,
806806
if (Depth == MaxAnalysisRecursionDepth)
807807
continue;
808808

809-
ICmpInst *Cmp = dyn_cast<ICmpInst>(Arg);
810-
if (!Cmp)
809+
if (!isa<ICmpInst>(Arg) && !match(Arg, m_LogicalOp(m_Value(), m_Value())))
811810
continue;
812811

813812
if (!isValidAssumeForContext(I, Q.CxtI, Q.DT))
814813
continue;
815814

816-
computeKnownBitsFromCmp(V, Cmp->getPredicate(), Cmp->getOperand(0),
817-
Cmp->getOperand(1), Known, Q);
815+
computeKnownBitsFromCond(V, Arg, Known, /*Depth*/ 0, Q, /*Invert*/ false);
818816
}
819817

820818
// Conflicting assumption: Undefined behavior will occur on this execution

llvm/test/Analysis/ValueTracking/numsignbits-from-assume.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ define i32 @computeNumSignBits_sub1(i32 %in) {
5151

5252
define i32 @computeNumSignBits_sub2(i32 %in) {
5353
; CHECK-LABEL: @computeNumSignBits_sub2(
54-
; CHECK-NEXT: [[SUB:%.*]] = add i32 [[IN:%.*]], -1
54+
; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[IN:%.*]], -1
5555
; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[SUB]], 43
5656
; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
5757
; CHECK-NEXT: [[SH:%.*]] = shl nuw nsw i32 [[SUB]], 3

llvm/test/Transforms/InstCombine/fpclass-from-dom-cond.ll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,9 @@ define i1 @test8(float %x) {
185185
; CHECK-NEXT: [[COND:%.*]] = fcmp oeq float [[ABS]], 0x7FF0000000000000
186186
; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
187187
; CHECK: if.then:
188-
; CHECK-NEXT: [[RET1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 575)
189-
; CHECK-NEXT: ret i1 [[RET1]]
188+
; CHECK-NEXT: ret i1 true
190189
; CHECK: if.else:
191-
; CHECK-NEXT: [[RET2:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 575)
190+
; CHECK-NEXT: [[RET2:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 59)
192191
; CHECK-NEXT: ret i1 [[RET2]]
193192
;
194193
%abs = call float @llvm.fabs.f32(float %x)

llvm/test/Transforms/InstSimplify/assume_icmp.ll

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,10 @@ define void @and(i32 %x, i32 %y, i32 %z) {
9393
; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[Z:%.*]], [[Y]]
9494
; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
9595
; CHECK-NEXT: call void @llvm.assume(i1 [[AND]])
96-
; CHECK-NEXT: [[CMP3:%.*]] = icmp ugt i32 [[X]], [[Y]]
97-
; CHECK-NEXT: call void @use(i1 [[CMP3]])
98-
; CHECK-NEXT: [[CMP4:%.*]] = icmp uge i32 [[X]], [[Y]]
99-
; CHECK-NEXT: call void @use(i1 [[CMP4]])
100-
; CHECK-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[Z]], [[Y]]
101-
; CHECK-NEXT: call void @use(i1 [[CMP5]])
102-
; CHECK-NEXT: [[CMP6:%.*]] = icmp uge i32 [[Z]], [[Y]]
103-
; CHECK-NEXT: call void @use(i1 [[CMP6]])
96+
; CHECK-NEXT: call void @use(i1 true)
97+
; CHECK-NEXT: call void @use(i1 true)
98+
; CHECK-NEXT: call void @use(i1 true)
99+
; CHECK-NEXT: call void @use(i1 true)
104100
; CHECK-NEXT: ret void
105101
;
106102
%cmp1 = icmp ugt i32 %x, %y

0 commit comments

Comments
 (0)