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
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to