================
@@ -1948,6 +1948,89 @@ static bool isIntegerVectorBinOp(mlir::Type ty) {
return vecTy && mlir::isa<cir::IntType>(vecTy.getElementType());
}
+// Construct a cir.fmuladd op to represent a fused mul-add of `mulOp` and
+// `addend`. Use negMul and negAdd to negate the first operand of the mul or
+// the addend respectively. This allows fmuladd to represent a*b-c, or c-a*b.
+// Patterns in LLVM should catch the negated forms and translate them to
+// efficient operations.
+static mlir::Value buildFMulAdd(cir::FMulOp mulOp, mlir::Value addend,
+ CIRGenBuilderTy &builder, bool negMul,
+ bool negAdd) {
+ const mlir::Location loc = mulOp.getLoc();
+ mlir::Value mulOp0 = mulOp.getLhs();
+ mlir::Value mulOp1 = mulOp.getRhs();
+ if (negMul)
+ mulOp0 = builder.createFNeg(loc, mulOp0);
+ if (negAdd)
+ addend = builder.createFNeg(loc, addend);
+
+ mlir::Value fmuladd =
+ cir::FMulAddOp::create(builder, loc, addend.getType(), mulOp0, mulOp1,
+ addend, builder.getConstrainedFPAttr());
+ mulOp.erase();
+ return fmuladd;
+}
+
+// Check whether it would be legal to emit a cir.fmuladd op to represent op
+// and if so, build it.
+//
+// Checks that (a) the operation is fusable, and (b) -ffp-contract=on.
+// Does NOT check the type of the operation - it's assumed that this function
+// will be called from contexts where it's known that the type is contractable.
+static mlir::Value tryEmitFMulAdd(const BinOpInfo &op, CIRGenBuilderTy
&builder,
+ bool isSub = false) {
+ assert((op.opcode == BO_Add || op.opcode == BO_AddAssign ||
+ op.opcode == BO_Sub || op.opcode == BO_SubAssign) &&
+ "Only fadd/fsub can be the root of an fmuladd.");
+
+ // Check whether this op is marked as fusable.
+ if (!op.fpFeatures.allowFPContractWithinStatement())
----------------
koparasy wrote:
I think we are good on this
https://github.com/llvm/llvm-project/pull/215382
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits