Skip to content

Commit 2379c6c

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 3bad2d4 commit 2379c6c

File tree

4 files changed

+78
-59
lines changed

4 files changed

+78
-59
lines changed

llvm/include/llvm/Analysis/ConditionCacheUtil.h

Lines changed: 73 additions & 55 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

@@ -32,6 +46,14 @@ findValuesAffectedByCondition(Value *Cond, bool IsAssume,
3246
addValueAffectedByCondition(V, InsertAffected);
3347
};
3448

49+
auto AddCmpOperands = [&AddAffected, IsAssume](Value *LHS, Value *RHS) {
50+
if (IsAssume) {
51+
AddAffected(LHS);
52+
AddAffected(RHS);
53+
} else if (match(RHS, m_Constant()))
54+
AddAffected(LHS);
55+
};
56+
3557
SmallVector<Value *, 8> Worklist;
3658
SmallPtrSet<Value *, 8> Visited;
3759
Worklist.push_back(Cond);
@@ -43,65 +65,61 @@ findValuesAffectedByCondition(Value *Cond, bool IsAssume,
4365
CmpInst::Predicate Pred;
4466
Value *A, *B, *X;
4567

46-
if (IsAssume)
68+
if (IsAssume) {
4769
AddAffected(V);
70+
if (match(V, m_Not(m_Value(X))))
71+
AddAffected(X);
72+
}
4873

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)))) {
52-
Worklist.push_back(A);
53-
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())) {
57-
AddAffected(A);
58-
if (IsAssume)
59-
AddAffected(B);
60-
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);
74-
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-
}
89-
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-
}
74+
if (match(V, m_LogicalOp(m_Value(A), m_Value(B)))) {
75+
// assume(A && B) is split to -> assume(A); assume(B);
76+
// assume(!(A || B)) is split to -> assume(!A); assume(!B);
77+
// TODO: We might want to handle assume(A || B) / assume(!(A && B)). If we
78+
// make this change make sure to update computeKnownBitsFromContext.
79+
if (!IsAssume) {
80+
Worklist.push_back(A);
81+
Worklist.push_back(B);
82+
}
83+
} else if (match(V, m_ICmp(Pred, m_Value(A), m_Value(B)))) {
84+
AddCmpOperands(A, B);
85+
86+
if (ICmpInst::isEquality(Pred)) {
87+
if (match(B, m_ConstantInt())) {
88+
// (X & C) or (X | C) or (X ^ C).
89+
// (X << C) or (X >>_s C) or (X >>_u C).
90+
if (match(A, m_BitwiseLogic(m_Value(X), m_ConstantInt())) ||
91+
match(A, m_Shift(m_Value(X), m_ConstantInt())))
92+
AddAffected(X);
93+
}
94+
} else {
95+
// Handle (A + C1) u< C2, which is the canonical form of
96+
// A > C3 && A < C4.
97+
if (match(A, m_Add(m_Value(X), m_ConstantInt())) &&
98+
match(B, m_ConstantInt()))
99+
AddAffected(X);
100+
101+
// Handle icmp slt/sgt (bitcast X to int), 0/-1, which is supported
102+
// by computeKnownFPClass().
103+
if (match(A, m_ElementWiseBitCast(m_Value(X)))) {
104+
if (Pred == ICmpInst::ICMP_SLT && match(B, m_Zero()))
105+
InsertAffected(X, -1);
106+
else if (Pred == ICmpInst::ICMP_SGT && match(B, m_AllOnes()))
107+
InsertAffected(X, -1);
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(Cond, m_FCmp(Pred, m_Value(A), m_Value(B)))) {
111+
AddCmpOperands(A, B);
112+
113+
// fcmp fneg(x), y
114+
// fcmp fabs(x), y
115+
// fcmp fneg(fabs(x)), y
116+
if (match(A, m_FNeg(m_Value(A))))
117+
AddAffected(A);
118+
if (match(A, m_FAbs(m_Value(A))))
119+
AddAffected(A);
120+
121+
} else if (match(V, m_Intrinsic<Intrinsic::is_fpclass>(m_Value(A),
122+
m_Value()))) {
105123
// Handle patterns that computeKnownFPClass() support.
106124
AddAffected(A);
107125
}

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,8 @@ void llvm::computeKnownBitsFromContext(const Value *V, KnownBits &Known,
813813
if (!isValidAssumeForContext(I, Q.CxtI, Q.DT))
814814
continue;
815815

816+
// Change to `computeKnownBitsFromCond` if we start supporting assume of
817+
// logic op in ConditionCacheUtil.
816818
computeKnownBitsFromCmp(V, Cmp->getPredicate(), Cmp->getOperand(0),
817819
Cmp->getOperand(1), Known, Q);
818820
}

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)

0 commit comments

Comments
 (0)