Skip to content

Commit 897347c

Browse files
committed
[ValueTracking] Use findValuesAffectedByCondition to get ephemerals part of assume condition.
1 parent f321614 commit 897347c

File tree

6 files changed

+83
-52
lines changed

6 files changed

+83
-52
lines changed

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1268,7 +1268,8 @@ std::optional<bool> isImpliedByDomCondition(CmpPredicate Pred, const Value *LHS,
12681268
/// affected by the condition \p Cond. Used by AssumptionCache and
12691269
/// DomConditionCache.
12701270
void findValuesAffectedByCondition(Value *Cond, bool IsAssume,
1271-
function_ref<void(Value *)> InsertAffected);
1271+
function_ref<void(Value *)> InsertAffected,
1272+
bool EphemeralOnly = false);
12721273

12731274
} // end namespace llvm
12741275

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 70 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,17 @@ static bool isEphemeralValueOf(const Instruction *I, const Value *E) {
473473
}
474474
}
475475

476-
return false;
476+
auto *Assume = dyn_cast<AssumeInst>(I);
477+
if (!Assume)
478+
return false;
479+
480+
SmallVector<const Value *, 8> Affected;
481+
auto InsertAffected = [&Affected](Value *V) { Affected.push_back(V); };
482+
483+
findValuesAffectedByCondition(Assume->getArgOperand(0), /*IsAssume=*/true,
484+
InsertAffected, /*EphemeralOnly=*/true);
485+
486+
return is_contained(Affected, E);
477487
}
478488

479489
// Is this an intrinsic that cannot be speculated but also cannot trap?
@@ -10200,35 +10210,39 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned,
1020010210
}
1020110211

