Skip to content

Commit 5a612b8

Browse files
committed
Handle ult comparison constants exceeding 64 bit unsigned range
Use tryZExtValue in matchShiftULTCondition to ensure that constants that exceed 64 bit unsigned range do not cause a crash, and we instead bail on further analysis.
1 parent 1a4e312 commit 5a612b8

File tree

2 files changed

+38
-5
lines changed

2 files changed

+38
-5
lines changed

llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1545,12 +1545,15 @@ static Value *matchShiftULTCondition(BranchInst *BI, BasicBlock *LoopEntry,
15451545
BasicBlock *FalseSucc = BI->getSuccessor(1);
15461546
ICmpInst::Predicate Pred = Cond->getPredicate();
15471547

1548-
if (Pred == ICmpInst::ICMP_ULT && FalseSucc == LoopEntry) {
1549-
Threshold = CmpConst->getZExtValue();
1550-
return Cond->getOperand(0);
1551-
}
1548+
if (Pred != ICmpInst::ICMP_ULT || FalseSucc != LoopEntry)
1549+
return nullptr;
15521550

1553-
return nullptr;
1551+
std::optional<uint64_t> ValIntOpt = CmpConst->getValue().tryZExtValue();
1552+
if (!ValIntOpt)
1553+
return nullptr;
1554+
1555+
Threshold = *ValIntOpt;
1556+
return Cond->getOperand(0);
15541557
}
15551558

15561559
// Check if the recurrence variable `VarX` is in the right form to create

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,36 @@ 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.
778+
779+
define i128 @large_constant(i128 noundef %n) {
780+
; CHECK-LABEL: define i128 @large_constant(
781+
; CHECK-SAME: i128 noundef [[N:%.*]]) {
782+
; CHECK-NEXT: entry:
783+
; CHECK-NEXT: br label [[DO_BODY:%.*]]
784+
; CHECK: do.body:
785+
; CHECK-NEXT: [[N_ADDR_0:%.*]] = phi i128 [ [[N]], [[ENTRY:%.*]] ], [ [[SHR:%.*]], [[DO_BODY]] ]
786+
; CHECK-NEXT: [[SHR]] = lshr i128 [[N_ADDR_0]], 1
787+
; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ult i128 [[N_ADDR_0]], 18446744073709551616
788+
; CHECK-NEXT: br i1 [[CMP_NOT]], label [[DO_END:%.*]], label [[DO_BODY]]
789+
; CHECK: do.end:
790+
; CHECK-NEXT: [[SHR_LCSSA:%.*]] = phi i128 [ [[SHR]], [[DO_BODY]] ]
791+
; CHECK-NEXT: ret i128 [[SHR_LCSSA]]
792+
;
793+
entry:
794+
br label %do.body
795+
796+
do.body: ; preds = %do.body, %entry
797+
%n.addr.0 = phi i128 [ %n, %entry ], [ %shr, %do.body ]
798+
%shr = lshr i128 %n.addr.0, 1
799+
%cmp.not = icmp ult i128 %n.addr.0, 18446744073709551616
800+
br i1 %cmp.not, label %do.end, label %do.body
801+
802+
do.end: ; preds = %do.body
803+
ret i128 %shr
804+
}
805+
776806

777807
declare i32 @llvm.abs.i32(i32, i1)
778808
declare i16 @llvm.abs.i16(i16, i1)

0 commit comments

Comments
 (0)