[llvm] [ValueTracking] Improve tracking for constant range of `{s|u}rem C` (PR #82303)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 19 19:58:58 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: None (goldsteinn)
<details>
<summary>Changes</summary>
- **[ValueTracking] Add tests for constant range of `{s|u}rem C**
- **[ValueTracking] Improve tracking for constant range of `{s|u}rem C**
---
Full diff: https://github.com/llvm/llvm-project/pull/82303.diff
2 Files Affected:
- (modified) llvm/lib/Analysis/ValueTracking.cpp (+13)
- (modified) llvm/test/Analysis/ValueTracking/constant-ranges.ll (+100)
``````````diff
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 1a076adb1bad0a..856243da8793ba 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -8776,6 +8776,16 @@ static void setLimitsForBinOp(const BinaryOperator &BO, APInt &Lower,
// 'srem x, C' produces (-|C|, |C|).
Upper = C->abs();
Lower = (-Upper) + 1;
+ } else if (match(BO.getOperand(0), m_APInt(C))) {
+ if (C->isNegative()) {
+ // 'srem -|C|, x' produces [-|C|, 0].
+ Upper = 1;
+ Lower = *C;
+ } else {
+ // 'srem |C|, x' produces [0, |C|].
+ Upper = *C + 1;
+ Lower = 0;
+ }
}
break;
@@ -8783,6 +8793,9 @@ static void setLimitsForBinOp(const BinaryOperator &BO, APInt &Lower,
if (match(BO.getOperand(1), m_APInt(C)))
// 'urem x, C' produces [0, C).
Upper = *C;
+ else if (match(BO.getOperand(0), m_APInt(C)))
+ // 'urem C, x' produces [0, C].
+ Upper = *C + 1;
break;
default:
diff --git a/llvm/test/Analysis/ValueTracking/constant-ranges.ll b/llvm/test/Analysis/ValueTracking/constant-ranges.ll
index 26e01efedd3dfc..c440cfad889d3b 100644
--- a/llvm/test/Analysis/ValueTracking/constant-ranges.ll
+++ b/llvm/test/Analysis/ValueTracking/constant-ranges.ll
@@ -130,3 +130,103 @@ define i1 @and_ugt_fail(i8 %xx) {
%r = icmp ugt i8 %x_p2, 127
ret i1 %r
}
+
+define i1 @urem_okay(i8 %x) {
+; CHECK-LABEL: @urem_okay(
+; CHECK-NEXT: ret i1 true
+;
+ %val = urem i8 34, %x
+ %r = icmp ule i8 %val, 35
+ ret i1 %r
+}
+
+define i1 @urem_fail(i8 %x) {
+; CHECK-LABEL: @urem_fail(
+; CHECK-NEXT: [[VAL:%.*]] = urem i8 34, [[X:%.*]]
+; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[VAL]], 33
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %val = urem i8 34, %x
+ %r = icmp ule i8 %val, 33
+ ret i1 %r
+}
+
+define i1 @srem_posC_okay0(i8 %x) {
+; CHECK-LABEL: @srem_posC_okay0(
+; CHECK-NEXT: ret i1 true
+;
+ %val = srem i8 34, %x
+ %r = icmp sle i8 %val, 34
+ ret i1 %r
+}
+
+define i1 @srem_posC_okay1(i8 %x) {
+; CHECK-LABEL: @srem_posC_okay1(
+; CHECK-NEXT: ret i1 true
+;
+ %val = srem i8 34, %x
+ %r = icmp sge i8 %val, -3
+ ret i1 %r
+}
+
+define i1 @srem_negC_okay0(i8 %x) {
+; CHECK-LABEL: @srem_negC_okay0(
+; CHECK-NEXT: ret i1 true
+;
+ %val = srem i8 -34, %x
+ %r = icmp sle i8 %val, 0
+ ret i1 %r
+}
+
+define i1 @srem_negC_okay1(i8 %x) {
+; CHECK-LABEL: @srem_negC_okay1(
+; CHECK-NEXT: ret i1 true
+;
+ %val = srem i8 -34, %x
+ %r = icmp sge i8 %val, -34
+ ret i1 %r
+}
+
+define i1 @srem_posC_fail0(i8 %x) {
+; CHECK-LABEL: @srem_posC_fail0(
+; CHECK-NEXT: [[VAL:%.*]] = srem i8 34, [[X:%.*]]
+; CHECK-NEXT: [[R:%.*]] = icmp sle i8 [[VAL]], 32
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %val = srem i8 34, %x
+ %r = icmp sle i8 %val, 32
+ ret i1 %r
+}
+
+define i1 @srem_posC_fail1(i8 %x) {
+; CHECK-LABEL: @srem_posC_fail1(
+; CHECK-NEXT: [[VAL:%.*]] = srem i8 34, [[X:%.*]]
+; CHECK-NEXT: [[R:%.*]] = icmp sge i8 [[VAL]], 1
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %val = srem i8 34, %x
+ %r = icmp sge i8 %val, 1
+ ret i1 %r
+}
+
+define i1 @srem_negC_fail0(i8 %x) {
+; CHECK-LABEL: @srem_negC_fail0(
+; CHECK-NEXT: [[VAL:%.*]] = srem i8 -34, [[X:%.*]]
+; CHECK-NEXT: [[R:%.*]] = icmp sle i8 [[VAL]], -1
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %val = srem i8 -34, %x
+ %r = icmp sle i8 %val, -1
+ ret i1 %r
+}
+
+define i1 @srem_negC_fail1(i8 %x) {
+; CHECK-LABEL: @srem_negC_fail1(
+; CHECK-NEXT: [[VAL:%.*]] = srem i8 -34, [[X:%.*]]
+; CHECK-NEXT: [[R:%.*]] = icmp sge i8 [[VAL]], -33
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %val = srem i8 -34, %x
+ %r = icmp sge i8 %val, -33
+ ret i1 %r
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/82303
More information about the llvm-commits
mailing list