llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clangir Author: Amr Hesham (AmrDeveloper) <details> <summary>Changes</summary> Implement support for the _builtin_fma --- Full diff: https://github.com/llvm/llvm-project/pull/210365.diff 4 Files Affected: - (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+37) - (modified) clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp (+17-1) - (modified) clang/test/CIR/CodeGen/builtins-x86.c (+25) - (modified) clang/test/CIR/CodeGenBuiltins/builtins-elementwise.c (+9) ``````````diff diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 0a60514ee21fc..814d88ac014fb 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -7262,6 +7262,43 @@ def CIR_ModfOp : CIR_Op<"modf", [Pure]> { }]; } +class CIR_TernaryFPToFPBuiltinOp<string mnemonic, string llvmOpName> + : CIR_Op<mnemonic, [Pure, SameOperandsAndResultType]> +{ + let arguments = (ins + CIR_AnyFloatOrVecOfFloatType:$a, + CIR_AnyFloatOrVecOfFloatType:$b, + CIR_AnyFloatOrVecOfFloatType:$c + ); + + let results = (outs CIR_AnyFloatOrVecOfFloatType:$result); + + let assemblyFormat = "$a `,` $b `,` $c `:` type($a) attr-dict"; + + let llvmOp = llvmOpName; +} + +def CIR_FMAOp : CIR_TernaryFPToFPBuiltinOp<"fma", "FMAOp"> { + let summary = "Fused Multiply-Add operation"; + + let description = [{ + Computes the fused multiply-add of three floating-point values or vector. + + The inputs must be either: + • floating-point scalar types, or + • vectors whose element type is floating-point. + + The result type must match the input type exactly. + + Examples: + // scalar + %r = cir.fma %a, %b, %c : !cir.float + + // vector + %v = cir.fma %a, %b, %c : !cir.vector<4 x !cir.float> + }]; +} + //===----------------------------------------------------------------------===// // Variadic Operations //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 9b2ea8bf0e4bb..5fdc76bfbb362 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -394,6 +394,22 @@ static RValue emitBinaryFPBuiltin(CIRGenFunction &cgf, const CallExpr &e) { return RValue::get(call->getResult(0)); } +template <typename Op> +static RValue emitTernaryMaybeConstrainedFPBuiltin(CIRGenFunction &cgf, + const CallExpr &e) { + mlir::Value arg0 = cgf.emitScalarExpr(e.getArg(0)); + mlir::Value arg1 = cgf.emitScalarExpr(e.getArg(1)); + mlir::Value arg2 = cgf.emitScalarExpr(e.getArg(2)); + + mlir::Location loc = cgf.getLoc(e.getExprLoc()); + mlir::Type ty = cgf.convertType(e.getType()); + + assert(!cir::MissingFeatures::fpConstraints()); + + auto call = Op::create(cgf.getBuilder(), loc, ty, arg0, arg1, arg2); + return RValue::get(call->getResult(0)); +} + template <typename Op> static mlir::Value emitBinaryMaybeConstrainedFPBuiltin(CIRGenFunction &cgf, const CallExpr &e) { @@ -648,7 +664,7 @@ static RValue tryEmitFPMathIntrinsic(CIRGenFunction &cgf, const CallExpr *e, case Builtin::BI__builtin_fmal: case Builtin::BI__builtin_fmaf128: case Builtin::BI__builtin_elementwise_fma: - return errorBuiltinNYI(cgf, e, builtinID); + return emitTernaryMaybeConstrainedFPBuiltin<cir::FMAOp>(cgf, *e); case Builtin::BIfmax: case Builtin::BIfmaxf: case Builtin::BIfmaxl: diff --git a/clang/test/CIR/CodeGen/builtins-x86.c b/clang/test/CIR/CodeGen/builtins-x86.c index fa0cfd2fd5322..4f72a3000fc44 100644 --- a/clang/test/CIR/CodeGen/builtins-x86.c +++ b/clang/test/CIR/CodeGen/builtins-x86.c @@ -289,3 +289,28 @@ void test_movntss(float *dest, v4f src) { // OGCG: store float %{{.*}}, ptr %{{.*}}, align 1, !nontemporal return __builtin_ia32_movntss(dest, src); } + +float test_fma_f32(float a, float b, float c) { + // CIR-LABEL: test_fma_f32 + // CIR: %[[R:.*]] = cir.fma %[[A:.*]], %[[B:.*]], %[[C:.*]] : !cir.float + + // LLVM-LABEL: @test_fma_f32 + // LLVM: %[[R:.*]] = call float @llvm.fma.f32(float %[[A:.*]], float %[[B:.*]], float %[[C:.*]]) + + // OGCG-LABEL: @test_fma_f32 + // OGCG: %[[R:.*]] = call float @llvm.fma.f32(float %[[A:.*]], float %[[B:.*]], float %[[C:.*]]) + return __builtin_fmaf(a, b, c); +} + +double test_fma_f64(double a, double b, double c) { + // CIR-LABEL: test_fma_f64 + // CIR: %[[R:.*]] = cir.fma %[[A:.*]], %[[B:.*]], %[[C:.*]] : !cir.double + + // LLVM-LABEL: @test_fma_f64 + // LLVM: %[[R:.*]] = call double @llvm.fma.f64(double %[[A:.*]], double %[[B:.*]], double %[[C:.*]]) + + // OGCG-LABEL: @test_fma_f64 + // OGCG: %[[R:.*]] = call double @llvm.fma.f64(double %[[A:.*]], double %[[B:.*]], double %[[C:.*]]) + return __builtin_fma(a, b, c); +} + diff --git a/clang/test/CIR/CodeGenBuiltins/builtins-elementwise.c b/clang/test/CIR/CodeGenBuiltins/builtins-elementwise.c index 442ecdaa7faf1..b5600901be247 100644 --- a/clang/test/CIR/CodeGenBuiltins/builtins-elementwise.c +++ b/clang/test/CIR/CodeGenBuiltins/builtins-elementwise.c @@ -640,3 +640,12 @@ void test_builtin_elementwise_sub_sat(int i1, int i2, unsigned u1, unsigned u2, // LLVM: call <8 x i16> @llvm.ssub.sat.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) vs1 = __builtin_elementwise_sub_sat(vs1, vs2); } + +vfloat4 test_builtin_elementwise_fma(vfloat4 a, vfloat4 b, vfloat4 c) { + // CIR-LABEL: test_builtin_elementwise_fma + // LLVM-LABEL: test_builtin_elementwise_fma + + // CIR: cir.fma %{{.*}}, %{{.*}}, %{{.*}} : !cir.vector<4 x !cir.float> + // LLVM: call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}) + return __builtin_elementwise_fma(a, b, c); +} `````````` </details> https://github.com/llvm/llvm-project/pull/210365 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
