[llvm] a524248 - [SCEV] Recognize vscale intrinsics

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 17 02:09:40 PDT 2023


Author: Nikita Popov
Date: 2023-03-17T10:07:39+01:00
New Revision: a5242483e40cd30f59ad419154ca6ce9e0adadca

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

LOG: [SCEV] Recognize vscale intrinsics

Now that SCEV has a dedicated vscale node type, we should also map
vscale intrinsics to it. To make sure this does not regress ranges
(which were KnownBits based previously), add support for vscale to
getRangeRef() as well.

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

Added: 
    

Modified: 
    llvm/include/llvm/Analysis/ValueTracking.h
    llvm/lib/Analysis/ScalarEvolution.cpp
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/test/Analysis/ScalarEvolution/scalable-vector.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index 26fb1051978bd..0a8af8c449996 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -654,6 +654,10 @@ OverflowResult computeOverflowForSignedSub(const Value *LHS, const Value *RHS,
 bool isOverflowIntrinsicNoWrap(const WithOverflowInst *WO,
                                const DominatorTree &DT);
 
+/// Determine the possible constant range of vscale with the given bit width,
+/// based on the vscale_range function attribute.
+ConstantRange getVScaleRange(const Function *F, unsigned BitWidth);
+
 /// Determine the possible constant range of an integer or vector of integer
 /// value. This is intended as a cheap, non-recursive check.
 ConstantRange computeConstantRange(const Value *V, bool ForSigned,

diff  --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 09c64324a89cd..e3c4fc57c202c 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -6600,7 +6600,7 @@ const ConstantRange &ScalarEvolution::getRangeRef(
   case scConstant:
     llvm_unreachable("Already handled above.");
   case scVScale:
-    return setRange(S, SignHint, std::move(ConservativeResult));
+    return setRange(S, SignHint, getVScaleRange(&F, BitWidth));
   case scTruncate: {
     const SCEVTruncateExpr *Trunc = cast<SCEVTruncateExpr>(S);
     ConstantRange X = getRangeRef(Trunc->getOperand(), SignHint, Depth + 1);
@@ -8007,6 +8007,8 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
         // A start_loop_iterations or llvm.annotation or llvm.prt.annotation is
         // just eqivalent to the first operand for SCEV purposes.
         return getSCEV(II->getArgOperand(0));
+      case Intrinsic::vscale:
+        return getVScale(II->getType());
       default:
         break;
       }

diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 6cc2fb2ebcc24..1ce06e5b57d81 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -1152,7 +1152,7 @@ KnownBits llvm::analyzeKnownBitsFromAndXorOr(
       Query(DL, AC, safeCxtI(I, CxtI), DT, UseInstrInfo, ORE));
 }
 
-static ConstantRange getVScaleRange(const Function *F, unsigned BitWidth) {
+ConstantRange llvm::getVScaleRange(const Function *F, unsigned BitWidth) {
   Attribute Attr = F->getFnAttribute(Attribute::VScaleRange);
   // Without vscale_range, we only know that vscale is non-zero.
   if (!Attr.isValid())

diff  --git a/llvm/test/Analysis/ScalarEvolution/scalable-vector.ll b/llvm/test/Analysis/ScalarEvolution/scalable-vector.ll
index 3bc709ef026d4..13648ebdaf868 100644
--- a/llvm/test/Analysis/ScalarEvolution/scalable-vector.ll
+++ b/llvm/test/Analysis/ScalarEvolution/scalable-vector.ll
@@ -19,9 +19,9 @@ define void @vscale_gep_range(ptr %p) vscale_range(2, 16) {
 ; CHECK-LABEL: 'vscale_gep_range'
 ; CHECK-NEXT:  Classifying expressions for: @vscale_gep_range
 ; CHECK-NEXT:    %1 = getelementptr <vscale x 4 x i32>, ptr null, i32 3
-; CHECK-NEXT:    --> ((48 * vscale) + null) U: [0,-15) S: [-9223372036854775808,9223372036854775793)
+; CHECK-NEXT:    --> ((48 * vscale)<nuw><nsw> + null) U: [96,769) S: [96,769)
 ; CHECK-NEXT:    %2 = getelementptr <vscale x 1 x i64>, ptr %p, i32 1
-; CHECK-NEXT:    --> ((8 * vscale) + %p) U: full-set S: full-set
+; CHECK-NEXT:    --> ((8 * vscale)<nuw><nsw> + %p) U: full-set S: full-set
 ; CHECK-NEXT:  Determining loop execution counts for: @vscale_gep_range
 ;
   getelementptr <vscale x 4 x i32>, ptr null, i32 3
@@ -33,7 +33,7 @@ define i64 @vscale_no_range() {
 ; CHECK-LABEL: 'vscale_no_range'
 ; CHECK-NEXT:  Classifying expressions for: @vscale_no_range
 ; CHECK-NEXT:    %vscale = call i64 @llvm.vscale.i64()
-; CHECK-NEXT:    --> %vscale U: [1,0) S: [1,0)
+; CHECK-NEXT:    --> vscale U: [1,0) S: [1,0)
 ; CHECK-NEXT:  Determining loop execution counts for: @vscale_no_range
 ;
   %vscale = call i64 @llvm.vscale.i64()
@@ -44,7 +44,7 @@ define i64 @vscale_min_max_range() vscale_range(2, 16) {
 ; CHECK-LABEL: 'vscale_min_max_range'
 ; CHECK-NEXT:  Classifying expressions for: @vscale_min_max_range
 ; CHECK-NEXT:    %vscale = call i64 @llvm.vscale.i64()
-; CHECK-NEXT:    --> %vscale U: [1,32) S: [1,32)
+; CHECK-NEXT:    --> vscale U: [2,17) S: [2,17)
 ; CHECK-NEXT:  Determining loop execution counts for: @vscale_min_max_range
 ;
   %vscale = call i64 @llvm.vscale.i64()
@@ -55,7 +55,7 @@ define i64 @vscale_min_range() vscale_range(2, 0) {
 ; CHECK-LABEL: 'vscale_min_range'
 ; CHECK-NEXT:  Classifying expressions for: @vscale_min_range
 ; CHECK-NEXT:    %vscale = call i64 @llvm.vscale.i64()
-; CHECK-NEXT:    --> %vscale U: [1,0) S: [1,0)
+; CHECK-NEXT:    --> vscale U: [2,0) S: [2,0)
 ; CHECK-NEXT:  Determining loop execution counts for: @vscale_min_range
 ;
   %vscale = call i64 @llvm.vscale.i64()
@@ -66,7 +66,7 @@ define i64 @vscale_exact_range() vscale_range(2) {
 ; CHECK-LABEL: 'vscale_exact_range'
 ; CHECK-NEXT:  Classifying expressions for: @vscale_exact_range
 ; CHECK-NEXT:    %vscale = call i64 @llvm.vscale.i64()
-; CHECK-NEXT:    --> %vscale U: [2,3) S: [2,3)
+; CHECK-NEXT:    --> vscale U: [2,3) S: [2,3)
 ; CHECK-NEXT:  Determining loop execution counts for: @vscale_exact_range
 ;
   %vscale = call i64 @llvm.vscale.i64()


        


More information about the llvm-commits mailing list