diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -252,6 +252,16 @@ Res = CastInst::Create( static_cast(Opc), I->getOperand(0), Ty); break; + case Instruction::Call: { + const IntrinsicInst *II = dyn_cast(I); + if (II && II->getIntrinsicID() == Intrinsic::vscale) { + Function *Fn = + Intrinsic::getDeclaration(I->getModule(), Intrinsic::vscale, {Ty}); + Res = CallInst::Create(Fn->getFunctionType(), Fn); + break; + } + LLVM_FALLTHROUGH; + } default: // TODO: Can handle more cases here. llvm_unreachable("Unreachable!"); @@ -1217,6 +1227,13 @@ return false; return true; } + case Instruction::Call: + // llvm.vscale() can always be executed in larger type, because the + // value is automatically zero-extended. + if (const IntrinsicInst *II = dyn_cast(I)) + if (II->getIntrinsicID() == Intrinsic::vscale) + return true; + return false; default: // TODO: Can handle more cases here. return false; diff --git a/llvm/test/Transforms/InstCombine/vscale.ll b/llvm/test/Transforms/InstCombine/vscale.ll --- a/llvm/test/Transforms/InstCombine/vscale.ll +++ b/llvm/test/Transforms/InstCombine/vscale.ll @@ -4,8 +4,8 @@ define i64 @free_zext_vscale_i32_to_i64() #0 { ; CHECK-LABEL: @free_zext_vscale_i32_to_i64( -; CHECK-NEXT: [[EXT:%.*]] = call i64 @llvm.vscale.i64() -; CHECK-NEXT: ret i64 [[EXT]] +; CHECK-NEXT: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() +; CHECK-NEXT: ret i64 [[VSCALE]] ; %vscale = call i32 @llvm.vscale.i32() %ext = zext i32 %vscale to i64 @@ -14,10 +14,9 @@ define i64 @free_zext_vscale_shl_i32_to_i64() #0 { ; CHECK-LABEL: @free_zext_vscale_shl_i32_to_i64( -; CHECK-NEXT: [[VSCALE:%.*]] = call i32 @llvm.vscale.i32() -; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i32 [[VSCALE]], 3 -; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[SHL]] to i64 -; CHECK-NEXT: ret i64 [[EXT]] +; CHECK-NEXT: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() +; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i64 [[VSCALE]], 3 +; CHECK-NEXT: ret i64 [[SHL]] ; %vscale = call i32 @llvm.vscale.i32() %shl = shl i32 %vscale, 3