Skip to content

Instantly share code, notes, and snippets.

@annanay25
Last active July 18, 2017 13:30
Show Gist options
  • Save annanay25/bec53da307ab7d10a0263a4059182f33 to your computer and use it in GitHub Desktop.
Save annanay25/bec53da307ab7d10a0263a4059182f33 to your computer and use it in GitHub Desktop.
diff --git a/lib/Analysis/ScopInfo.cpp b/lib/Analysis/ScopInfo.cpp
index 18e8a89..da939e6 100644
--- a/lib/Analysis/ScopInfo.cpp
+++ b/lib/Analysis/ScopInfo.cpp
@@ -1584,12 +1584,104 @@ static bool buildConditionSets(
// to be set. The comparison is equal to a signed comparison under this
// assumption.
bool NonNeg = ICond->isUnsigned();
- LHS = getPwAff(S, BB, InvalidDomainMap,
- SE.getSCEVAtScope(ICond->getOperand(0), L), NonNeg);
- RHS = getPwAff(S, BB, InvalidDomainMap,
- SE.getSCEVAtScope(ICond->getOperand(1), L), NonNeg);
- ConsequenceCondSet =
- buildConditionSet(ICond->getPredicate(), LHS, RHS, Domain);
+
+ // Checking wrap-around for ICMP_ULT.
+ // ICMP_SLT is handled by design.
+ if (ICond->getPredicate() == ICmpInst::ICMP_ULT) {
+ // Case handling for 0 <= LHS < RHS
+ // But assuming LHS might have MSB set.
+ LHS = getPwAff(S, BB, InvalidDomainMap,
+ SE.getSCEVAtScope(ICond->getOperand(0), L), false);
+ RHS = getPwAff(S, BB, InvalidDomainMap,
+ SE.getSCEVAtScope(ICond->getOperand(1), L), true);
+
+ // 0 <= LHS
+ isl_set *ge = isl_pw_aff_ge_set(
+ isl_pw_aff_copy(LHS),
+ isl_pw_aff_zero_on_domain(
+ isl_local_space_from_space(isl_pw_aff_get_domain_space(LHS))));
+ // LHS < RHS
+ isl_set *gt = isl_pw_aff_gt_set(RHS, LHS);
+
+ ConsequenceCondSet = isl_set_intersect(ge, gt);
+ ConsequenceCondSet = setDimensionIds(Domain, ConsequenceCondSet);
+
+ }
+ // Checking wrap-around for ICMP_UGT.
+ // ICMP_SGT is handled by design.
+ else if (ICond->getPredicate() == ICmpInst::ICMP_UGT) {
+ // Case handling for LHS > RHS >= 0.
+ // But assuming RHS might have MSB set.
+ LHS = getPwAff(S, BB, InvalidDomainMap,
+ SE.getSCEVAtScope(ICond->getOperand(0), L), true);
+ RHS = getPwAff(S, BB, InvalidDomainMap,
+ SE.getSCEVAtScope(ICond->getOperand(1), L), false);
+
+ isl_set *ge, *gt;
+ // LHS > RHS
+ gt = isl_pw_aff_gt_set(LHS, isl_pw_aff_copy(RHS));
+ // RHS >= 0
+ ge = isl_pw_aff_ge_set(
+ RHS, isl_pw_aff_zero_on_domain(isl_local_space_from_space(
+ isl_pw_aff_get_domain_space(RHS))));
+
+ ConsequenceCondSet = isl_set_intersect(ge, gt);
+ ConsequenceCondSet = setDimensionIds(Domain, ConsequenceCondSet);
+
+ }
+ // Checking wrap-around for ICMP_UGE.
+ // ICMP_SGE is handled by design.
+ else if (ICond->getPredicate() == ICmpInst::ICMP_UGE) {
+ // Case handling for LHS >= RHS >= 0.
+ // But assuming RHS might have MSB set.
+ LHS = getPwAff(S, BB, InvalidDomainMap,
+ SE.getSCEVAtScope(ICond->getOperand(0), L), true);
+ RHS = getPwAff(S, BB, InvalidDomainMap,
+ SE.getSCEVAtScope(ICond->getOperand(1), L), false);
+
+ isl_set *ge_1, *ge_2;
+ // LHS >= RHS
+ ge_1 = isl_pw_aff_ge_set(LHS, isl_pw_aff_copy(RHS));
+ // RHS >= 0
+ ge_2 = isl_pw_aff_ge_set(
+ RHS, isl_pw_aff_zero_on_domain(isl_local_space_from_space(
+ isl_pw_aff_get_domain_space(RHS))));
+
+ ConsequenceCondSet = isl_set_intersect(ge_1, ge_2);
+ ConsequenceCondSet = setDimensionIds(Domain, ConsequenceCondSet);
+
+ }
+ // Checking wrap-around for ICMP_ULE.
+ // ICMP_SLE is handled by design.
+ else if (ICond->getPredicate() == ICmpInst::ICMP_ULE) {
+ // Case handling for 0 <= LHS <= RHS
+ // But assuming LHS might have MSB set.
+ LHS = getPwAff(S, BB, InvalidDomainMap,
+ SE.getSCEVAtScope(ICond->getOperand(0), L), false);
+ RHS = getPwAff(S, BB, InvalidDomainMap,
+ SE.getSCEVAtScope(ICond->getOperand(1), L), true);
+
+ isl_set *ge_1, *ge_2;
+ // 0 <= LHS
+ ge_1 = isl_pw_aff_ge_set(
+ isl_pw_aff_copy(LHS),
+ isl_pw_aff_zero_on_domain(
+ isl_local_space_from_space(isl_pw_aff_get_domain_space(LHS))));
+ // LHS <= RHS
+ ge_2 = isl_pw_aff_gt_set(RHS, LHS);
+
+ ConsequenceCondSet = isl_set_intersect(ge_1, ge_2);
+ ConsequenceCondSet = setDimensionIds(Domain, ConsequenceCondSet);
+
+ } else {
+ LHS = getPwAff(S, BB, InvalidDomainMap,
+ SE.getSCEVAtScope(ICond->getOperand(0), L), NonNeg);
+ RHS = getPwAff(S, BB, InvalidDomainMap,
+ SE.getSCEVAtScope(ICond->getOperand(1), L), NonNeg);
+
+ ConsequenceCondSet =
+ buildConditionSet(ICond->getPredicate(), LHS, RHS, Domain);
+ }
}
// If no terminator was given we are only looking for parameter constraints
diff --git a/test/ScopInfo/unsigned_wrap_ugt.ll b/test/ScopInfo/unsigned_wrap_ugt.ll
new file mode 100644
index 0000000..4427cca
--- /dev/null
+++ b/test/ScopInfo/unsigned_wrap_ugt.ll
@@ -0,0 +1,39 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+
+define void @func(double* noalias nonnull %A) {
+entry:
+ br label %for
+
+ for:
+ %j = phi i32 [-1, %entry], [%j.inc, %inc]
+ %j.cmp = icmp slt i32 %j, 65
+ br i1 %j.cmp, label %body, label %exit
+
+ body:
+ %inbounds = icmp ugt i32 64, %j
+ br i1 %inbounds, label %ifinbounds, label %ifoutbounds
+
+ ifinbounds:
+ %A_idx = getelementptr inbounds double, double* %A, i32 %j
+ store double 42.0, double* %A_idx
+ br label %inc
+
+ ifoutbounds:
+ br label %inc
+
+ inc:
+ %j.inc = add nuw nsw i32 %j, 1
+ br label %for
+
+ exit:
+ br label %return
+
+ return:
+ ret void
+}
+
+
+; CHECK: Region: %for---%return
+; CHECK: Domain :=
+; CHECK-NEXT: { Stmt_ifinbounds[i0] : 0 < i0 <= 64 };
+
diff --git a/test/ScopInfo/unsigned_wrap_ult.ll b/test/ScopInfo/unsigned_wrap_ult.ll
new file mode 100644
index 0000000..9808cc0
--- /dev/null
+++ b/test/ScopInfo/unsigned_wrap_ult.ll
@@ -0,0 +1,39 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+
+define void @func(double* noalias nonnull %A) {
+entry:
+ br label %for
+
+ for:
+ %j = phi i32 [-1, %entry], [%j.inc, %inc]
+ %j.cmp = icmp slt i32 %j, 65
+ br i1 %j.cmp, label %body, label %exit
+
+ body:
+ %inbounds = icmp ult i32 %j, 64
+ br i1 %inbounds, label %ifinbounds, label %ifoutbounds
+
+ ifinbounds:
+ %A_idx = getelementptr inbounds double, double* %A, i32 %j
+ store double 42.0, double* %A_idx
+ br label %inc
+
+ ifoutbounds:
+ br label %inc
+
+ inc:
+ %j.inc = add nuw nsw i32 %j, 1
+ br label %for
+
+ exit:
+ br label %return
+
+ return:
+ ret void
+}
+
+
+; CHECK: Region: %for---%return
+; CHECK: Domain :=
+; CHECK-NEXT: { Stmt_ifinbounds[i0] : 0 < i0 <= 64 };
+
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment