diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -41,6 +41,7 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicsAArch64.h" #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsWebAssembly.h" @@ -1486,6 +1487,7 @@ case Intrinsic::arm_mve_vctp16: case Intrinsic::arm_mve_vctp32: case Intrinsic::arm_mve_vctp64: + case Intrinsic::aarch64_sve_convert_from_svbool: // WebAssembly float semantics are always known case Intrinsic::wasm_trunc_signed: case Intrinsic::wasm_trunc_unsigned: @@ -2847,20 +2849,10 @@ return nullptr; } -static Constant *ConstantFoldVectorCall(StringRef Name, - Intrinsic::ID IntrinsicID, - VectorType *VTy, - ArrayRef Operands, - const DataLayout &DL, - const TargetLibraryInfo *TLI, - const CallBase *Call) { - // Do not iterate on scalable vector. The number of elements is unknown at - // compile-time. - if (isa(VTy)) - return nullptr; - - auto *FVTy = cast(VTy); - +static Constant *ConstantFoldFixedVectorCall( + StringRef Name, Intrinsic::ID IntrinsicID, FixedVectorType *FVTy, + ArrayRef Operands, const DataLayout &DL, + const TargetLibraryInfo *TLI, const CallBase *Call) { SmallVector Result(FVTy->getNumElements()); SmallVector Lane(Operands.size()); Type *Ty = FVTy->getElementType(); @@ -2977,6 +2969,24 @@ return ConstantVector::get(Result); } +static Constant *ConstantFoldScalableVectorCall( + StringRef Name, Intrinsic::ID IntrinsicID, ScalableVectorType *SVTy, + ArrayRef Operands, const DataLayout &DL, + const TargetLibraryInfo *TLI, const CallBase *Call) { + switch (IntrinsicID) { + case Intrinsic::aarch64_sve_convert_from_svbool: { + auto *Src = dyn_cast(Operands[0]); + if (!Src || !Src->isNullValue()) + break; + + return ConstantInt::getFalse(SVTy); + } + default: + break; + } + return nullptr; +} + } // end anonymous namespace Constant *llvm::ConstantFoldCall(const CallBase *Call, Function *F, @@ -2990,9 +3000,15 @@ Type *Ty = F->getReturnType(); - if (auto *VTy = dyn_cast(Ty)) - return ConstantFoldVectorCall(Name, F->getIntrinsicID(), VTy, Operands, - F->getParent()->getDataLayout(), TLI, Call); + if (auto *FVTy = dyn_cast(Ty)) + return ConstantFoldFixedVectorCall( + Name, F->getIntrinsicID(), FVTy, Operands, + F->getParent()->getDataLayout(), TLI, Call); + + if (auto *SVTy = dyn_cast(Ty)) + return ConstantFoldScalableVectorCall( + Name, F->getIntrinsicID(), SVTy, Operands, + F->getParent()->getDataLayout(), TLI, Call); return ConstantFoldScalarCall(Name, F->getIntrinsicID(), Ty, Operands, TLI, Call); diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/AArch64/aarch64-sve-convert-from-svbool.ll b/llvm/test/Transforms/InstSimplify/ConstProp/AArch64/aarch64-sve-convert-from-svbool.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstSimplify/ConstProp/AArch64/aarch64-sve-convert-from-svbool.ll @@ -0,0 +1,10 @@ +; RUN: opt -instsimplify -S -o - < %s | FileCheck %s + +define @reinterpret_zero() { +; CHECK-LABEL: @reinterpret_zero( +; CHECK: ret zeroinitializer + %pg = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( zeroinitializer) + ret %pg +} + +declare @llvm.aarch64.sve.convert.from.svbool.nxv2i1() diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/AArch64/lit.local.cfg b/llvm/test/Transforms/InstSimplify/ConstProp/AArch64/lit.local.cfg new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstSimplify/ConstProp/AArch64/lit.local.cfg @@ -0,0 +1,2 @@ +if not 'AArch64' in config.root.targets: + config.unsupported = True