llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: adams381

<details>
<summary>Changes</summary>

When `-menable-no-infs` or `-menable-no-nans` is set, OGCG adds
`nofpclass(nan inf)` to FP arguments and return values.  CIR was
missing this.

Adds the check in `constructFunctionReturnAttributes` and
`constructFunctionArgumentAttributes`, gated on
`hasFloatingRepresentation()` (same condition classic codegen uses
in `canApplyNoFPClass`).

The MLIR LLVM dialect already has `llvm.nofpclass` from #<!-- -->188374,
so only the CIRGen side is needed here.

Test covers float, double, `_Complex double`, and a non-FP
control case.

Made with [Cursor](https://cursor.com)

---
Full diff: https://github.com/llvm/llvm-project/pull/191455.diff


2 Files Affected:

- (modified) clang/lib/CIR/CodeGen/CIRGenCall.cpp (+23-3) 
- (added) clang/test/CIR/CodeGen/nofpclass.c (+22) 


``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp 
b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
index 876fef687b477..4e623de96442e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
@@ -18,6 +18,7 @@
 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
 #include "clang/CIR/ABIArgInfo.h"
 #include "clang/CIR/MissingFeatures.h"
+#include "llvm/ADT/FloatingPointMode.h"
 #include "llvm/Support/TypeSize.h"
 
 using namespace clang;
@@ -587,9 +588,17 @@ void CIRGenModule::constructFunctionReturnAttributes(
     retAttrs.set(mlir::LLVM::LLVMDialect::getNoUndefAttrName(),
                  mlir::UnitAttr::get(&getMLIRContext()));
 
-  // TODO(cir): classic codegen adds a bunch of attributes based on
-  // calling-convention lowering results.  However, since calling conventions
-  // haven't happened yet, this work likely has to happen there.
+  // nofpclass(nan inf) when -menable-no-infs / -menable-no-nans.
+  if (retTy->hasFloatingRepresentation()) {
+    unsigned mask = 0;
+    if (getLangOpts().NoHonorInfs)
+      mask |= llvm::fcInf;
+    if (getLangOpts().NoHonorNaNs)
+      mask |= llvm::fcNan;
+    if (mask)
+      retAttrs.set(mlir::LLVM::LLVMDialect::getNoFPClassAttrName(),
+                   builder.getI64IntegerAttr(mask));
+  }
 
   if (!isThunk) {
     // TODO(cir): following comment taken from classic codegen, so if anything
@@ -698,6 +707,17 @@ void CIRGenModule::constructFunctionArgumentAttributes(
             builder.getI64IntegerAttr(
                 getNaturalPointeeTypeAlignment(argType).getQuantity()));
     }
+
+    if (argType->hasFloatingRepresentation()) {
+      unsigned mask = 0;
+      if (getLangOpts().NoHonorInfs)
+        mask |= llvm::fcInf;
+      if (getLangOpts().NoHonorNaNs)
+        mask |= llvm::fcNan;
+      if (mask)
+        argAttrList.set(mlir::LLVM::LLVMDialect::getNoFPClassAttrName(),
+                        builder.getI64IntegerAttr(mask));
+    }
   }
 }
 
diff --git a/clang/test/CIR/CodeGen/nofpclass.c 
b/clang/test/CIR/CodeGen/nofpclass.c
new file mode 100644
index 0000000000000..56563173600a8
--- /dev/null
+++ b/clang/test/CIR/CodeGen/nofpclass.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -menable-no-infs 
-menable-no-nans -fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -menable-no-infs 
-menable-no-nans -emit-llvm %s -o %t.ll
+// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s
+
+float identity(float x) { return x; }
+// LLVM: define {{.*}} nofpclass(nan inf) float @identity(float noundef 
nofpclass(nan inf) %{{.*}})
+// OGCG: define {{.*}} nofpclass(nan inf) float @identity(float noundef 
nofpclass(nan inf) %{{.*}})
+
+double add(double a, double b) { return a + b; }
+// LLVM: define {{.*}} nofpclass(nan inf) double @add(double noundef 
nofpclass(nan inf) %{{.*}}, double noundef nofpclass(nan inf) %{{.*}})
+// OGCG: define {{.*}} nofpclass(nan inf) double @add(double noundef 
nofpclass(nan inf) %{{.*}}, double noundef nofpclass(nan inf) %{{.*}})
+
+_Complex double ret_complex(void) { return 1.0 + 2.0i; }
+// LLVM: define {{.*}} nofpclass(nan inf) { double, double } @ret_complex()
+// OGCG: define {{.*}} nofpclass(nan inf) { double, double } @ret_complex()
+
+int non_fp(int x) { return x; }
+// LLVM: define {{.*}} i32 @non_fp(i32 noundef %{{.*}})
+// LLVM-NOT: nofpclass
+// OGCG: define {{.*}} i32 @non_fp(i32 noundef %{{.*}})
+// OGCG-NOT: nofpclass

``````````

</details>


https://github.com/llvm/llvm-project/pull/191455
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to