[clang] [CIR] Add fenv attribute to more builtins (PR #212880)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 29 14:53:14 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Andy Kaylor (andykaylor)
<details>
<summary>Changes</summary>
This adds the #cir.fenv attribute to the CIR_UnaryFPToIntBuiltinOp and CIR_TernaryFPToFPBuiltinOp base classes, and through them to the cir.lround, cir.llround, cir.lrint, cir.llrint, and cir.fma operations.
This attribute is still missing from various cast and compare operations. Those will be added in a follow-up change.
Assisted-by: Cursor / various models
---
Full diff: https://github.com/llvm/llvm-project/pull/212880.diff
3 Files Affected:
- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+22-6)
- (modified) clang/test/CIR/IR/fenv.cir (+24)
- (modified) clang/unittests/CIR/FenvOpTest.cpp (+20-1)
``````````diff
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 7d6e250c09e02..8592d2e9bdc16 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -7236,9 +7236,10 @@ def CIR_FloorOp : CIR_UnaryFPToFPBuiltinOp<"floor", "FFloorOp"> {
}
class CIR_UnaryFPToIntBuiltinOp<string mnemonic, string llvmOpName>
- : CIR_Op<mnemonic, [Pure]>
+ : CIR_Op<mnemonic, CIR_FenvOpTraits>
{
- let arguments = (ins CIR_AnyFloatType:$src);
+ let arguments = (ins CIR_AnyFloatType:$src,
+ OptionalAttr<CIR_FenvAttr>:$fenv);
let results = (outs CIR_IntType:$result);
let summary = [{
@@ -7250,6 +7251,12 @@ class CIR_UnaryFPToIntBuiltinOp<string mnemonic, string llvmOpName>
$src `:` type($src) `->` type($result) attr-dict
}];
+ let builders = [
+ OpBuilder<(ins "mlir::Type":$result, "mlir::Value":$src), [{
+ build($_builder, $_state, result, src, cir::FenvAttr{});
+ }]>
+ ];
+
let llvmOp = llvmOpName;
}
@@ -7425,18 +7432,27 @@ def CIR_ModfOp : CIR_Op<"modf", [Pure]> {
}
class CIR_TernaryFPToFPBuiltinOp<string mnemonic, string llvmOpName>
- : CIR_Op<mnemonic, [Pure, SameOperandsAndResultType]>
+ : CIR_Op<mnemonic,
+ !listconcat([SameOperandsAndResultType], CIR_FenvOpTraits)>
{
- let arguments = (ins
+ let arguments = (ins
CIR_AnyFloatOrVecOfFloatType:$a,
CIR_AnyFloatOrVecOfFloatType:$b,
- CIR_AnyFloatOrVecOfFloatType:$c
+ CIR_AnyFloatOrVecOfFloatType:$c,
+ OptionalAttr<CIR_FenvAttr>:$fenv
);
-
+
let results = (outs CIR_AnyFloatOrVecOfFloatType:$result);
let assemblyFormat = "$a `,` $b `,` $c `:` type($a) attr-dict";
+ 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{});
+ }]>
+ ];
+
let llvmOp = llvmOpName;
}
diff --git a/clang/test/CIR/IR/fenv.cir b/clang/test/CIR/IR/fenv.cir
index fad82abdb43dc..d6817484b4feb 100644
--- a/clang/test/CIR/IR/fenv.cir
+++ b/clang/test/CIR/IR/fenv.cir
@@ -66,3 +66,27 @@ cir.func @binary_fp_builtin_fenv(%a: !cir.float, %b: !cir.float) {
%2 = cir.atan2 %a, %b : !cir.float
cir.return
}
+
+// CHECK-LABEL: cir.func @unary_fp_to_int_builtin_fenv
+cir.func @unary_fp_to_int_builtin_fenv(%a: !cir.float) -> !s32i {
+ // CHECK: cir.lround %{{.*}} : !cir.float -> !s32i {fenv = #cir.fenv<dynamic_rounding_mode = tonearest>}
+ %0 = cir.lround %a : !cir.float -> !s32i {fenv = #cir.fenv<dynamic_rounding_mode = tonearest>}
+ // CHECK: cir.llround %{{.*}} : !cir.float -> !s32i {fenv = #cir.fenv<except_mode = unmasked>}
+ %1 = cir.llround %a : !cir.float -> !s32i {fenv = #cir.fenv<except_mode = unmasked>}
+ // CHECK: cir.lrint %{{.*}} : !cir.float -> !s32i {fenv = #cir.fenv<>}
+ %2 = cir.lrint %a : !cir.float -> !s32i {fenv = #cir.fenv<>}
+ // CHECK: cir.llrint %{{.*}} : !cir.float -> !s32i
+ // CHECK-NOT: fenv
+ %3 = cir.llrint %a : !cir.float -> !s32i
+ cir.return %3 : !s32i
+}
+
+// CHECK-LABEL: cir.func @ternary_fp_builtin_fenv
+cir.func @ternary_fp_builtin_fenv(%a: !cir.float, %b: !cir.float, %c: !cir.float) {
+ // CHECK: cir.fma %{{.*}}, %{{.*}}, %{{.*}} : !cir.float {fenv = #cir.fenv<dynamic_rounding_mode = downward, strict_except = true>}
+ %0 = cir.fma %a, %b, %c : !cir.float {fenv = #cir.fenv<dynamic_rounding_mode = downward, strict_except = true>}
+ // CHECK: cir.fma %{{.*}}, %{{.*}}, %{{.*}} : !cir.float
+ // CHECK-NOT: fenv
+ %1 = cir.fma %a, %b, %c : !cir.float
+ cir.return
+}
diff --git a/clang/unittests/CIR/FenvOpTest.cpp b/clang/unittests/CIR/FenvOpTest.cpp
index 6a3a89b264e14..2588203971c7c 100644
--- a/clang/unittests/CIR/FenvOpTest.cpp
+++ b/clang/unittests/CIR/FenvOpTest.cpp
@@ -63,11 +63,16 @@ class CIRFenvOpTest : public ::testing::Test {
TEST_F(CIRFenvOpTest, MemoryEffects) {
OwningOpRef<ModuleOp> module = parse(R"CIR(
- cir.func @f(%a: !cir.float, %b: !cir.float) {
+ !s32i = !cir.int<s, 32>
+ cir.func @f(%a: !cir.float, %b: !cir.float, %c: !cir.float) {
%0 = cir.fadd %a, %b : !cir.float
%1 = cir.fadd %a, %b : !cir.float {fenv = #cir.fenv<>}
%2 = cir.sqrt %a : !cir.float {fenv = #cir.fenv<>}
%3 = cir.pow %a, %b : !cir.float {fenv = #cir.fenv<>}
+ %4 = cir.fma %a, %b, %c : !cir.float
+ %5 = cir.fma %a, %b, %c : !cir.float {fenv = #cir.fenv<>}
+ %6 = cir.lround %a : !cir.float -> !s32i
+ %7 = cir.lround %a : !cir.float -> !s32i {fenv = #cir.fenv<>}
cir.return
}
)CIR");
@@ -87,6 +92,20 @@ TEST_F(CIRFenvOpTest, MemoryEffects) {
SmallVector<cir::PowOp> powOps = findOps<cir::PowOp>(*module);
ASSERT_EQ(powOps.size(), 1u);
expectFenvReadAndWrite(powOps[0]);
+
+ SmallVector<cir::FMAOp> fmaOps = findOps<cir::FMAOp>(*module);
+ ASSERT_EQ(fmaOps.size(), 2u);
+ EXPECT_TRUE(getEffects(fmaOps[0]).empty());
+ EXPECT_TRUE(isMemoryEffectFree(fmaOps[0]));
+ expectFenvReadAndWrite(fmaOps[1]);
+ EXPECT_FALSE(isMemoryEffectFree(fmaOps[1]));
+
+ SmallVector<cir::LroundOp> lroundOps = findOps<cir::LroundOp>(*module);
+ ASSERT_EQ(lroundOps.size(), 2u);
+ EXPECT_TRUE(getEffects(lroundOps[0]).empty());
+ EXPECT_TRUE(isMemoryEffectFree(lroundOps[0]));
+ expectFenvReadAndWrite(lroundOps[1]);
+ EXPECT_FALSE(isMemoryEffectFree(lroundOps[1]));
}
TEST_F(CIRFenvOpTest, Speculatability) {
``````````
</details>
https://github.com/llvm/llvm-project/pull/212880
More information about the cfe-commits
mailing list