[InstSimplify] Simplify llvm.vscale when vscale_range attribute exists

Reduce llvm.vscale to constant based on vscale_range attribute.

Differential Revision: https://reviews.llvm.org/D106850
This commit is contained in:
Jun Ma 2021-07-27 11:29:46 +08:00
parent 3ad6437fcc
commit ca0fe3447f
2 changed files with 62 additions and 4 deletions

View File

@ -5772,13 +5772,31 @@ static Value *simplifyBinaryIntrinsic(Function *F, Value *Op0, Value *Op1,
static Value *simplifyIntrinsic(CallBase *Call, const SimplifyQuery &Q) {
// Intrinsics with no operands have some kind of side effect. Don't simplify.
unsigned NumOperands = Call->getNumArgOperands();
if (!NumOperands)
return nullptr;
Function *F = cast<Function>(Call->getCalledFunction());
Intrinsic::ID IID = F->getIntrinsicID();
// Most of the intrinsics with no operands have some kind of side effect.
// Don't simplify.
if (!NumOperands) {
switch (IID) {
case Intrinsic::vscale: {
auto Attr = Call->getFunction()->getFnAttribute(Attribute::VScaleRange);
if (!Attr.isValid())
return nullptr;
unsigned MinScalarVectorSize, MaxScalarVectorSize;
std::tie(MinScalarVectorSize, MaxScalarVectorSize) =
Attr.getVScaleRangeArgs();
if (MinScalarVectorSize == MaxScalarVectorSize &&
MaxScalarVectorSize != 0)
return ConstantInt::get(F->getReturnType(), MinScalarVectorSize);
return nullptr;
}
default:
return nullptr;
}
}
if (NumOperands == 1)
return simplifyUnaryIntrinsic(F, Call->getArgOperand(0), Q);

View File

@ -0,0 +1,40 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instsimplify -S | FileCheck %s
define i64 @vscale_i64() #1 {
; CHECK-LABEL: @vscale_i64(
; CHECK-NEXT: ret i64 1
;
%out = call i64 @llvm.vscale.i64()
ret i64 %out
}
define i32 @vscale_i32() #2 {
; CHECK-LABEL: @vscale_i32(
; CHECK-NEXT: ret i32 2
;
%out = call i32 @llvm.vscale.i32()
ret i32 %out
}
define i64 @vscale_i64_diff() #3 {
; CHECK-LABEL: @vscale_i64_diff(
; CHECK-NEXT: [[OUT:%.*]] = call i64 @llvm.vscale.i64()
; CHECK-NEXT: ret i64 [[OUT]]
;
%out = call i64 @llvm.vscale.i64()
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) }