Skip to content

Commit 6231876

Browse files
committed
Use APInt for threshold in matchShiftULTCondition
Use APInt for the threshold in matchShiftULTCondition, so that the function works for integers of arbitrary precision (rather than just those within the range of uint64_t).
1 parent 1a4e312 commit 6231876

File tree

2 files changed

+36
-5
lines changed

2 files changed

+36
-5
lines changed

llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1530,7 +1530,7 @@ static Value *matchCondition(BranchInst *BI, BasicBlock *LoopEntry,
15301530
/// the control yields to the loop entry. If the branch matches the behaviour,
15311531
/// the variable involved in the comparison is returned.
15321532
static Value *matchShiftULTCondition(BranchInst *BI, BasicBlock *LoopEntry,
1533-
uint64_t &Threshold) {
1533+
APInt &Threshold) {
15341534
if (!BI || !BI->isConditional())
15351535
return nullptr;
15361536

@@ -1546,7 +1546,7 @@ static Value *matchShiftULTCondition(BranchInst *BI, BasicBlock *LoopEntry,
15461546
ICmpInst::Predicate Pred = Cond->getPredicate();
15471547

15481548
if (Pred == ICmpInst::ICMP_ULT && FalseSucc == LoopEntry) {
1549-
Threshold = CmpConst->getZExtValue();
1549+
Threshold = CmpConst->getValue();
15501550
return Cond->getOperand(0);
15511551
}
15521552

@@ -1595,7 +1595,7 @@ static bool detectShiftUntilLessThanIdiom(Loop *CurLoop, const DataLayout &DL,
15951595
Intrinsic::ID &IntrinID,
15961596
Value *&InitX, Instruction *&CntInst,
15971597
PHINode *&CntPhi, Instruction *&DefX,
1598-
uint64_t &Threshold) {
1598+
APInt &Threshold) {
15991599
BasicBlock *LoopEntry;
16001600

16011601
DefX = nullptr;
@@ -2012,7 +2012,7 @@ bool LoopIdiomRecognize::recognizeShiftUntilLessThan() {
20122012
PHINode *CntPhi = nullptr;
20132013
Instruction *CntInst = nullptr;
20142014

2015-
uint64_t LoopThreshold;
2015+
APInt LoopThreshold;
20162016
if (!detectShiftUntilLessThanIdiom(CurLoop, *DL, IntrinID, InitX, CntInst,
20172017
CntPhi, DefX, LoopThreshold))
20182018
return false;
@@ -2041,7 +2041,7 @@ bool LoopIdiomRecognize::recognizeShiftUntilLessThan() {
20412041
if (!PreCondBI)
20422042
return false;
20432043

2044-
uint64_t PreLoopThreshold;
2044+
APInt PreLoopThreshold;
20452045
if (matchShiftULTCondition(PreCondBI, PH, PreLoopThreshold) != InitX ||
20462046
PreLoopThreshold != 2)
20472047
return false;

llvm/test/Transforms/LoopIdiom/AArch64/ctlz.ll

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,37 @@ do.end: ; preds = %do.body
773773
ret i32 %inc.0
774774
}
775775

776+
; Check that we correctly bail on analysis when the ult comparison is with a
777+
; constant that exceeds the (unsigned) range of a 64-bit integer, as we currently
778+
; only handle loopback condition ult 2 or 4.
779+
780+
define i128 @large_constant(i128 noundef %n) {
781+
; CHECK-LABEL: define i128 @large_constant(
782+
; CHECK-SAME: i128 noundef [[N:%.*]]) {
783+
; CHECK-NEXT: entry:
784+
; CHECK-NEXT: br label [[DO_BODY:%.*]]
785+
; CHECK: do.body:
786+
; CHECK-NEXT: [[N_ADDR_0:%.*]] = phi i128 [ [[N]], [[ENTRY:%.*]] ], [ [[SHR:%.*]], [[DO_BODY]] ]
787+
; CHECK-NEXT: [[SHR]] = lshr i128 [[N_ADDR_0]], 1
788+
; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ult i128 [[N_ADDR_0]], 18446744073709551616
789+
; CHECK-NEXT: br i1 [[CMP_NOT]], label [[DO_END:%.*]], label [[DO_BODY]]
790+
; CHECK: do.end:
791+
; CHECK-NEXT: [[SHR_LCSSA:%.*]] = phi i128 [ [[SHR]], [[DO_BODY]] ]
792+
; CHECK-NEXT: ret i128 [[SHR_LCSSA]]
793+
;
794+
entry:
795+
br label %do.body
796+
797+
do.body: ; preds = %do.body, %entry
798+
%n.addr.0 = phi i128 [ %n, %entry ], [ %shr, %do.body ]
799+
%shr = lshr i128 %n.addr.0, 1
800+
%cmp.not = icmp ult i128 %n.addr.0, 18446744073709551616
801+
br i1 %cmp.not, label %do.end, label %do.body
802+
803+
do.end: ; preds = %do.body
804+
ret i128 %shr
805+
}
806+
776807

777808
declare i32 @llvm.abs.i32(i32, i1)
778809
declare i16 @llvm.abs.i16(i16, i1)

0 commit comments

Comments
 (0)