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