diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -2056,6 +2056,17 @@ } break; } + case Intrinsic::vscale: { + auto Attr = II->getFunction()->getFnAttribute(Attribute::VScaleRange); + if (!Attr.isValid()) + break; + unsigned MinSVEVectorSize, MaxSVEVectorSize; + std::tie(MinSVEVectorSize, MaxSVEVectorSize) = Attr.getVScaleRangeArgs(); + if (MinSVEVectorSize == MaxSVEVectorSize && MaxSVEVectorSize != 0) + return replaceInstUsesWith( + CI, ConstantInt::get(II->getType(), MinSVEVectorSize)); + break; + } default: { // Handle target specific intrinsics Optional V = targetInstCombineIntrinsic(*II); diff --git a/llvm/test/Transforms/InstCombine/fold-vscale.ll b/llvm/test/Transforms/InstCombine/fold-vscale.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/fold-vscale.ll @@ -0,0 +1,44 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -instcombine -S | FileCheck %s + +define i64 @vscale_i64() #1 { +; CHECK-LABEL: @vscale_i64( +; CHECK-NEXT: ret i64 16 +; + %1 = call i64 @llvm.vscale.i64() + %out = shl i64 %1, 4 + ret i64 %out +} + +define i32 @vscale_i32() #2 { +; CHECK-LABEL: @vscale_i32( +; CHECK-NEXT: ret i32 8 +; + %1 = call i32 @llvm.vscale.i32() + %out = shl i32 %1, 2 + ret i32 %out +} + +define i64 @vscale_i64_diff() #3 { +; CHECK-LABEL: @vscale_i64_diff( +; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64() +; CHECK-NEXT: [[OUT:%.*]] = shl i64 [[TMP1]], 4 +; CHECK-NEXT: ret i64 [[OUT]] +; + %1 = call i64 @llvm.vscale.i64() + %out = shl i64 %1, 4 + ret i64 %out +} + +; Function Attrs: nofree nosync nounwind readnone willreturn +declare i64 @llvm.vscale.i64() #0 + +; Function Attrs: nofree nosync nounwind readnone willreturn +declare i32 @llvm.vscale.i32() #0 + +attributes #0 = { nofree nosync nounwind readnone willreturn } +attributes #1 = { mustprogress nofree nosync nounwind uwtable vscale_range(1,1) } +attributes #2 = { mustprogress nofree nosync nounwind uwtable vscale_range(2,2) } +attributes #3 = { mustprogress nofree nosync nounwind uwtable vscale_range(2,4) } + +