llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: David Rivera (RiverDave) <details> <summary>Changes</summary> Classic CodeGen stamps contract on floating-point instructions so a later Standard-fusion backend can still form an FMA. CIR only fused within a statement via cir.fmuladd, which dropped FFMA on the CUDA device default. While the LLVM dialect specifies nearly the same fast math flags, I didn't make use of them given it would introduce a dependency (partly inspired by a similar comment in a different PR: https://github.com/llvm/llvm-project/pull/223890#pullrequestreview-5246892362). Assisted-by: Cursor / Grok 4.7 --- Patch is 51.14 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/226334.diff 15 Files Affected: - (modified) clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h (+30-8) - (modified) clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td (+30) - (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+54-17) - (modified) clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp (+15-6) - (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+22-10) - (modified) clang/lib/CIR/CodeGen/CIRGenFunction.cpp (+18-1) - (modified) clang/lib/CIR/CodeGen/CIRGenFunction.h (+2) - (modified) clang/lib/CIR/Dialect/IR/CIRDialect.cpp (+6) - (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+93-28) - (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h (+4) - (added) clang/test/CIR/CodeGen/fp-contract-fast.c (+138) - (modified) clang/test/CIR/CodeGen/fp-math-precision-opts.c (+4-4) - (added) clang/test/CIR/CodeGenCUDA/fp-contract.cu (+57) - (added) clang/test/CIR/Lowering/fastmath-contract.cir (+47) - (modified) clang/utils/TableGen/CIRLoweringEmitter.cpp (+15-2) ``````````diff diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 29f1a64ad1d17..e8ec07a66a77a 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -74,6 +74,18 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { clang::LangOptions::FPE_Ignore; llvm::RoundingMode defaultConstrainedRounding = llvm::RoundingMode::NearestTiesToEven; + // Fast-math flags applied to floating-point ops created by this builder. + // CIRGen currently populates `contract` only. + cir::FastMathFlags fastMathFlags = cir::FastMathFlags::none; + + void setFastMathFlags(cir::FastMathFlags flags) { fastMathFlags = flags; } + cir::FastMathFlags getFastMathFlags() const { return fastMathFlags; } + + cir::FastMathFlagsAttr getFastMathFlagsAttr() { + if (fastMathFlags == cir::FastMathFlags::none) + return {}; + return cir::FastMathFlagsAttr::get(getContext(), fastMathFlags); + } mlir::Value getConstAPInt(mlir::Location loc, mlir::Type typ, const llvm::APInt &val) { @@ -848,32 +860,39 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { mlir::Value createFAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) { assert(!cir::MissingFeatures::metaDataNode()); + // `contract` is applied via getFastMathFlagsAttr(). The other fast-math + // bits are still unimplemented. assert(!cir::MissingFeatures::fastMathFlags()); - return cir::FAddOp::create(*this, loc, lhs, rhs, getConstrainedFPAttr()); + return cir::FAddOp::create(*this, loc, lhs, rhs, getConstrainedFPAttr(), + getFastMathFlagsAttr()); } mlir::Value createFSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) { assert(!cir::MissingFeatures::metaDataNode()); assert(!cir::MissingFeatures::fastMathFlags()); - return cir::FSubOp::create(*this, loc, lhs, rhs, getConstrainedFPAttr()); + return cir::FSubOp::create(*this, loc, lhs, rhs, getConstrainedFPAttr(), + getFastMathFlagsAttr()); } mlir::Value createFMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) { assert(!cir::MissingFeatures::metaDataNode()); assert(!cir::MissingFeatures::fastMathFlags()); - return cir::FMulOp::create(*this, loc, lhs, rhs, getConstrainedFPAttr()); + return cir::FMulOp::create(*this, loc, lhs, rhs, getConstrainedFPAttr(), + getFastMathFlagsAttr()); } mlir::Value createFDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) { assert(!cir::MissingFeatures::metaDataNode()); assert(!cir::MissingFeatures::fastMathFlags()); - return cir::FDivOp::create(*this, loc, lhs, rhs, getConstrainedFPAttr()); + return cir::FDivOp::create(*this, loc, lhs, rhs, getConstrainedFPAttr(), + getFastMathFlagsAttr()); } mlir::Value createFRem(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) { assert(!cir::MissingFeatures::metaDataNode()); assert(!cir::MissingFeatures::fastMathFlags()); - return cir::FRemOp::create(*this, loc, lhs, rhs, getConstrainedFPAttr()); + return cir::FRemOp::create(*this, loc, lhs, rhs, getConstrainedFPAttr(), + getFastMathFlagsAttr()); } mlir::Value createFNeg(mlir::Location loc, mlir::Value operand) { @@ -883,7 +902,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { assert(!cir::MissingFeatures::fastMathFlags()); // fneg does not raise FP exceptions or depend on the rounding mode, so it // never carries an fenv attribute. - return cir::FNegOp::create(*this, loc, operand); + return cir::FNegOp::create(*this, loc, operand, getFastMathFlagsAttr()); } mlir::Value createXor(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) { @@ -903,7 +922,10 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { cir::FenvAttr fenv; if (cir::isAnyFloatingPointType(lhs.getType())) fenv = getConstrainedFPAttr(); - return cir::CmpOp::create(*this, loc, kind, lhs, rhs, fenv); + return cir::CmpOp::create(*this, loc, kind, lhs, rhs, fenv, + cir::isAnyFloatingPointType(lhs.getType()) + ? getFastMathFlagsAttr() + : cir::FastMathFlagsAttr{}); } cir::VecCmpOp createVecCompare(mlir::Location loc, cir::CmpOpKind kind, @@ -917,7 +939,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { if (cir::isFPOrVectorOfFPType(lhs.getType())) fenv = getConstrainedFPAttr(); return cir::VecCmpOp::create(*this, loc, integralVecTy, kind, lhs, rhs, - fenv); + fenv, getFastMathFlagsAttr()); } mlir::Value createIsNaN(mlir::Location loc, mlir::Value operand) { diff --git a/clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td b/clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td index 3ee06412d8a90..ecd981593ec04 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td +++ b/clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td @@ -47,6 +47,36 @@ class CIR_EnumAttr<EnumInfo info, string name = "", list<Trait> traits = []> let assemblyFormat = "`<` $value `>`"; } +// Bit positions match `mlir::LLVM::FastmathFlags`. Only `contract` is set by +// CIRGen today; the other bits exist so the attribute can round-trip. +def CIR_FastMathFlags : CIR_I32BitEnum< + "FastMathFlags", "fast-math flags", [ + I32BitEnumCaseNone<"none">, + I32BitEnumCaseBit<"nnan", 0>, + I32BitEnumCaseBit<"ninf", 1>, + I32BitEnumCaseBit<"nsz", 2>, + I32BitEnumCaseBit<"arcp", 3>, + I32BitEnumCaseBit<"contract", 4>, + I32BitEnumCaseBit<"afn", 5>, + I32BitEnumCaseBit<"reassoc", 6> +]> { + let description = [{ + Per-operation fast-math flags. These are the LLVM fast-math bits, carried + on CIR floating-point operations and lowered onto the corresponding LLVM + dialect operation's `fastmathFlags`. + + `contract` allows the backend to fuse this operation with another + floating-point operation, including across statements. It is what + `-ffp-contract=fast` records. `-ffp-contract=on` is represented separately + by `cir.fmuladd`. + }]; + let separator = ", "; +} + +def CIR_FastMathFlagsAttr : CIR_EnumAttr<CIR_FastMathFlags, "fastmath"> { + let summary = "Fast-math flags for a floating-point operation"; +} + def CIR_LangAddressSpace : CIR_I32Enum< "LangAddressSpace", "language address space kind", [ I32EnumCase<"Default", 0, "default">, diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index c1ba78eea2835..9a83faff745d2 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -87,6 +87,10 @@ class LLVMLoweringInfo { string llvmOp = ""; string constrainedLLVMIntrinsic = ""; bit constrainedLLVMIntrinsicHasRoundingMode = true; + // Copy an optional `fastmath` attribute onto the lowered LLVM operation. + // Floating-point ops that go through `lowerConstrainableFPOp` propagate the + // attribute there and do not need this bit. + bit propagateFastMathFlags = false; } class LoweringBuilders<dag p> { @@ -2160,18 +2164,31 @@ def CIR_FNegOp : CIR_UnaryOp<"fneg", CIR_AnyFloatOrVecOfFloatType> { The `cir.fneg` operation negates the operand. The operand and result must have the same type. + The optional `fastmath` attribute carries LLVM fast-math flags for this + operation. `-ffp-contract=fast` sets `contract`. + Example: ``` %1 = cir.fneg %0 : !cir.float - %3 = cir.fneg %2 : !cir.double + %3 = cir.fneg %2 : !cir.double {fastmath = #cir.fastmath<contract>} %5 = cir.fneg %4 : !cir.vector<4 x !cir.float> ``` }]; + let arguments = !con(commonArgs, + (ins OptionalAttr<CIR_FastMathFlagsAttr>:$fastmath)); + + let builders = [ + OpBuilder<(ins "mlir::Value":$input), [{ + build($_builder, $_state, input, cir::FastMathFlagsAttr{}); + }]> + ]; + let hasFolder = 1; let llvmOp = "FNegOp"; + let propagateFastMathFlags = true; } //===----------------------------------------------------------------------===// @@ -2626,7 +2643,8 @@ def CIR_CmpOp : CIR_Op<"cmp", CIR_CmpOpKindAttr:$kind, CIR_ComparableType:$lhs, CIR_ComparableType:$rhs, - OptionalAttr<CIR_FenvAttr>:$fenv + OptionalAttr<CIR_FenvAttr>:$fenv, + OptionalAttr<CIR_FastMathFlagsAttr>:$fastmath ); let results = (outs CIR_BoolType:$result); @@ -2638,11 +2656,13 @@ def CIR_CmpOp : CIR_Op<"cmp", let builders = [ OpBuilder<(ins "cir::CmpOpKind":$kind, "mlir::Value":$lhs, "mlir::Value":$rhs), [{ - build($_builder, $_state, kind, lhs, rhs, cir::FenvAttr{}); + build($_builder, $_state, kind, lhs, rhs, cir::FenvAttr{}, + cir::FastMathFlagsAttr{}); }]>, OpBuilder<(ins "mlir::Type":$result, "cir::CmpOpKind":$kind, "mlir::Value":$lhs, "mlir::Value":$rhs), [{ - build($_builder, $_state, result, kind, lhs, rhs, cir::FenvAttr{}); + build($_builder, $_state, result, kind, lhs, rhs, cir::FenvAttr{}, + cir::FastMathFlagsAttr{}); }]> ]; @@ -2941,18 +2961,23 @@ def CIR_RemOp : CIR_BinaryOp<"rem", CIR_AnyIntOrVecOfIntType> { // and result must all be the same floating-point scalar or vector type. // // The optional `fenv` attribute describes constraints on the floating-point -// handling of the operation. +// handling of the operation. The optional `fastmath` attribute carries LLVM +// fast-math flags; `-ffp-contract=fast` sets `contract` here rather than +// forming `cir.fmuladd`. class CIR_FPBinaryOp<string mnemonic, list<Trait> traits = []> : CIR_BinaryOp<mnemonic, CIR_AnyFloatOrVecOfFloatType, !listconcat(CIR_FenvOpTraits, traits), CIR_DynamicMemoryEffects> { - let arguments = !con(commonArgs, (ins OptionalAttr<CIR_FenvAttr>:$fenv)); + let arguments = !con(commonArgs, (ins + OptionalAttr<CIR_FenvAttr>:$fenv, + OptionalAttr<CIR_FastMathFlagsAttr>:$fastmath)); let constrainedLLVMIntrinsic = mnemonic; let builders = [ OpBuilder<(ins "mlir::Value":$lhs, "mlir::Value":$rhs), [{ - build($_builder, $_state, lhs, rhs, cir::FenvAttr{}); + build($_builder, $_state, lhs, rhs, cir::FenvAttr{}, + cir::FastMathFlagsAttr{}); }]> ]; } @@ -6084,7 +6109,8 @@ def CIR_VecCmpOp : CIR_Op<"vec.cmp", CIR_CmpOpKindAttr:$kind, CIR_VectorType:$lhs, CIR_VectorType:$rhs, - OptionalAttr<CIR_FenvAttr>:$fenv + OptionalAttr<CIR_FenvAttr>:$fenv, + OptionalAttr<CIR_FastMathFlagsAttr>:$fastmath ); let results = (outs CIR_VectorType:$result); @@ -6097,7 +6123,8 @@ def CIR_VecCmpOp : CIR_Op<"vec.cmp", let builders = [ OpBuilder<(ins "mlir::Type":$result, "cir::CmpOpKind":$kind, "mlir::Value":$lhs, "mlir::Value":$rhs), [{ - build($_builder, $_state, result, kind, lhs, rhs, cir::FenvAttr{}); + build($_builder, $_state, result, kind, lhs, rhs, cir::FenvAttr{}, + cir::FastMathFlagsAttr{}); }]> ]; @@ -7438,14 +7465,16 @@ class CIR_UnaryFPToFPBuiltinOp<string mnemonic, string llvmOpName> !listconcat([SameOperandsAndResultType], CIR_FenvOpTraits)> { let arguments = (ins CIR_AnyFloatOrVecOfFloatType:$src, - OptionalAttr<CIR_FenvAttr>:$fenv); + OptionalAttr<CIR_FenvAttr>:$fenv, + OptionalAttr<CIR_FastMathFlagsAttr>:$fastmath); let results = (outs CIR_AnyFloatOrVecOfFloatType:$result); let assemblyFormat = "$src `:` type($src) attr-dict"; let builders = [ OpBuilder<(ins "mlir::Value":$src), [{ - build($_builder, $_state, src, cir::FenvAttr{}); + build($_builder, $_state, src, cir::FenvAttr{}, + cir::FastMathFlagsAttr{}); }]> ]; @@ -7706,6 +7735,7 @@ def CIR_FAbsOp : CIR_UnaryFPToFPBuiltinOp<"fabs", "FAbsOp"> { // fabs is exact and does not raise exceptions, so it is always lowered to // the plain llvm.fabs intrinsic. let constrainedLLVMIntrinsic = ""; + let propagateFastMathFlags = true; } def CIR_AbsOp : CIR_Op<"abs", [Pure, SameOperandsAndResultType]> { @@ -7760,7 +7790,8 @@ class CIR_UnaryFPToIntBuiltinOp<string mnemonic, string llvmOpName> : CIR_Op<mnemonic, CIR_FenvOpTraits> { let arguments = (ins CIR_AnyFloatType:$src, - OptionalAttr<CIR_FenvAttr>:$fenv); + OptionalAttr<CIR_FenvAttr>:$fenv, + OptionalAttr<CIR_FastMathFlagsAttr>:$fastmath); let results = (outs CIR_IntType:$result); let summary = [{ @@ -7774,7 +7805,8 @@ class CIR_UnaryFPToIntBuiltinOp<string mnemonic, string llvmOpName> let builders = [ OpBuilder<(ins "mlir::Type":$result, "mlir::Value":$src), [{ - build($_builder, $_state, result, src, cir::FenvAttr{}); + build($_builder, $_state, result, src, cir::FenvAttr{}, + cir::FastMathFlagsAttr{}); }]> ]; @@ -7829,7 +7861,8 @@ class CIR_BinaryFPToFPBuiltinOp<string mnemonic, string llvmOpName> let arguments = (ins CIR_AnyFloatOrVecOfFloatType:$lhs, CIR_AnyFloatOrVecOfFloatType:$rhs, - OptionalAttr<CIR_FenvAttr>:$fenv + OptionalAttr<CIR_FenvAttr>:$fenv, + OptionalAttr<CIR_FastMathFlagsAttr>:$fastmath ); let results = (outs CIR_AnyFloatOrVecOfFloatType:$result); @@ -7841,7 +7874,8 @@ class CIR_BinaryFPToFPBuiltinOp<string mnemonic, string llvmOpName> let builders = [ OpBuilder<(ins "mlir::Type":$result, "mlir::Value":$lhs, "mlir::Value":$rhs), [{ - build($_builder, $_state, result, lhs, rhs, cir::FenvAttr{}); + build($_builder, $_state, result, lhs, rhs, cir::FenvAttr{}, + cir::FastMathFlagsAttr{}); }]> ]; @@ -7857,6 +7891,7 @@ def CIR_CopysignOp : CIR_BinaryFPToFPBuiltinOp<"copysign", "CopySignOp"> { // copysign is exact and does not raise exceptions, so it is always lowered // to the plain llvm.copysign intrinsic. + let propagateFastMathFlags = true; } def CIR_FMaxNumOp : CIR_BinaryFPToFPBuiltinOp<"fmaxnum", "MaxNumOp"> { @@ -7981,7 +8016,8 @@ class CIR_TernaryFPToFPBuiltinOp<string mnemonic, string llvmOpName> CIR_AnyFloatOrVecOfFloatType:$a, CIR_AnyFloatOrVecOfFloatType:$b, CIR_AnyFloatOrVecOfFloatType:$c, - OptionalAttr<CIR_FenvAttr>:$fenv + OptionalAttr<CIR_FenvAttr>:$fenv, + OptionalAttr<CIR_FastMathFlagsAttr>:$fastmath ); let results = (outs CIR_AnyFloatOrVecOfFloatType:$result); @@ -7991,7 +8027,8 @@ class CIR_TernaryFPToFPBuiltinOp<string mnemonic, string llvmOpName> let builders = [ OpBuilder<(ins "mlir::Type":$result, "mlir::Value":$a, "mlir::Value":$b, "mlir::Value":$c), [{ - build($_builder, $_state, result, a, b, c, cir::FenvAttr{}); + build($_builder, $_state, result, a, b, c, cir::FenvAttr{}, + cir::FastMathFlagsAttr{}); }]> ]; diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 2b223c8ae1939..2d2ed0cceefbe 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -558,14 +558,18 @@ static RValue emitUnaryMaybeConstrainedFPBuiltin(CIRGenFunction &cgf, CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, &e); auto call = Operation::create(cgf.getBuilder(), arg.getLoc(), arg.getType(), - arg, cgf.getBuilder().getConstrainedFPAttr()); + arg, cgf.getBuilder().getConstrainedFPAttr(), + cgf.getBuilder().getFastMathFlagsAttr()); return RValue::get(call->getResult(0)); } template <class Operation> static RValue emitUnaryFPBuiltin(CIRGenFunction &cgf, const CallExpr &e) { mlir::Value arg = cgf.emitScalarExpr(e.getArg(0)); - auto call = Operation::create(cgf.getBuilder(), arg.getLoc(), arg); + CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, &e); + auto call = Operation::create(cgf.getBuilder(), arg.getLoc(), arg.getType(), + arg, cir::FenvAttr{}, + cgf.getBuilder().getFastMathFlagsAttr()); return RValue::get(call->getResult(0)); } @@ -578,7 +582,8 @@ static RValue emitUnaryMaybeConstrainedFPToIntBuiltin(CIRGenFunction &cgf, CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, &e); auto call = Op::create(cgf.getBuilder(), src.getLoc(), resultType, src, - cgf.getBuilder().getConstrainedFPAttr()); + cgf.getBuilder().getConstrainedFPAttr(), + cgf.getBuilder().getFastMathFlagsAttr()); return RValue::get(call->getResult(0)); } @@ -587,9 +592,11 @@ static RValue emitBinaryFPBuiltin(CIRGenFunction &cgf, const CallExpr &e) { mlir::Value arg0 = cgf.emitScalarExpr(e.getArg(0)); mlir::Value arg1 = cgf.emitScalarExpr(e.getArg(1)); + CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, &e); mlir::Location loc = cgf.getLoc(e.getExprLoc()); mlir::Type ty = cgf.convertType(e.getType()); - auto call = Op::create(cgf.getBuilder(), loc, ty, arg0, arg1); + auto call = Op::create(cgf.getBuilder(), loc, ty, arg0, arg1, cir::FenvAttr{}, + cgf.getBuilder().getFastMathFlagsAttr()); return RValue::get(call->getResult(0)); } @@ -621,7 +628,8 @@ static RValue emitTernaryMaybeConstrainedFPBuiltin(CIRGenFunction &cgf, mlir::Type ty = cgf.convertType(e.getType()); auto call = Op::create(cgf.getBuilder(), loc, ty, arg0, arg1, arg2, - cgf.getBuilder().getConstrainedFPAttr()); + cgf.getBuilder().getConstrainedFPAttr(), + cgf.getBuilder().getFastMathFlagsAttr()); return RValue::get(call->getResult(0)); } @@ -637,7 +645,8 @@ static mlir::Value emitBinaryMaybeConstrainedFPBuiltin(CIRGenFunction &cgf, mlir::Type ty = cgf.convertType(e.getType()); auto call = Op::create(cgf.getBuilder(), loc, ty, arg0, arg1, - cgf.getBuilder().getConstrainedFPAttr()); + cgf.getBuilder().getConstrainedFPAttr(), + cgf.getBuilder().getFastMathFlagsAttr()); return call->getResult(0); } diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 80e8b36dfda6b..cc29109883b77 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -899,8 +899,11 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> { mlir::Location loc = cgf.getLoc(e->getSourceRange().getBegin()); - if (cir::isFPOrVectorOfFPType(operand.getType())) - return builder.createOrFold<cir::FNegOp>(loc, operand); + if (cir::isFPOrVectorOfFPType(operand.getType())) { + CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, e); + return builder.createOrFold<cir::FNegOp>(loc, operand, + builder.getFastMathFlagsAttr()); + } // TODO(cir): We might have to change this to support overflow trapping. // Classic codegen routes unary minus through emitSub to ensure @@ -1281,6 +1284,9 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> { BinOpInfo boInfo = emitBinOps(e); mlir::Value lhs = boInfo.lhs; mlir::Value rhs = boInfo.rhs; + std::optional<CIRGenFunction::CIRGenFPOptionsRAII> fpOpts; + if (cir::isFPOrVectorOfFPType(lhs.getType())) + fpOpts.emplace(cgf, boInfo.fpFeatures); if (lhsTy->isVectorType()) { if (!e->getType()->isVectorType()) { @@ -1290,9 +1296,15 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> { } else { // Other kinds of vectors. Element-wise comparison returning // a vector. - result = cir::VecCmpOp::create(builder, cgf.getLoc(boInfo.loc), - cgf.convertType(boInfo.fullType), kind, - boInfo.lhs, boInfo.rhs); + result = cir::VecCmpOp::create( + bu... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/226334 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
