-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[MLIR][LLVM] Add fast-math related function attribute support #79812
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[MLIR][LLVM] Add fast-math related function attribute support #79812
Conversation
Adds unsafe-fp-math, no-infs-fp-math, no-nans-fp-math, approx-func-fp-math, and no-signed-zeros-fp-math function attributes.
@llvm/pr-subscribers-mlir-llvm @llvm/pr-subscribers-mlir Author: Alex Bradbury (asb) ChangesAdds unsafe-fp-math, no-infs-fp-math, no-nans-fp-math, approx-func-fp-math, and no-signed-zeros-fp-math function attributes. This allows code generators using the LLVMIR dialect to match the codegen of Clang. Full diff: https://github.com/llvm/llvm-project/pull/79812.diff 6 Files Affected:
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 01d476f530b1c5..ad67fba5a81cf8 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -1428,7 +1428,12 @@ def LLVM_LLVMFuncOp : LLVM_Op<"func", [
OptionalAttr<LLVM_VScaleRangeAttr>:$vscale_range,
OptionalAttr<FramePointerKindAttr>:$frame_pointer,
OptionalAttr<StrAttr>:$target_cpu,
- OptionalAttr<LLVM_TargetFeaturesAttr>:$target_features
+ OptionalAttr<LLVM_TargetFeaturesAttr>:$target_features,
+ OptionalAttr<BoolAttr>:$unsafe_fp_math,
+ OptionalAttr<BoolAttr>:$no_infs_fp_math,
+ OptionalAttr<BoolAttr>:$no_nans_fp_math,
+ OptionalAttr<BoolAttr>:$approx_func_fp_math,
+ OptionalAttr<BoolAttr>:$no_signed_zeros_fp_math
);
let regions = (region AnyRegion:$body);
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 928d8077175ccf..5ca4a9fd68d650 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1646,6 +1646,11 @@ static constexpr std::array ExplicitAttributes{
StringLiteral("vscale_range"),
StringLiteral("frame-pointer"),
StringLiteral("target-features"),
+ StringLiteral("unsafe-fp-math"),
+ StringLiteral("no-infs-fp-math"),
+ StringLiteral("no-nans-fp-math"),
+ StringLiteral("approx-func-fp-math"),
+ StringLiteral("no-signed-zeros-fp-math"),
};
static void processPassthroughAttrs(llvm::Function *func, LLVMFuncOp funcOp) {
@@ -1752,6 +1757,26 @@ void ModuleImport::processFunctionAttributes(llvm::Function *func,
attr.isStringAttribute())
funcOp.setTargetFeaturesAttr(
LLVM::TargetFeaturesAttr::get(context, attr.getValueAsString()));
+
+ if (llvm::Attribute attr = func->getFnAttribute("unsafe-fp-math");
+ attr.isStringAttribute())
+ funcOp.setUnsafeFpMath(attr.getValueAsBool());
+
+ if (llvm::Attribute attr = func->getFnAttribute("no-infs-fp-math");
+ attr.isStringAttribute())
+ funcOp.setNoInfsFpMath(attr.getValueAsBool());
+
+ if (llvm::Attribute attr = func->getFnAttribute("no-nans-fp-math");
+ attr.isStringAttribute())
+ funcOp.setNoNansFpMath(attr.getValueAsBool());
+
+ if (llvm::Attribute attr = func->getFnAttribute("approx-func-fp-math");
+ attr.isStringAttribute())
+ funcOp.setApproxFuncFpMath(attr.getValueAsBool());
+
+ if (llvm::Attribute attr = func->getFnAttribute("no-signed-zeros-fp-math");
+ attr.isStringAttribute())
+ funcOp.setNoSignedZerosFpMath(attr.getValueAsBool());
}
DictionaryAttr
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 69a1cbe5969e85..6364cacbd19245 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -37,6 +37,7 @@
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
#include "llvm/IR/BasicBlock.h"
@@ -1214,6 +1215,23 @@ LogicalResult ModuleTranslation::convertOneFunction(LLVMFuncOp func) {
getLLVMContext(), attr->getMinRange().getInt(),
attr->getMaxRange().getInt()));
+ if (auto unsafeFpMath = func.getUnsafeFpMath())
+ llvmFunc->addFnAttr("unsafe-fp-math", llvm::toStringRef(*unsafeFpMath));
+
+ if (auto noInfsFpMath = func.getNoInfsFpMath())
+ llvmFunc->addFnAttr("no-infs-fp-math", llvm::toStringRef(*noInfsFpMath));
+
+ if (auto noNansFpMath = func.getNoNansFpMath())
+ llvmFunc->addFnAttr("no-nans-fp-math", llvm::toStringRef(*noNansFpMath));
+
+ if (auto approxFuncFpMath = func.getApproxFuncFpMath())
+ llvmFunc->addFnAttr("approx-func-fp-math",
+ llvm::toStringRef(*approxFuncFpMath));
+
+ if (auto noSignedZerosFpMath = func.getNoSignedZerosFpMath())
+ llvmFunc->addFnAttr("no-signed-zeros-fp-math",
+ llvm::toStringRef(*noSignedZerosFpMath));
+
// Add function attribute frame-pointer, if found.
if (FramePointerKindAttr attr = func.getFramePointerAttr())
llvmFunc->addFnAttr("frame-pointer",
diff --git a/mlir/test/Dialect/LLVMIR/func.mlir b/mlir/test/Dialect/LLVMIR/func.mlir
index 9dc1bc57034e02..006f2f64a27277 100644
--- a/mlir/test/Dialect/LLVMIR/func.mlir
+++ b/mlir/test/Dialect/LLVMIR/func.mlir
@@ -257,6 +257,36 @@ module {
llvm.func @frame_pointer_roundtrip() attributes {frame_pointer = #llvm.framePointerKind<"non-leaf">} {
llvm.return
}
+
+ llvm.func @unsafe_fp_math_roundtrip() attributes {unsafe_fp_math = true} {
+ // CHECK: @unsafe_fp_math_roundtrip
+ // CHECK-SAME: attributes {unsafe_fp_math = true}
+ llvm.return
+ }
+
+ llvm.func @no_infs_fp_math_roundtrip() attributes {no_infs_fp_math = true} {
+ // CHECK: @no_infs_fp_math_roundtrip
+ // CHECK-SAME: attributes {no_infs_fp_math = true}
+ llvm.return
+ }
+
+ llvm.func @no_nans_fp_math_roundtrip() attributes {no_nans_fp_math = true} {
+ // CHECK: @no_nans_fp_math_roundtrip
+ // CHECK-SAME: attributes {no_nans_fp_math = true}
+ llvm.return
+ }
+
+ llvm.func @approx_func_fp_math_roundtrip() attributes {approx_func_fp_math = true} {
+ // CHECK: @approx_func_fp_math_roundtrip
+ // CHECK-SAME: attributes {approx_func_fp_math = true}
+ llvm.return
+ }
+
+ llvm.func @no_signed_zeros_fp_math_roundtrip() attributes {no_signed_zeros_fp_math = true} {
+ // CHECK: @no_signed_zeros_fp_math_roundtrip
+ // CHECK-SAME: attributes {no_signed_zeros_fp_math = true}
+ llvm.return
+ }
}
// -----
diff --git a/mlir/test/Target/LLVMIR/Import/function-attributes.ll b/mlir/test/Target/LLVMIR/Import/function-attributes.ll
index af2ef9db96ae33..70387789aa97e4 100644
--- a/mlir/test/Target/LLVMIR/Import/function-attributes.ll
+++ b/mlir/test/Target/LLVMIR/Import/function-attributes.ll
@@ -272,3 +272,33 @@ define void @align_func() align 2 {
; CHECK-LABEL: @align_decl
; CHECK-SAME: attributes {alignment = 64 : i64}
declare void @align_decl() align 64
+
+; // -----
+
+; CHECK-LABEL: @func_attr_unsafe_fp_math
+; CHECK-SAME: attributes {unsafe_fp_math = true}
+declare void @func_attr_unsafe_fp_math() "unsafe-fp-math"="true"
+
+; // -----
+
+; CHECK-LABEL: @func_attr_no_infs_fp_math
+; CHECK-SAME: attributes {no_infs_fp_math = true}
+declare void @func_attr_no_infs_fp_math() "no-infs-fp-math"="true"
+
+; // -----
+
+; CHECK-LABEL: @func_attr_no_nans_fp_math
+; CHECK-SAME: attributes {no_nans_fp_math = true}
+declare void @func_attr_no_nans_fp_math() "no-nans-fp-math"="true"
+
+; // -----
+
+; CHECK-LABEL: @func_attr_approx_func_fp_math
+; CHECK-SAME: attributes {approx_func_fp_math = true}
+declare void @func_attr_approx_func_fp_math() "approx-func-fp-math"="true"
+
+; // -----
+
+; CHECK-LABEL: @func_attr_no_signed_zeros_fp_math
+; CHECK-SAME: attributes {no_signed_zeros_fp_math = true}
+declare void @func_attr_no_signed_zeros_fp_math() "no-signed-zeros-fp-math"="true"
diff --git a/mlir/test/Target/LLVMIR/fp-math-function-attributes.mlir b/mlir/test/Target/LLVMIR/fp-math-function-attributes.mlir
new file mode 100644
index 00000000000000..ccae06cc3dd76d
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/fp-math-function-attributes.mlir
@@ -0,0 +1,44 @@
+// RUN: mlir-translate -mlir-to-llvmir -split-input-file %s | FileCheck %s
+
+// CHECK-LABEL: define void @unsafe_fp_math_func()
+// CHECK-SAME: #[[ATTRS:[0-9]+]]
+llvm.func @unsafe_fp_math_func() attributes {unsafe_fp_math = true} {
+ llvm.return
+}
+// CHECK: attributes #[[ATTRS]] = { "unsafe-fp-math"="true" }
+
+// -----
+
+// CHECK-LABEL: define void @no_infs_fp_math_func()
+// CHECK-SAME: #[[ATTRS:[0-9]+]]
+llvm.func @no_infs_fp_math_func() attributes {no_infs_fp_math = true} {
+ llvm.return
+}
+// CHECK: attributes #[[ATTRS]] = { "no-infs-fp-math"="true" }
+
+// -----
+
+// CHECK-LABEL: define void @no_nans_fp_math_func()
+// CHECK-SAME: #[[ATTRS:[0-9]+]]
+llvm.func @no_nans_fp_math_func() attributes {no_nans_fp_math = true} {
+ llvm.return
+}
+// CHECK: attributes #[[ATTRS]] = { "no-nans-fp-math"="true" }
+
+// -----
+
+// CHECK-LABEL: define void @approx_func_fp_math_func()
+// CHECK-SAME: #[[ATTRS:[0-9]+]]
+llvm.func @approx_func_fp_math_func() attributes {approx_func_fp_math = true} {
+ llvm.return
+}
+// CHECK: attributes #[[ATTRS]] = { "approx-func-fp-math"="true" }
+
+// -----
+
+// CHECK-LABEL: define void @no_signed_zeros_fp_math_func()
+// CHECK-SAME: #[[ATTRS:[0-9]+]]
+llvm.func @no_signed_zeros_fp_math_func() attributes {no_signed_zeros_fp_math = true} {
+ llvm.return
+}
+// CHECK: attributes #[[ATTRS]] = { "no-signed-zeros-fp-math"="true" }
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you so much for working on this! Code itself looks good to me although I am curious about the OptionalAttr<BoolAttr>
.
Is there any documentation one can read up on these attributes? They do not seem to be present in the language reference, requiring to resort to reading LLVM code to try and deduce semantics it seems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks LGTM!
Adds unsafe-fp-math, no-infs-fp-math, no-nans-fp-math, approx-func-fp-math, and no-signed-zeros-fp-math function attributes.
This allows code generators using the LLVMIR dialect to match the codegen of Clang.