diff options
author | Benjamin Maxwell <benjamin.maxwell@arm.com> | 2024-12-08 21:16:50 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-12-08 21:16:50 +0000 |
commit | 47df46b1e7a397af428bc455b8e173fbdf4869af (patch) | |
tree | f5bb041338ea8ea6d9ba291d5de84bf355ff3e84 /llvm/lib/Analysis/ConstantFolding.cpp | |
parent | bd07e87082aec965820b1facc495a1363cbc243f (diff) | |
download | llvm-47df46b1e7a397af428bc455b8e173fbdf4869af.zip llvm-47df46b1e7a397af428bc455b8e173fbdf4869af.tar.gz llvm-47df46b1e7a397af428bc455b8e173fbdf4869af.tar.bz2 |
[InstSimplify] Add basic constant folding for `llvm.sincos` (#114527)
This calls into the existing constant folding for `llvm.sin` and
`llvm.cos`, which currently does not fold for any non-finite values, so
most tests are negative tests at the moment.
Note: The constant folding does not consider the `afn` fast-math flag
and will produce the same result regardless of if the flag is set.
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) |