Skip to content

Commit 75dcb6a

Browse files
committed
[SCCP] Strengthen two-instruction range checks
1 parent 6ef74bb commit 75dcb6a

File tree

2 files changed

+24
-19
lines changed

2 files changed

+24
-19
lines changed

llvm/lib/Transforms/Utils/SCCPSolver.cpp

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -317,24 +317,29 @@ static Value *simplifyInstruction(SCCPSolver &Solver,
317317
// Early exit if we know nothing about X.
318318
if (LRange.isFullSet())
319319
return nullptr;
320-
// We are allowed to refine the comparison to either true or false for out
321-
// of range inputs. Here we refine the comparison to true, i.e. we relax
322-
// the range check.
323-
auto NewCR = CR->exactUnionWith(LRange.inverse());
324-
// TODO: Check if we can narrow the range check to an equality test.
325-
// E.g, for X in [0, 4), X - 3 u< 2 -> X == 3
326-
if (!NewCR)
320+
auto ConvertCRToICmp =
321+
[&](const std::optional<ConstantRange> &NewCR) -> Value * {
322+
ICmpInst::Predicate Pred;
323+
APInt RHS;
324+
// Check if we can represent NewCR as an icmp predicate.
325+
if (NewCR && NewCR->getEquivalentICmp(Pred, RHS)) {
326+
IRBuilder<NoFolder> Builder(&Inst);
327+
Value *NewICmp =
328+
Builder.CreateICmp(Pred, X, ConstantInt::get(X->getType(), RHS));
329+
InsertedValues.insert(NewICmp);
330+
return NewICmp;
331+
}
327332
return nullptr;
328-
ICmpInst::Predicate Pred;
329-
APInt RHS;
330-
// Check if we can represent NewCR as an icmp predicate.
331-
if (NewCR->getEquivalentICmp(Pred, RHS)) {
332-
IRBuilder<NoFolder> Builder(&Inst);
333-
Value *NewICmp =
334-
Builder.CreateICmp(Pred, X, ConstantInt::get(X->getType(), RHS));
335-
InsertedValues.insert(NewICmp);
336-
return NewICmp;
337-
}
333+
};
334+
// We are allowed to refine the comparison to either true or false for out
335+
// of range inputs.
336+
// Here we refine the comparison to false, and check if we can narrow the
337+
// range check to an equality test.
338+
if (auto *V = ConvertCRToICmp(CR->exactIntersectWith(LRange)))
339+
return V;
340+
// Here we refine the comparison to true, i.e. we relax the range check.
341+
if (auto *V = ConvertCRToICmp(CR->exactUnionWith(LRange.inverse())))
342+
return V;
338343
}
339344
}
340345

llvm/test/Transforms/SCCP/relax-range-checks.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ define i1 @range_check_to_icmp_eq1(i32 range(i32 0, 4) %x) {
9393
; CHECK-LABEL: define i1 @range_check_to_icmp_eq1(
9494
; CHECK-SAME: i32 range(i32 0, 4) [[X:%.*]]) {
9595
; CHECK-NEXT: [[OFF:%.*]] = add nsw i32 [[X]], -3
96-
; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[X]], 3
96+
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X]], 3
9797
; CHECK-NEXT: ret i1 [[TMP1]]
9898
;
9999
%off = add nsw i32 %x, -3
@@ -105,7 +105,7 @@ define i1 @range_check_to_icmp_eq2(i32 range(i32 -1, 2) %x) {
105105
; CHECK-LABEL: define i1 @range_check_to_icmp_eq2(
106106
; CHECK-SAME: i32 range(i32 -1, 2) [[X:%.*]]) {
107107
; CHECK-NEXT: [[OFF:%.*]] = add nsw i32 [[X]], -1
108-
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[OFF]], -2
108+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], 1
109109
; CHECK-NEXT: ret i1 [[CMP]]
110110
;
111111
%off = add nsw i32 %x, -1

0 commit comments

Comments
 (0)