diff options
Diffstat (limited to 'llvm/lib/Analysis/ConstantFolding.cpp')
-rw-r--r-- | llvm/lib/Analysis/ConstantFolding.cpp | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index efbccee..0233d31 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -1632,6 +1632,7 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) { case Intrinsic::sqrt: case Intrinsic::sin: case Intrinsic::cos: + case Intrinsic::sincos: case Intrinsic::pow: case Intrinsic::powi: case Intrinsic::ldexp: @@ -3534,6 +3535,40 @@ ConstantFoldStructCall(StringRef Name, Intrinsic::ID IntrinsicID, return nullptr; return ConstantStruct::get(StTy, Result0, Result1); } + case Intrinsic::sincos: { + Type *Ty = StTy->getContainedType(0); + Type *TyScalar = Ty->getScalarType(); + + auto ConstantFoldScalarSincosCall = + [&](Constant *Op) -> std::pair<Constant *, Constant *> { + Constant *SinResult = + ConstantFoldScalarCall(Name, Intrinsic::sin, TyScalar, Op, TLI, Call); + Constant *CosResult = + ConstantFoldScalarCall(Name, Intrinsic::cos, TyScalar, Op, TLI, Call); + return std::make_pair(SinResult, CosResult); + }; + + if (auto *FVTy = dyn_cast<FixedVectorType>(Ty)) { + SmallVector<Constant *> SinResults(FVTy->getNumElements()); + SmallVector<Constant *> CosResults(FVTy->getNumElements()); + + for (unsigned I = 0, E = FVTy->getNumElements(); I != E; ++I) { + Constant *Lane = Operands[0]->getAggregateElement(I); + std::tie(SinResults[I], CosResults[I]) = + ConstantFoldScalarSincosCall(Lane); + if (!SinResults[I] || !CosResults[I]) + return nullptr; + } + + return ConstantStruct::get(StTy, ConstantVector::get(SinResults), + ConstantVector::get(CosResults)); + } + + auto [SinResult, CosResult] = ConstantFoldScalarSincosCall(Operands[0]); + if (!SinResult || !CosResult) + return nullptr; + return ConstantStruct::get(StTy, SinResult, CosResult); + } default: // TODO: Constant folding of vector intrinsics that fall through here does // not work (e.g. overflow intrinsics) |