[clang] [CIR] Add nofpclass for fast-math flags (PR #191455)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 10 09:27:29 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangir
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
More information about the cfe-commits
mailing list