Skip to content

Commit 5aa39a6

Browse files
dtcxzywDanielCChen
authored andcommitted
[InstCombine] Drop range attributes in foldIsPowerOf2OrZero (llvm#112178)
Closes llvm#112078.
1 parent a180562 commit 5aa39a6

File tree

2 files changed

+43
-7
lines changed

2 files changed

+43
-7
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -935,21 +935,31 @@ static Value *foldSignedTruncationCheck(ICmpInst *ICmp0, ICmpInst *ICmp1,
935935

936936
/// Fold (icmp eq ctpop(X) 1) | (icmp eq X 0) into (icmp ult ctpop(X) 2) and
937937
/// fold (icmp ne ctpop(X) 1) & (icmp ne X 0) into (icmp ugt ctpop(X) 1).
938-
/// Also used for logical and/or, must be poison safe.
938+
/// Also used for logical and/or, must be poison safe if range attributes are
939+
/// dropped.
939940
static Value *foldIsPowerOf2OrZero(ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd,
940-
InstCombiner::BuilderTy &Builder) {
941+
InstCombiner::BuilderTy &Builder,
942+
InstCombinerImpl &IC) {
941943
CmpInst::Predicate Pred0, Pred1;
942944
Value *X;
943945
if (!match(Cmp0, m_ICmp(Pred0, m_Intrinsic<Intrinsic::ctpop>(m_Value(X)),
944946
m_SpecificInt(1))) ||
945947
!match(Cmp1, m_ICmp(Pred1, m_Specific(X), m_ZeroInt())))
946948
return nullptr;
947949

948-
Value *CtPop = Cmp0->getOperand(0);
949-
if (IsAnd && Pred0 == ICmpInst::ICMP_NE && Pred1 == ICmpInst::ICMP_NE)
950+
auto *CtPop = cast<Instruction>(Cmp0->getOperand(0));
951+
if (IsAnd && Pred0 == ICmpInst::ICMP_NE && Pred1 == ICmpInst::ICMP_NE) {
952+
// Drop range attributes and re-infer them in the next iteration.
953+
CtPop->dropPoisonGeneratingAnnotations();
954+
IC.addToWorklist(CtPop);
950955
return Builder.CreateICmpUGT(CtPop, ConstantInt::get(CtPop->getType(), 1));
951-
if (!IsAnd && Pred0 == ICmpInst::ICMP_EQ && Pred1 == ICmpInst::ICMP_EQ)
956+
}
957+
if (!IsAnd && Pred0 == ICmpInst::ICMP_EQ && Pred1 == ICmpInst::ICMP_EQ) {
958+
// Drop range attributes and re-infer them in the next iteration.
959+
CtPop->dropPoisonGeneratingAnnotations();
960+
IC.addToWorklist(CtPop);
952961
return Builder.CreateICmpULT(CtPop, ConstantInt::get(CtPop->getType(), 2));
962+
}
953963

954964
return nullptr;
955965
}
@@ -3362,9 +3372,9 @@ Value *InstCombinerImpl::foldAndOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
33623372
/*IsLogical*/ false, Builder, Q))
33633373
return V;
33643374

3365-
if (Value *V = foldIsPowerOf2OrZero(LHS, RHS, IsAnd, Builder))
3375+
if (Value *V = foldIsPowerOf2OrZero(LHS, RHS, IsAnd, Builder, *this))
33663376
return V;
3367-
if (Value *V = foldIsPowerOf2OrZero(RHS, LHS, IsAnd, Builder))
3377+
if (Value *V = foldIsPowerOf2OrZero(RHS, LHS, IsAnd, Builder, *this))
33683378
return V;
33693379

33703380
// TODO: One of these directions is fine with logical and/or, the other could

llvm/test/Transforms/InstCombine/ispow2.ll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,3 +1546,29 @@ entry:
15461546
%sel = select i1 %cmp1, i1 true, i1 %cmp2
15471547
ret i1 %sel
15481548
}
1549+
1550+
define i1 @is_power2_or_zero_with_range(i32 %x) {
1551+
; CHECK-LABEL: @is_power2_or_zero_with_range(
1552+
; CHECK-NEXT: [[CTPOP:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
1553+
; CHECK-NEXT: [[RES:%.*]] = icmp ult i32 [[CTPOP]], 2
1554+
; CHECK-NEXT: ret i1 [[RES]]
1555+
;
1556+
%ctpop = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 %x)
1557+
%cmp = icmp eq i32 %ctpop, 1
1558+
%notzero = icmp eq i32 %x, 0
1559+
%res = select i1 %notzero, i1 true, i1 %cmp
1560+
ret i1 %res
1561+
}
1562+
1563+
define i1 @is_power2_or_zero_inv_with_range(i32 %x) {
1564+
; CHECK-LABEL: @is_power2_or_zero_inv_with_range(
1565+
; CHECK-NEXT: [[CTPOP:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
1566+
; CHECK-NEXT: [[RES:%.*]] = icmp ugt i32 [[CTPOP]], 1
1567+
; CHECK-NEXT: ret i1 [[RES]]
1568+
;
1569+
%ctpop = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 %x)
1570+
%cmp = icmp ne i32 %ctpop, 1
1571+
%notzero = icmp ne i32 %x, 0
1572+
%res = select i1 %notzero, i1 %cmp, i1 false
1573+
ret i1 %res
1574+
}

0 commit comments

Comments
 (0)