Skip to content

Commit 137baab

Browse files
committed
[LVI][CVP] Fold trunc bittest to true/false.
1 parent f8ab91f commit 137baab

File tree

3 files changed

+45
-14
lines changed

3 files changed

+45
-14
lines changed

llvm/lib/Analysis/LazyValueInfo.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,8 @@ class LazyValueInfoImpl {
398398
std::optional<ValueLatticeElement>
399399
getValueFromICmpCondition(Value *Val, ICmpInst *ICI, bool isTrueDest,
400400
bool UseBlockValue);
401+
std::optional<ValueLatticeElement>
402+
getValueFromTrunc(Value *Val, TruncInst *Trunc, bool IsTrueDest);
401403

402404
std::optional<ValueLatticeElement>
403405
getValueFromCondition(Value *Val, Value *Cond, bool IsTrueDest,
@@ -1283,6 +1285,20 @@ std::optional<ValueLatticeElement> LazyValueInfoImpl::getValueFromICmpCondition(
12831285
return ValueLatticeElement::getOverdefined();
12841286
}
12851287

1288+
std::optional<ValueLatticeElement>
1289+
LazyValueInfoImpl::getValueFromTrunc(Value *Val, TruncInst *Trunc,
1290+
bool IsTrueDest) {
1291+
assert(Trunc->getType()->isIntegerTy(1));
1292+
1293+
Type *Ty = Val->getType();
1294+
if (!Ty->isIntegerTy() || Trunc->getOperand(0) != Val)
1295+
return ValueLatticeElement::getOverdefined();
1296+
1297+
if (IsTrueDest)
1298+
return ValueLatticeElement::getNot(Constant::getNullValue(Ty));
1299+
return ValueLatticeElement::getNot(Constant::getAllOnesValue(Ty));
1300+
}
1301+
12861302
// Handle conditions of the form
12871303
// extractvalue(op.with.overflow(%x, C), 1).
12881304
static ValueLatticeElement getValueFromOverflowCondition(
@@ -1312,6 +1328,9 @@ LazyValueInfoImpl::getValueFromCondition(Value *Val, Value *Cond,
13121328
if (ICmpInst *ICI = dyn_cast<ICmpInst>(Cond))
13131329
return getValueFromICmpCondition(Val, ICI, IsTrueDest, UseBlockValue);
13141330

1331+
if (auto *Trunc = dyn_cast<TruncInst>(Cond))
1332+
return getValueFromTrunc(Val, Trunc, IsTrueDest);
1333+
13151334
if (auto *EVI = dyn_cast<ExtractValueInst>(Cond))
13161335
if (auto *WO = dyn_cast<WithOverflowInst>(EVI->getAggregateOperand()))
13171336
if (EVI->getNumIndices() == 1 && *EVI->idx_begin() == 1)

llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,21 @@ static bool processCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
348348
return false;
349349
}
350350

351+
static bool processTrunc(TruncInst *Trunc, LazyValueInfo *LVI) {
352+
Type *Ty = Trunc->getType();
353+
if (!Ty->isIntegerTy(1))
354+
return false;
355+
356+
Value *Arg = Trunc->getOperand(0);
357+
ConstantRange Res = LVI->getConstantRange(Arg, Trunc, false);
358+
if (Res.contains(APInt::getZero(Arg->getType()->getScalarSizeInBits())))
359+
return false;
360+
361+
Trunc->replaceAllUsesWith(ConstantInt::getTrue(Ty));
362+
Trunc->eraseFromParent();
363+
return true;
364+
}
365+
351366
/// Simplify a switch instruction by removing cases which can never fire. If the
352367
/// uselessness of a case could be determined locally then constant propagation
353368
/// would already have figured it out. Instead, walk the predecessors and
@@ -1239,6 +1254,9 @@ static bool runImpl(Function &F, LazyValueInfo *LVI, DominatorTree *DT,
12391254
case Instruction::FCmp:
12401255
BBChanged |= processCmp(cast<CmpInst>(&II), LVI);
12411256
break;
1257+
case Instruction::Trunc:
1258+
BBChanged |= processTrunc(cast<TruncInst>(&II), LVI);
1259+
break;
12421260
case Instruction::Call:
12431261
case Instruction::Invoke:
12441262
BBChanged |= processCallSite(cast<CallBase>(II), LVI);

llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,10 +1515,8 @@ define void @test_trunc_bittest(i8 %a) {
15151515
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[A:%.*]] to i1
15161516
; CHECK-NEXT: br i1 [[TRUNC]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
15171517
; CHECK: if.true:
1518-
; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[A]], 0
1519-
; CHECK-NEXT: call void @check1(i1 [[CMP1]])
1520-
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[A]], 0
1521-
; CHECK-NEXT: call void @check1(i1 [[CMP2]])
1518+
; CHECK-NEXT: call void @check1(i1 true)
1519+
; CHECK-NEXT: call void @check1(i1 false)
15221520
; CHECK-NEXT: ret void
15231521
; CHECK: if.false:
15241522
; CHECK-NEXT: ret void
@@ -1543,10 +1541,8 @@ define void @test_trunc_not_bittest(i8 %a) {
15431541
; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[TRUNC]], true
15441542
; CHECK-NEXT: br i1 [[NOT]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]]
15451543
; CHECK: if.true:
1546-
; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[A]], -1
1547-
; CHECK-NEXT: call void @check1(i1 [[CMP1]])
1548-
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[A]], -1
1549-
; CHECK-NEXT: call void @check1(i1 [[CMP2]])
1544+
; CHECK-NEXT: call void @check1(i1 true)
1545+
; CHECK-NEXT: call void @check1(i1 false)
15501546
; CHECK-NEXT: ret void
15511547
; CHECK: if.false:
15521548
; CHECK-NEXT: ret void
@@ -1571,8 +1567,7 @@ define void @test_icmp_trunc(i8 %a) {
15711567
; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[A:%.*]], 0
15721568
; CHECK-NEXT: br i1 [[CMP1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
15731569
; CHECK: if.true:
1574-
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[A]] to i1
1575-
; CHECK-NEXT: call void @check1(i1 [[TRUNC]])
1570+
; CHECK-NEXT: call void @check1(i1 true)
15761571
; CHECK-NEXT: ret void
15771572
; CHECK: if.false:
15781573
; CHECK-NEXT: ret void
@@ -1594,9 +1589,8 @@ define void @test_icmp_trunc_not(i8 %a) {
15941589
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[A:%.*]], -1
15951590
; CHECK-NEXT: br i1 [[CMP1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
15961591
; CHECK: if.true:
1597-
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[A]] to i1
1598-
; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[TRUNC]], true
1599-
; CHECK-NEXT: call void @check1(i1 [[TRUNC]])
1592+
; CHECK-NEXT: [[NOT:%.*]] = xor i1 true, true
1593+
; CHECK-NEXT: call void @check1(i1 [[NOT]])
16001594
; CHECK-NEXT: ret void
16011595
; CHECK: if.false:
16021596
; CHECK-NEXT: ret void
@@ -1607,7 +1601,7 @@ define void @test_icmp_trunc_not(i8 %a) {
16071601
if.true:
16081602
%trunc = trunc i8 %a to i1
16091603
%not = xor i1 %trunc, true
1610-
call void @check1(i1 %trunc)
1604+
call void @check1(i1 %not)
16111605
ret void
16121606

16131607
if.false:

0 commit comments

Comments
 (0)