[clang] [Clang][bytecode] Add interp__builtin_elementwise_triop_fp to handle general 3-operand floating point intrinsics (PR #157106)

Simon Pilgrim via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 5 06:33:20 PDT 2025


https://github.com/RKSimon created https://github.com/llvm/llvm-project/pull/157106

Refactor interp__builtin_elementwise_fma into something similar to interp__builtin_elementwise_triop with a callback function argument to allow reuse with other intrinsics

This will allow reuse with some upcoming x86 intrinsics

>From 4d6078f92740efa3f109b85492f43b8fadd39b03 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Fri, 5 Sep 2025 14:32:07 +0100
Subject: [PATCH] [Clang][bytecode] Add interp__builtin_elementwise_triop_fp to
 handle general 3-operand floating point intrinsics

Refactor interp__builtin_elementwise_fma into something similar to interp__builtin_elementwise_triop with a callback function argument to allow reuse with other intrinsics

This will allow reuse with some upcoming x86 intrinsics
---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 713895b191c88..c0937ecb683bf 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -2736,12 +2736,14 @@ 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) {
+static bool interp__builtin_elementwise_triop_fp(
+    InterpState &S, CodePtr OpPC, const CallExpr *Call,
+    llvm::function_ref<APFloat(const APFloat &, const APFloat &,
+                               const APFloat &, const FPOptions &)>
+        Fn) {
   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();
@@ -2756,8 +2758,7 @@ static bool interp__builtin_elementwise_fma(InterpState &S, CodePtr OpPC,
     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);
+    APFloat F = Fn(X.getAPFloat(), Y.getAPFloat(), Z.getAPFloat(), FPO);
     Floating Result = S.allocFloat(X.getSemantics());
     Result.copy(F);
     S.Stk.push<Floating>(Result);
@@ -2788,8 +2789,8 @@ static bool interp__builtin_elementwise_fma(InterpState &S, CodePtr OpPC,
     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);
+    APFloat F = Fn(X, Y, Z, FPO);
+    Dst.elem<Floating>(I) = Floating(F);
   }
   Dst.initializeAllElements();
   return true;
@@ -3410,7 +3411,14 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
     return interp__builtin_ia32_pmul(S, OpPC, Call, BuiltinID);
 
   case Builtin::BI__builtin_elementwise_fma:
-    return interp__builtin_elementwise_fma(S, OpPC, Call);
+    return interp__builtin_elementwise_triop_fp(
+        S, OpPC, Call,
+        [](const APFloat &X, const APFloat &Y, const APFloat &Z,
+           const FPOptions &FPO) {
+          APFloat F = X;
+          F.fusedMultiplyAdd(Y, Z, getRoundingMode(FPO));
+          return F;
+        });
 
   case X86::BI__builtin_ia32_selectb_128:
   case X86::BI__builtin_ia32_selectb_256:



More information about the cfe-commits mailing list