diff options
author | Chaitanya Koparkar <ckoparkar@gmail.com> | 2025-08-20 09:51:40 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-08-20 14:51:40 +0100 |
commit | f649605bcf5e9455a4a13e51bec8d7fa89bc6b4c (patch) | |
tree | 31a8c4242f83f5d75dbfd0dee4301af1916b204d /clang/lib/AST/ByteCode/InterpBuiltin.cpp | |
parent | 318b0dda7c914190487f3a7f6f948f720eecd59e (diff) | |
download | llvm-f649605bcf5e9455a4a13e51bec8d7fa89bc6b4c.zip llvm-f649605bcf5e9455a4a13e51bec8d7fa89bc6b4c.tar.gz llvm-f649605bcf5e9455a4a13e51bec8d7fa89bc6b4c.tar.bz2 |
[clang] Enable constexpr handling for __builtin_elementwise_fma (#152919)
Fixes https://github.com/llvm/llvm-project/issues/152455.
Diffstat (limited to 'clang/lib/AST/ByteCode/InterpBuiltin.cpp')
-rw-r--r-- | clang/lib/AST/ByteCode/InterpBuiltin.cpp | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index fd8c70c..5de5091 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -2714,6 +2714,62 @@ static bool interp__builtin_ia32_pmul(InterpState &S, CodePtr OpPC, return true; } +static bool interp__builtin_elementwise_fma(InterpState &S, CodePtr OpPC, + const CallExpr *Call) { + assert(Call->getNumArgs() == 3); + + FPOptions FPO = Call->getFPFeaturesInEffect(S.Ctx.getLangOpts()); + llvm::RoundingMode RM = getRoundingMode(FPO); + const QualType Arg1Type = Call->getArg(0)->getType(); + const QualType Arg2Type = Call->getArg(1)->getType(); + const QualType Arg3Type = Call->getArg(2)->getType(); + + // Non-vector floating point types. + if (!Arg1Type->isVectorType()) { + assert(!Arg2Type->isVectorType()); + assert(!Arg3Type->isVectorType()); + + const Floating &Z = S.Stk.pop<Floating>(); + const Floating &Y = S.Stk.pop<Floating>(); + const Floating &X = S.Stk.pop<Floating>(); + APFloat F = X.getAPFloat(); + F.fusedMultiplyAdd(Y.getAPFloat(), Z.getAPFloat(), RM); + Floating Result = S.allocFloat(X.getSemantics()); + Result.copy(F); + S.Stk.push<Floating>(Result); + return true; + } + + // Vector type. + assert(Arg1Type->isVectorType() && Arg2Type->isVectorType() && + Arg3Type->isVectorType()); + + const VectorType *VecT = Arg1Type->castAs<VectorType>(); + const QualType ElemT = VecT->getElementType(); + unsigned NumElems = VecT->getNumElements(); + + assert(ElemT == Arg2Type->castAs<VectorType>()->getElementType() && + ElemT == Arg3Type->castAs<VectorType>()->getElementType()); + assert(NumElems == Arg2Type->castAs<VectorType>()->getNumElements() && + NumElems == Arg3Type->castAs<VectorType>()->getNumElements()); + assert(ElemT->isRealFloatingType()); + + const Pointer &VZ = S.Stk.pop<Pointer>(); + const Pointer &VY = S.Stk.pop<Pointer>(); + const Pointer &VX = S.Stk.pop<Pointer>(); + const Pointer &Dst = S.Stk.peek<Pointer>(); + for (unsigned I = 0; I != NumElems; ++I) { + using T = PrimConv<PT_Float>::T; + APFloat X = VX.elem<T>(I).getAPFloat(); + APFloat Y = VY.elem<T>(I).getAPFloat(); + APFloat Z = VZ.elem<T>(I).getAPFloat(); + (void)X.fusedMultiplyAdd(Y, Z, RM); + Dst.elem<Floating>(I) = Floating(X); + } + Dst.initializeAllElements(); + return true; +} + bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, uint32_t BuiltinID) { if (!S.getASTContext().BuiltinInfo.isConstantEvaluated(BuiltinID)) @@ -3145,6 +3201,8 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, case clang::X86::BI__builtin_ia32_pmuludq128: case clang::X86::BI__builtin_ia32_pmuludq256: return interp__builtin_ia32_pmul(S, OpPC, Call, BuiltinID); + case Builtin::BI__builtin_elementwise_fma: + return interp__builtin_elementwise_fma(S, OpPC, Call); default: S.FFDiag(S.Current->getLocation(OpPC), |