[llvm] goldsteinn/constant range rem (PR #82303)

via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 19 19:58:25 PST 2024


https://github.com/goldsteinn created https://github.com/llvm/llvm-project/pull/82303

- **[ValueTracking] Add tests for constant range of `{s|u}rem C**
- **[ValueTracking] Improve tracking for constant range of `{s|u}rem C**


>From c6b900711fc1f631c6649f785f0f5c93cc4ec338 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Mon, 19 Feb 2024 21:51:38 -0600
Subject: [PATCH 1/2] [ValueTracking] Add tests for constant range of `{s|u}rem
 C, x`; NFC

---
 .../Analysis/ValueTracking/constant-ranges.ll | 110 ++++++++++++++++++
 1 file changed, 110 insertions(+)

diff --git a/llvm/test/Analysis/ValueTracking/constant-ranges.ll b/llvm/test/Analysis/ValueTracking/constant-ranges.ll
index 26e01efedd3dfc..addfe0fc4c54d6 100644
--- a/llvm/test/Analysis/ValueTracking/constant-ranges.ll
+++ b/llvm/test/Analysis/ValueTracking/constant-ranges.ll
@@ -130,3 +130,113 @@ 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:    [[VAL:%.*]] = urem i8 34, [[X:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = icmp ule i8 [[VAL]], 35
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %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:    [[VAL:%.*]] = srem i8 34, [[X:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = icmp sle i8 [[VAL]], 34
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %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:    [[VAL:%.*]] = srem i8 34, [[X:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = icmp sge i8 [[VAL]], -3
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %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:    [[VAL:%.*]] = srem i8 -34, [[X:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = icmp sle i8 [[VAL]], 0
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %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:    [[VAL:%.*]] = srem i8 -34, [[X:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = icmp sge i8 [[VAL]], -34
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %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
+}

>From ac430ea804607a02bea5e3625b643739eae485a6 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Mon, 19 Feb 2024 21:51:44 -0600
Subject: [PATCH 2/2] [ValueTracking] Improve tracking for constant range of
 `{s|u}rem C, x`

Current we only support `C` as the remainder, but we can also limit
with a constant numerator.

Proofs: https://alive2.llvm.org/ce/z/QB95gU
---
 llvm/lib/Analysis/ValueTracking.cpp           | 13 ++++++++++++
 .../Analysis/ValueTracking/constant-ranges.ll | 20 +++++--------------
 2 files changed, 18 insertions(+), 15 deletions(-)

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 addfe0fc4c54d6..c440cfad889d3b 100644
--- a/llvm/test/Analysis/ValueTracking/constant-ranges.ll
+++ b/llvm/test/Analysis/ValueTracking/constant-ranges.ll
@@ -133,9 +133,7 @@ define i1 @and_ugt_fail(i8 %xx) {
 
 define i1 @urem_okay(i8 %x) {
 ; CHECK-LABEL: @urem_okay(
-; CHECK-NEXT:    [[VAL:%.*]] = urem i8 34, [[X:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = icmp ule i8 [[VAL]], 35
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %val = urem i8 34, %x
   %r = icmp ule i8 %val, 35
@@ -155,9 +153,7 @@ define i1 @urem_fail(i8 %x) {
 
 define i1 @srem_posC_okay0(i8 %x) {
 ; CHECK-LABEL: @srem_posC_okay0(
-; CHECK-NEXT:    [[VAL:%.*]] = srem i8 34, [[X:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = icmp sle i8 [[VAL]], 34
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %val = srem i8 34, %x
   %r = icmp sle i8 %val, 34
@@ -166,9 +162,7 @@ define i1 @srem_posC_okay0(i8 %x) {
 
 define i1 @srem_posC_okay1(i8 %x) {
 ; CHECK-LABEL: @srem_posC_okay1(
-; CHECK-NEXT:    [[VAL:%.*]] = srem i8 34, [[X:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = icmp sge i8 [[VAL]], -3
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %val = srem i8 34, %x
   %r = icmp sge i8 %val, -3
@@ -177,9 +171,7 @@ define i1 @srem_posC_okay1(i8 %x) {
 
 define i1 @srem_negC_okay0(i8 %x) {
 ; CHECK-LABEL: @srem_negC_okay0(
-; CHECK-NEXT:    [[VAL:%.*]] = srem i8 -34, [[X:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = icmp sle i8 [[VAL]], 0
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %val = srem i8 -34, %x
   %r = icmp sle i8 %val, 0
@@ -188,9 +180,7 @@ define i1 @srem_negC_okay0(i8 %x) {
 
 define i1 @srem_negC_okay1(i8 %x) {
 ; CHECK-LABEL: @srem_negC_okay1(
-; CHECK-NEXT:    [[VAL:%.*]] = srem i8 -34, [[X:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = icmp sge i8 [[VAL]], -34
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %val = srem i8 -34, %x
   %r = icmp sge i8 %val, -34



More information about the llvm-commits mailing list