[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 06:24:10 PDT 2021


fhahn created this revision.
fhahn added reviewers: nikic, lebedev.ri.
Herald added subscribers: dexonsmith, hiraditya.
fhahn requested review of this revision.
Herald added a project: LLVM.

Currently UREM & SREM on constant ranges produces overly pessimistic
results for single element constant ranges.

Delegate to APInt's implementation if both operands are single element
constant ranges. We already do something similar for other binary
operators, like binary AND.o

Fixes PR49731.


Repository:
  rG LLVM Github Monorepo

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:    ret void
 ;
   %sel = select i1 false, i16 0, i16 12704
@@ -126,16 +120,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:    ret void
 ;
   %sel = select i1 false, i16 0, i16 12704
Index: llvm/lib/IR/ConstantRange.cpp
===================================================================
--- llvm/lib/IR/ConstantRange.cpp
+++ llvm/lib/IR/ConstantRange.cpp
@@ -1221,6 +1221,10 @@
   if (isEmptySet() || RHS.isEmptySet() || RHS.getUnsignedMax().isNullValue())
     return getEmpty();
 
+  // Use APInt's implementation of UREM for single element ranges.
+  if (isSingleElement() && RHS.isSingleElement())
+    return {getSingleElement()->urem(*RHS.getSingleElement())};
+
   // L % R for L < R is L.
   if (getUnsignedMax().ult(RHS.getUnsignedMin()))
     return *this;
@@ -1234,6 +1238,10 @@
   if (isEmptySet() || RHS.isEmptySet())
     return getEmpty();
 
+  // Use APInt's implementation of SREM for single element ranges.
+  if (isSingleElement() && RHS.isSingleElement())
+    return {getSingleElement()->srem(*RHS.getSingleElement())};
+
   ConstantRange AbsRHS = RHS.abs();
   APInt MinAbsRHS = AbsRHS.getUnsignedMin();
   APInt MaxAbsRHS = AbsRHS.getUnsignedMax();


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


More information about the llvm-commits mailing list