1020210212
static void
10203-
addValueAffectedByCondition(Value *V,
10213+
addValueAffectedByCondition(Value *V, bool EphemeralOnly, bool Ephemeral,
1020410214
function_ref<void(Value *)> InsertAffected) {
1020510215
assert(V != nullptr);
10206-
if (isa<Argument>(V) || isa<GlobalValue>(V)) {
10216+
if (!EphemeralOnly && (isa<Argument>(V) || isa<GlobalValue>(V))) {
1020710217
InsertAffected(V);
1020810218
} else if (auto *I = dyn_cast<Instruction>(V)) {
10209-
InsertAffected(V);
10210-
1021110219
// Peek through unary operators to find the source of the condition.
1021210220
Value *Op;
1021310221
if (match(I, m_CombineOr(m_PtrToInt(m_Value(Op)), m_Trunc(m_Value(Op))))) {
10214-
if (isa<Instruction>(Op) || isa<Argument>(Op))
10222+
Ephemeral = true;
10223+
if (!EphemeralOnly && (isa<Instruction>(Op) || isa<Argument>(Op)))
1021510224
InsertAffected(Op);
1021610225
}
10226+
if (Ephemeral || !EphemeralOnly)
10227+
InsertAffected(V);
1021710228
}
1021810229
}
1021910230

1022010231
void llvm::findValuesAffectedByCondition(
10221-
Value *Cond, bool IsAssume, function_ref<void(Value *)> InsertAffected) {
10222-
auto AddAffected = [&InsertAffected](Value *V) {
10223-
addValueAffectedByCondition(V, InsertAffected);
10232+
Value *Cond, bool IsAssume, function_ref<void(Value *)> InsertAffected,
10233+
bool EphemeralOnly) {
10234+
auto AddAffected = [&InsertAffected, EphemeralOnly](Value *V,
10235+
bool Ephemeral) {
10236+
addValueAffectedByCondition(V, EphemeralOnly, Ephemeral, InsertAffected);
1022410237
};
1022510238

10226-
auto AddCmpOperands = [&AddAffected, IsAssume](Value *LHS, Value *RHS) {
10239+
auto AddCmpOperands = [&AddAffected, IsAssume](Value *LHS, Value *RHS,
10240+
bool EphemeralLhs) {
1022710241
if (IsAssume) {
10228-
AddAffected(LHS);
10229-
AddAffected(RHS);
10242+
AddAffected(LHS, EphemeralLhs);
10243+
AddAffected(RHS, /*Ephemeral=*/false);
1023010244
} else if (match(RHS, m_Constant()))
10231-
AddAffected(LHS);
10245+
AddAffected(LHS, EphemeralLhs);
1023210246
};
1023310247

1023410248
SmallVector<Value *, 8> Worklist;
@@ -10241,11 +10255,12 @@ void llvm::findValuesAffectedByCondition(
1024110255

1024210256
CmpPredicate Pred;
1024310257
Value *A, *B, *X;
10258+
bool EphemeralA = false;
1024410259

1024510260
if (IsAssume) {
10246-
AddAffected(V);
10261+
AddAffected(V, /*Ephemeral=*/true);
1024710262
if (match(V, m_Not(m_Value(X))))
10248-
AddAffected(X);
10263+
AddAffected(X, /*Ephemeral=*/true);
1024910264
}
1025010265

1025110266
if (match(V, m_LogicalOp(m_Value(A), m_Value(B)))) {
@@ -10260,28 +10275,36 @@ void llvm::findValuesAffectedByCondition(
1026010275
}
1026110276
} else if (match(V, m_ICmp(Pred, m_Value(A), m_Value(B)))) {
1026210277
bool HasRHSC = match(B, m_ConstantInt());
10278+
if (HasRHSC && match(A, m_Intrinsic<Intrinsic::ctpop>(m_Value(X)))) {
10279+
AddAffected(X, /*Ephemeral=*/false);
10280+
EphemeralA = true;
10281+
}
10282+
1026310283
if (ICmpInst::isEquality(Pred)) {
10264-
AddAffected(A);
10265-
AddAffected(B);
1026610284
if (HasRHSC) {
1026710285
Value *Y;
1026810286
// (X & C) or (X | C).
1026910287
// (X << C) or (X >>_s C) or (X >>_u C).
10270-
if (match(A, m_Shift(m_Value(X), m_ConstantInt())))
10271-
AddAffected(X);
10272-
else if (match(A, m_And(m_Value(X), m_Value(Y))) ||
10273-
match(A, m_Or(m_Value(X), m_Value(Y)))) {
10274-
AddAffected(X);
10275-
AddAffected(Y);
10288+
if (match(A, m_Shift(m_Value(X), m_ConstantInt()))) {
10289+
AddAffected(X, /*Ephemeral=*/false);
10290+
EphemeralA = true;
10291+
} else if (match(A, m_And(m_Value(X), m_Value(Y))) ||
10292+
match(A, m_Or(m_Value(X), m_Value(Y)))) {
10293+
AddAffected(X, /*Ephemeral=*/false);
10294+
AddAffected(Y, /*Ephemeral=*/false);
10295+
EphemeralA = true;
1027610296
}
1027710297
}
10298+
AddAffected(A, EphemeralA);
10299+
AddAffected(B, /*Ephemeral=*/false);
1027810300
} else {
10279-
AddCmpOperands(A, B);
1028010301
if (HasRHSC) {
1028110302
// Handle (A + C1) u< C2, which is the canonical form of
1028210303
// A > C3 && A < C4.
10283-
if (match(A, m_AddLike(m_Value(X), m_ConstantInt())))
10284-
AddAffected(X);
10304+
if (match(A, m_AddLike(m_Value(X), m_ConstantInt()))) {
10305+
AddAffected(X, /*Ephemeral=*/false);
10306+
EphemeralA = true;
10307+
}
1028510308

1028610309
if (ICmpInst::isUnsigned(Pred)) {
1028710310
Value *Y;
@@ -10291,46 +10314,51 @@ void llvm::findValuesAffectedByCondition(
1029110314
if (match(A, m_And(m_Value(X), m_Value(Y))) ||
1029210315
match(A, m_Or(m_Value(X), m_Value(Y))) ||
1029310316
match(A, m_NUWAdd(m_Value(X), m_Value(Y)))) {
10294-
AddAffected(X);
10295-
AddAffected(Y);
10317+
AddAffected(X, /*Ephemeral=*/false);
10318+
AddAffected(Y, /*Ephemeral=*/false);
1029610319
}
1029710320
// X nuw- Y u> C -> X u> C
1029810321
if (match(A, m_NUWSub(m_Value(X), m_Value())))
10299-
AddAffected(X);
10322+
AddAffected(X, /*Ephemeral=*/false);
1030010323
}
1030110324
}
1030210325

1030310326
// Handle icmp slt/sgt (bitcast X to int), 0/-1, which is supported
1030410327
// by computeKnownFPClass().
1030510328
if (match(A, m_ElementWiseBitCast(m_Value(X)))) {
10306-
if (Pred == ICmpInst::ICMP_SLT && match(B, m_Zero()))
10329+
if (Pred == ICmpInst::ICMP_SLT && match(B, m_Zero())) {
1030710330
InsertAffected(X);
10308-
else if (Pred == ICmpInst::ICMP_SGT && match(B, m_AllOnes()))
10331+
EphemeralA = true;
10332+
} else if (Pred == ICmpInst::ICMP_SGT && match(B, m_AllOnes())) {
1030910333
InsertAffected(X);
10334+
EphemeralA = true;
10335+
}
1031010336
}
10311-
}
1031210337

10313-
if (HasRHSC && match(A, m_Intrinsic<Intrinsic::ctpop>(m_Value(X))))
10314-
AddAffected(X);
10338+
AddCmpOperands(A, B, EphemeralA);
10339+
}
1031510340
} else if (match(V, m_FCmp(Pred, m_Value(A), m_Value(B)))) {
10316-
AddCmpOperands(A, B);
10317-
1031810341
// fcmp fneg(x), y
1031910342
// fcmp fabs(x), y
1032010343
// fcmp fneg(fabs(x)), y
10321-
if (match(A, m_FNeg(m_Value(A))))
10322-
AddAffected(A);
10323-
if (match(A, m_FAbs(m_Value(A))))
10324-
AddAffected(A);
10344+
if (match(A, m_FNeg(m_Value(X)))) {
10345+
AddAffected(X, /*Ephemeral=*/false);
10346+
EphemeralA = true;
10347+
}
10348+
if (match(A, m_FAbs(m_Value(X)))) {
10349+
AddAffected(X, /*Ephemeral=*/false);
10350+
EphemeralA = true;
10351+
}
1032510352

10353+
AddCmpOperands(A, B, EphemeralA);
1032610354
} else if (match(V, m_Intrinsic<Intrinsic::is_fpclass>(m_Value(A),
1032710355
m_Value()))) {
1032810356
// Handle patterns that computeKnownFPClass() support.
10329-
AddAffected(A);
10357+
AddAffected(A, /*Ephemeral=*/false);
1033010358
} else if (!IsAssume && match(V, m_Trunc(m_Value(X)))) {
1033110359
// Assume is checked here as X is already added above for assumes in
1033210360
// addValueAffectedByCondition
10333-
AddAffected(X);
10361+
AddAffected(X, /*Ephemeral=*/false);
1033410362
} else if (!IsAssume && match(V, m_Not(m_Value(X)))) {
1033510363
// Assume is checked here to avoid issues with ephemeral values
1033610364
Worklist.push_back(X);

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

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

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

llvm/test/Transforms/CorrelatedValuePropagation/add.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -562,12 +562,12 @@ join:
562562
ret i32 %add
563563
}
564564

565-
; todo do not remove the assume condition
566565
define i32 @issue90206(i32 noundef %x) {
567566
; CHECK-LABEL: define range(i32 0, -2147483648) i32 @issue90206(
568567
; CHECK-SAME: i32 noundef [[X:%.*]]) {
569568
; CHECK-NEXT: [[R:%.*]] = add i32 [[X]], -1
570-
; CHECK-NEXT: tail call void @llvm.assume(i1 true)
569+
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[R]], -1
570+
; CHECK-NEXT: tail call void @llvm.assume(i1 [[TMP1]])
571571
; CHECK-NEXT: ret i32 [[R]]
572572
;
573573
%r = add i32 %x, -1

llvm/test/Transforms/InstCombine/zext-or-icmp.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,11 @@ define i8 @PR49475_infloop(i32 %t0, i16 %insert, i64 %e, i8 %i162) "instcombine-
180180
; CHECK-NEXT: [[SEXT:%.*]] = shl i64 [[SUB17]], 32
181181
; CHECK-NEXT: [[CONV18:%.*]] = ashr exact i64 [[SEXT]], 32
182182
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i64 [[XOR]], [[CONV18]]
183-
; CHECK-NEXT: [[TRUNC44:%.*]] = zext i1 [[CMP]] to i8
184-
; CHECK-NEXT: [[INC:%.*]] = add i8 [[I162]], [[TRUNC44]]
185-
; CHECK-NEXT: [[TOBOOL23_NOT:%.*]] = xor i1 [[CMP]], true
183+
; CHECK-NEXT: [[CONV19:%.*]] = zext i1 [[CMP]] to i16
184+
; CHECK-NEXT: [[OR21:%.*]] = or i16 [[INSERT]], [[CONV19]]
185+
; CHECK-NEXT: [[TOBOOL23_NOT:%.*]] = icmp eq i16 [[OR21]], 0
186186
; CHECK-NEXT: call void @llvm.assume(i1 [[TOBOOL23_NOT]])
187-
; CHECK-NEXT: ret i8 [[INC]]
187+
; CHECK-NEXT: ret i8 [[I162]]
188188
;
189189
%b = icmp eq i32 %t0, 0
190190
%b2 = icmp eq i16 %insert, 0

llvm/test/Transforms/InstSimplify/ctpop-pow2.ll

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,12 @@ define <2 x i32> @ctpop_lshr_intmin_vec(<2 x i32> %x) {
148148
ret <2 x i32> %cnt
149149
}
150150

151-
; todo do not remove the assume
152151
define i1 @issue128152(i32 %x) {
153152
; CHECK-LABEL: @issue128152(
154-
; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[X:%.*]], 0
153+
; CHECK-NEXT: [[CTPOP:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X:%.*]])
154+
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[CTPOP]], 1
155+
; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
156+
; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[X]], 0
155157
; CHECK-NEXT: ret i1 [[RES]]
156158
;
157159
%ctpop = call i32 @llvm.ctpop.i32(i32 %x)

0 commit comments

Comments
 (0)