[llvm] 9fb46a4 - [SCCP] Compute ranges for supported intrinsics

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 7 13:16:17 PDT 2020


Author: Nikita Popov
Date: 2020-09-07T22:16:06+02:00
New Revision: 9fb46a452d4e5666828c95610ceac8dcd9e4ce16

URL: https://github.com/llvm/llvm-project/commit/9fb46a452d4e5666828c95610ceac8dcd9e4ce16
DIFF: https://github.com/llvm/llvm-project/commit/9fb46a452d4e5666828c95610ceac8dcd9e4ce16.diff

LOG: [SCCP] Compute ranges for supported intrinsics

For intrinsics supported by ConstantRange, compute the result range
based on the argument ranges. We do this independently of whether
some or all of the input ranges are full, as we can often still
constrain the result in some way.

Differential Revision: https://reviews.llvm.org/D87183

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/SCCP.cpp
    llvm/test/Transforms/SCCP/intrinsics.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp
index 2afc778ed821..33ab2907906e 100644
--- a/llvm/lib/Transforms/Scalar/SCCP.cpp
+++ b/llvm/lib/Transforms/Scalar/SCCP.cpp
@@ -1350,6 +1350,25 @@ void SCCPSolver::handleCallResult(CallBase &CB) {
 
       return (void)mergeInValue(IV, &CB, CopyOfVal);
     }
+
+    if (ConstantRange::isIntrinsicSupported(II->getIntrinsicID())) {
+      // Compute result range for intrinsics supported by ConstantRange.
+      // Do this even if we don't know a range for all operands, as we may
+      // still know something about the result range, e.g. of abs(x).
+      SmallVector<ConstantRange, 2> OpRanges;
+      for (Value *Op : II->args()) {
+        const ValueLatticeElement &State = getValueState(Op);
+        if (State.isConstantRange())
+          OpRanges.push_back(State.getConstantRange());
+        else
+          OpRanges.push_back(
+              ConstantRange::getFull(Op->getType()->getScalarSizeInBits()));
+      }
+
+      ConstantRange Result =
+          ConstantRange::intrinsic(II->getIntrinsicID(), OpRanges);
+      return (void)mergeInValue(II, ValueLatticeElement::getRange(Result));
+    }
   }
 
   // The common case is that we aren't tracking the callee, either because we

diff  --git a/llvm/test/Transforms/SCCP/intrinsics.ll b/llvm/test/Transforms/SCCP/intrinsics.ll
index d06b94162b5b..e261a59d3d6b 100644
--- a/llvm/test/Transforms/SCCP/intrinsics.ll
+++ b/llvm/test/Transforms/SCCP/intrinsics.ll
@@ -12,10 +12,8 @@ define void @abs1(i8* %p) {
 ; CHECK-LABEL: @abs1(
 ; CHECK-NEXT:    [[X:%.*]] = load i8, i8* [[P:%.*]], align 1, [[RNG0:!range !.*]]
 ; CHECK-NEXT:    [[ABS:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false)
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i8 [[ABS]], 0
-; CHECK-NEXT:    call void @use(i1 [[CMP1]])
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i8 [[ABS]], 10
-; CHECK-NEXT:    call void @use(i1 [[CMP2]])
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    call void @use(i1 true)
 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp sge i8 [[ABS]], 1
 ; CHECK-NEXT:    call void @use(i1 [[CMP3]])
 ; CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i8 [[ABS]], 9
@@ -40,8 +38,7 @@ define void @abs1(i8* %p) {
 define void @abs2(i8 %x) {
 ; CHECK-LABEL: @abs2(
 ; CHECK-NEXT:    [[ABS:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 true)
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i8 [[ABS]], 0
-; CHECK-NEXT:    call void @use(i1 [[CMP]])
+; CHECK-NEXT:    call void @use(i1 true)
 ; CHECK-NEXT:    ret void
 ;
   %abs = call i8 @llvm.abs.i8(i8 %x, i1 true)
@@ -68,10 +65,8 @@ define void @umax1(i8* %p1, i8* %p2) {
 ; CHECK-NEXT:    [[X1:%.*]] = load i8, i8* [[P1:%.*]], align 1, [[RNG1:!range !.*]]
 ; CHECK-NEXT:    [[X2:%.*]] = load i8, i8* [[P2:%.*]], align 1, [[RNG2:!range !.*]]
 ; CHECK-NEXT:    [[M:%.*]] = call i8 @llvm.umax.i8(i8 [[X1]], i8 [[X2]])
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp uge i8 [[M]], 5
-; CHECK-NEXT:    call void @use(i1 [[CMP1]])
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i8 [[M]], 15
-; CHECK-NEXT:    call void @use(i1 [[CMP2]])
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    call void @use(i1 true)
 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp uge i8 [[M]], 6
 ; CHECK-NEXT:    call void @use(i1 [[CMP3]])
 ; CHECK-NEXT:    [[CMP4:%.*]] = icmp ult i8 [[M]], 14
@@ -95,8 +90,7 @@ define void @umax1(i8* %p1, i8* %p2) {
 define void @umax2(i8 %x) {
 ; CHECK-LABEL: @umax2(
 ; CHECK-NEXT:    [[M:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 10)
-; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8 [[M]], 10
-; CHECK-NEXT:    call void @use(i1 [[CMP]])
+; CHECK-NEXT:    call void @use(i1 true)
 ; CHECK-NEXT:    ret void
 ;
   %m = call i8 @llvm.umax.i8(i8 %x, i8 10)


        


More information about the llvm-commits mailing list