Skip to content

Commit 8aebceb

Browse files
authored
[LVI] Add trunc to i1 handling. (#124480)
Proof: https://alive2.llvm.org/ce/z/yPrRp-
1 parent 52c1162 commit 8aebceb

File tree

3 files changed

+42
-30
lines changed

3 files changed

+42
-30
lines changed

llvm/lib/Analysis/LazyValueInfo.cpp

+26
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+
ValueLatticeElement getValueFromTrunc(Value *Val, TruncInst *Trunc,
402+
bool IsTrueDest);
401403

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

1288+
ValueLatticeElement LazyValueInfoImpl::getValueFromTrunc(Value *Val,
1289+
TruncInst *Trunc,
1290+
bool IsTrueDest) {
1291+
assert(Trunc->getType()->isIntOrIntVectorTy(1));
1292+
1293+
if (Trunc->getOperand(0) != Val)
1294+
return ValueLatticeElement::getOverdefined();
1295+
1296+
Type *Ty = Val->getType();
1297+
1298+
if (Trunc->hasNoUnsignedWrap()) {
1299+
if (IsTrueDest)
1300+
return ValueLatticeElement::get(ConstantInt::get(Ty, 1));
1301+
return ValueLatticeElement::get(Constant::getNullValue(Ty));
1302+
}
1303+
1304+
if (IsTrueDest)
1305+
return ValueLatticeElement::getNot(Constant::getNullValue(Ty));
1306+
return ValueLatticeElement::getNot(Constant::getAllOnesValue(Ty));
1307+
}
1308+
12861309
// Handle conditions of the form
12871310
// extractvalue(op.with.overflow(%x, C), 1).
12881311
static ValueLatticeElement getValueFromOverflowCondition(
@@ -1312,6 +1335,9 @@ LazyValueInfoImpl::getValueFromCondition(Value *Val, Value *Cond,
13121335
if (ICmpInst *ICI = dyn_cast<ICmpInst>(Cond))
13131336
return getValueFromICmpCondition(Val, ICI, IsTrueDest, UseBlockValue);
13141337

1338+
if (auto *Trunc = dyn_cast<TruncInst>(Cond))
1339+
return getValueFromTrunc(Val, Trunc, IsTrueDest);
1340+
13151341
if (auto *EVI = dyn_cast<ExtractValueInst>(Cond))
13161342
if (auto *WO = dyn_cast<WithOverflowInst>(EVI->getAggregateOperand()))
13171343
if (EVI->getNumIndices() == 1 && *EVI->idx_begin() == 1)

llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll

+4-6
Original file line numberDiff line numberDiff line change
@@ -557,9 +557,8 @@ define i16 @and_elide(i16 noundef %x) {
557557

558558
define i16 @and_elide_trunc_cond(i16 noundef %x) {
559559
; CHECK-LABEL: @and_elide_trunc_cond(
560-
; CHECK-NEXT: [[AND:%.*]] = and i16 [[X:%.*]], 1
561-
; CHECK-NEXT: [[CMP:%.*]] = trunc nuw i16 [[X]] to i1
562-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[AND]], i16 24
560+
; CHECK-NEXT: [[CMP:%.*]] = trunc nuw i16 [[X:%.*]] to i1
561+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[X]], i16 24
563562
; CHECK-NEXT: ret i16 [[SEL]]
564563
;
565564
%and = and i16 %x, 1
@@ -570,9 +569,8 @@ define i16 @and_elide_trunc_cond(i16 noundef %x) {
570569

571570
define <2 x i8> @and_elide_trunc_cond_vec(<2 x i8> noundef %x) {
572571
; CHECK-LABEL: @and_elide_trunc_cond_vec(
573-
; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 1)
574-
; CHECK-NEXT: [[CMP:%.*]] = trunc nuw <2 x i8> [[X]] to <2 x i1>
575-
; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[AND]], <2 x i8> splat (i8 24)
572+
; CHECK-NEXT: [[CMP:%.*]] = trunc nuw <2 x i8> [[X:%.*]] to <2 x i1>
573+
; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[X]], <2 x i8> splat (i8 24)
576574
; CHECK-NEXT: ret <2 x i8> [[SEL]]
577575
;
578576
%and = and <2 x i8> %x, splat (i8 1)

llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll

+12-24
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: [[CMP3:%.*]] = icmp ne i8 [[A]], 1
15231521
; CHECK-NEXT: call void @check1(i1 [[CMP3]])
15241522
; CHECK-NEXT: [[CMP4:%.*]] = icmp eq i8 [[A]], 1
@@ -1559,10 +1557,8 @@ define void @test_trunc_not_bittest(i8 %a) {
15591557
; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[TRUNC]], true
15601558
; CHECK-NEXT: br i1 [[NOT]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]]
15611559
; CHECK: if.true:
1562-
; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[A]], -1
1563-
; CHECK-NEXT: call void @check1(i1 [[CMP1]])
1564-
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[A]], -1
1565-
; CHECK-NEXT: call void @check1(i1 [[CMP2]])
1560+
; CHECK-NEXT: call void @check1(i1 true)
1561+
; CHECK-NEXT: call void @check1(i1 false)
15661562
; CHECK-NEXT: [[CMP3:%.*]] = icmp ne i8 [[A]], 0
15671563
; CHECK-NEXT: call void @check1(i1 [[CMP3]])
15681564
; CHECK-NEXT: [[CMP4:%.*]] = icmp eq i8 [[A]], 0
@@ -1603,14 +1599,10 @@ define void @test_trunc_nuw_bittest(i8 %a) {
16031599
; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i8 [[A:%.*]] to i1
16041600
; CHECK-NEXT: br i1 [[TRUNC]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
16051601
; CHECK: if.true:
1606-
; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[A]], 0
1607-
; CHECK-NEXT: call void @check1(i1 [[CMP1]])
1608-
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[A]], 0
1609-
; CHECK-NEXT: call void @check1(i1 [[CMP2]])
1610-
; CHECK-NEXT: [[CMP3:%.*]] = icmp ne i8 [[A]], 1
1611-
; CHECK-NEXT: call void @check1(i1 [[CMP3]])
1612-
; CHECK-NEXT: [[CMP4:%.*]] = icmp eq i8 [[A]], 1
1613-
; CHECK-NEXT: call void @check1(i1 [[CMP4]])
1602+
; CHECK-NEXT: call void @check1(i1 true)
1603+
; CHECK-NEXT: call void @check1(i1 false)
1604+
; CHECK-NEXT: call void @check1(i1 false)
1605+
; CHECK-NEXT: call void @check1(i1 true)
16141606
; CHECK-NEXT: ret void
16151607
; CHECK: if.false:
16161608
; CHECK-NEXT: ret void
@@ -1639,14 +1631,10 @@ define void @test_trunc_nuw_not_bittest(i8 %a) {
16391631
; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[TRUNC]], true
16401632
; CHECK-NEXT: br i1 [[NOT]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
16411633
; CHECK: if.true:
1642-
; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[A]], 0
1643-
; CHECK-NEXT: call void @check1(i1 [[CMP1]])
1644-
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[A]], 0
1645-
; CHECK-NEXT: call void @check1(i1 [[CMP2]])
1646-
; CHECK-NEXT: [[CMP3:%.*]] = icmp ne i8 [[A]], 1
1647-
; CHECK-NEXT: call void @check1(i1 [[CMP3]])
1648-
; CHECK-NEXT: [[CMP4:%.*]] = icmp eq i8 [[A]], 1
1649-
; CHECK-NEXT: call void @check1(i1 [[CMP4]])
1634+
; CHECK-NEXT: call void @check1(i1 false)
1635+
; CHECK-NEXT: call void @check1(i1 true)
1636+
; CHECK-NEXT: call void @check1(i1 true)
1637+
; CHECK-NEXT: call void @check1(i1 false)
16501638
; CHECK-NEXT: ret void
16511639
; CHECK: if.false:
16521640
; CHECK-NEXT: ret void

0 commit comments

Comments
 (0)