[PATCH] D105115: [ConstantRanges] Use APInt for constant case for urem/srem.

Florian Hahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 29 08:19:04 PDT 2021


fhahn updated this revision to Diff 355255.
fhahn added a comment.

In D105115#2846981 <https://reviews.llvm.org/D105115#2846981>, @nikic wrote:

> What does this do if the single element on the RHS is zero?

Oh, APInt::urem/srem assert that RHS is not zero. I updated the code to directly handle the case by return an empty range. I think we could further simplify the compares against UREM/SREM by 0, but currently that is not happening as we force empty ranges to overdefined when resolving undefs.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D105115/new/

https://reviews.llvm.org/D105115

Files:
  llvm/lib/IR/ConstantRange.cpp
  llvm/test/Transforms/SCCP/binaryops-range-special-cases.ll


Index: llvm/test/Transforms/SCCP/binaryops-range-special-cases.ll
===================================================================
--- llvm/test/Transforms/SCCP/binaryops-range-special-cases.ll
+++ llvm/test/Transforms/SCCP/binaryops-range-special-cases.ll
@@ -98,16 +98,10 @@
 
 define void @urem_cmp_constants() {
 ; CHECK-LABEL: @urem_cmp_constants(
-; CHECK-NEXT:    [[UREM_1:%.*]] = urem i16 12704, 12704
-; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i16 [[UREM_1]], 0
-; CHECK-NEXT:    call void @use(i1 [[C_1]])
-; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i16 [[UREM_1]], 1
-; CHECK-NEXT:    call void @use(i1 [[C_2]])
-; CHECK-NEXT:    [[UREM_2:%.*]] = urem i16 12704, 3
-; CHECK-NEXT:    [[C_3:%.*]] = icmp eq i16 [[UREM_2]], 2
-; CHECK-NEXT:    call void @use(i1 [[C_3]])
-; CHECK-NEXT:    [[C_4:%.*]] = icmp eq i16 [[UREM_2]], 1
-; CHECK-NEXT:    call void @use(i1 [[C_4]])
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    call void @use(i1 false)
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    call void @use(i1 false)
 ; CHECK-NEXT:    [[UREM_3:%.*]] = urem i16 12704, 0
 ; CHECK-NEXT:    [[C_5:%.*]] = icmp eq i16 [[UREM_3]], 1
 ; CHECK-NEXT:    call void @use(i1 [[C_5]])
@@ -132,16 +126,10 @@
 
 define void @srem_cmp_constants() {
 ; CHECK-LABEL: @srem_cmp_constants(
-; CHECK-NEXT:    [[SREM_1:%.*]] = srem i16 12704, 12704
-; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i16 [[SREM_1]], 0
-; CHECK-NEXT:    call void @use(i1 [[C_1]])
-; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i16 [[SREM_1]], 1
-; CHECK-NEXT:    call void @use(i1 [[C_2]])
-; CHECK-NEXT:    [[SREM_2:%.*]] = srem i16 12704, 3
-; CHECK-NEXT:    [[C_3:%.*]] = icmp eq i16 [[SREM_2]], 2
-; CHECK-NEXT:    call void @use(i1 [[C_3]])
-; CHECK-NEXT:    [[C_4:%.*]] = icmp eq i16 [[SREM_2]], 1
-; CHECK-NEXT:    call void @use(i1 [[C_4]])
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    call void @use(i1 false)
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    call void @use(i1 false)
 ; CHECK-NEXT:    [[SREM_3:%.*]] = srem i16 12704, 0
 ; CHECK-NEXT:    [[C_5:%.*]] = icmp eq i16 [[SREM_3]], 1
 ; CHECK-NEXT:    call void @use(i1 [[C_5]])
Index: llvm/lib/IR/ConstantRange.cpp
===================================================================
--- llvm/lib/IR/ConstantRange.cpp
+++ llvm/lib/IR/ConstantRange.cpp
@@ -1221,6 +1221,16 @@
   if (isEmptySet() || RHS.isEmptySet() || RHS.getUnsignedMax().isNullValue())
     return getEmpty();
 
+  if (RHS.isSingleElement()) {
+    const APInt &RHSInt = *RHS.getSingleElement();
+    // UREM by null is UB.
+    if (RHSInt.isNullValue())
+      return getEmpty();
+    // Use APInt's implementation of UREM for single element ranges.
+    if (isSingleElement())
+      return {getSingleElement()->urem(RHSInt)};
+  }
+
   // L % R for L < R is L.
   if (getUnsignedMax().ult(RHS.getUnsignedMin()))
     return *this;
@@ -1234,6 +1244,16 @@
   if (isEmptySet() || RHS.isEmptySet())
     return getEmpty();
 
+  if (RHS.isSingleElement()) {
+    const APInt &RHSInt = *RHS.getSingleElement();
+    // SREM by null is UB.
+    if (RHSInt.isNullValue())
+      return getEmpty();
+    // Use APInt's implementation of SREM for single element ranges.
+    if (isSingleElement())
+      return {getSingleElement()->srem(RHSInt)};
+  }
+
   ConstantRange AbsRHS = RHS.abs();
   APInt MinAbsRHS = AbsRHS.getUnsignedMin();
   APInt MaxAbsRHS = AbsRHS.getUnsignedMax();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D105115.355255.patch
Type: text/x-patch
Size: 3416 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210629/b68c2130/attachment.bin>


More information about the llvm-commits mailing list