Skip to content

Commit

Permalink
[MLIR][LLVM] Add fast-math related function attribute support (#79812)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
asb committed Jan 30, 2024
1 parent 8774d29 commit 748c295
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 1 deletion.
7 changes: 6 additions & 1 deletion mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
Expand Up @@ -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);
Expand Down
25 changes: 25 additions & 0 deletions mlir/lib/Target/LLVMIR/ModuleImport.cpp
Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -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",
Expand Down
30 changes: 30 additions & 0 deletions mlir/test/Dialect/LLVMIR/func.mlir
Expand Up @@ -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
}
}

// -----
Expand Down
60 changes: 60 additions & 0 deletions mlir/test/Target/LLVMIR/Import/function-attributes.ll
Expand Up @@ -272,3 +272,63 @@ 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_true
; CHECK-SAME: attributes {unsafe_fp_math = true}
declare void @func_attr_unsafe_fp_math_true() "unsafe-fp-math"="true"

; // -----

; CHECK-LABEL: @func_attr_unsafe_fp_math_false
; CHECK-SAME: attributes {unsafe_fp_math = false}
declare void @func_attr_unsafe_fp_math_false() "unsafe-fp-math"="false"

; // -----

; CHECK-LABEL: @func_attr_no_infs_fp_math_true
; CHECK-SAME: attributes {no_infs_fp_math = true}
declare void @func_attr_no_infs_fp_math_true() "no-infs-fp-math"="true"

; // -----

; CHECK-LABEL: @func_attr_no_infs_fp_math_false
; CHECK-SAME: attributes {no_infs_fp_math = false}
declare void @func_attr_no_infs_fp_math_false() "no-infs-fp-math"="false"

; // -----

; CHECK-LABEL: @func_attr_no_nans_fp_math_true
; CHECK-SAME: attributes {no_nans_fp_math = true}
declare void @func_attr_no_nans_fp_math_true() "no-nans-fp-math"="true"

; // -----

; CHECK-LABEL: @func_attr_no_nans_fp_math_false
; CHECK-SAME: attributes {no_nans_fp_math = false}
declare void @func_attr_no_nans_fp_math_false() "no-nans-fp-math"="false"

; // -----

; CHECK-LABEL: @func_attr_approx_func_fp_math_true
; CHECK-SAME: attributes {approx_func_fp_math = true}
declare void @func_attr_approx_func_fp_math_true() "approx-func-fp-math"="true"

; // -----

; CHECK-LABEL: @func_attr_approx_func_fp_math_false
; CHECK-SAME: attributes {approx_func_fp_math = false}
declare void @func_attr_approx_func_fp_math_false() "approx-func-fp-math"="false"

; // -----

; CHECK-LABEL: @func_attr_no_signed_zeros_fp_math_true
; CHECK-SAME: attributes {no_signed_zeros_fp_math = true}
declare void @func_attr_no_signed_zeros_fp_math_true() "no-signed-zeros-fp-math"="true"

; // -----

; CHECK-LABEL: @func_attr_no_signed_zeros_fp_math_false
; CHECK-SAME: attributes {no_signed_zeros_fp_math = false}
declare void @func_attr_no_signed_zeros_fp_math_false() "no-signed-zeros-fp-math"="false"
89 changes: 89 additions & 0 deletions mlir/test/Target/LLVMIR/fp-math-function-attributes.mlir
@@ -0,0 +1,89 @@
// RUN: mlir-translate -mlir-to-llvmir -split-input-file %s | FileCheck %s

// CHECK-LABEL: define void @unsafe_fp_math_func_true()
// CHECK-SAME: #[[ATTRS:[0-9]+]]
llvm.func @unsafe_fp_math_func_true() attributes {unsafe_fp_math = true} {
llvm.return
}
// CHECK: attributes #[[ATTRS]] = { "unsafe-fp-math"="true" }

// -----

// CHECK-LABEL: define void @unsafe_fp_math_func_false()
// CHECK-SAME: #[[ATTRS:[0-9]+]]
llvm.func @unsafe_fp_math_func_false() attributes {unsafe_fp_math = false} {
llvm.return
}
// CHECK: attributes #[[ATTRS]] = { "unsafe-fp-math"="false" }

// -----

// CHECK-LABEL: define void @no_infs_fp_math_func_true()
// CHECK-SAME: #[[ATTRS:[0-9]+]]
llvm.func @no_infs_fp_math_func_true() attributes {no_infs_fp_math = true} {
llvm.return
}
// CHECK: attributes #[[ATTRS]] = { "no-infs-fp-math"="true" }

// -----

// CHECK-LABEL: define void @no_infs_fp_math_func_false()
// CHECK-SAME: #[[ATTRS:[0-9]+]]
llvm.func @no_infs_fp_math_func_false() attributes {no_infs_fp_math = false} {
llvm.return
}
// CHECK: attributes #[[ATTRS]] = { "no-infs-fp-math"="false" }

// -----

// CHECK-LABEL: define void @no_nans_fp_math_func_true()
// CHECK-SAME: #[[ATTRS:[0-9]+]]
llvm.func @no_nans_fp_math_func_true() attributes {no_nans_fp_math = true} {
llvm.return
}
// CHECK: attributes #[[ATTRS]] = { "no-nans-fp-math"="true" }

// -----

// CHECK-LABEL: define void @no_nans_fp_math_func_false()
// CHECK-SAME: #[[ATTRS:[0-9]+]]
llvm.func @no_nans_fp_math_func_false() attributes {no_nans_fp_math = false} {
llvm.return
}
// CHECK: attributes #[[ATTRS]] = { "no-nans-fp-math"="false" }

// -----

// CHECK-LABEL: define void @approx_func_fp_math_func_true()
// CHECK-SAME: #[[ATTRS:[0-9]+]]
llvm.func @approx_func_fp_math_func_true() attributes {approx_func_fp_math = true} {
llvm.return
}
// CHECK: attributes #[[ATTRS]] = { "approx-func-fp-math"="true" }

// -----
//
// CHECK-LABEL: define void @approx_func_fp_math_func_false()
// CHECK-SAME: #[[ATTRS:[0-9]+]]
llvm.func @approx_func_fp_math_func_false() attributes {approx_func_fp_math = false} {
llvm.return
}
// CHECK: attributes #[[ATTRS]] = { "approx-func-fp-math"="false" }

// -----

// CHECK-LABEL: define void @no_signed_zeros_fp_math_func_true()
// CHECK-SAME: #[[ATTRS:[0-9]+]]
llvm.func @no_signed_zeros_fp_math_func_true() attributes {no_signed_zeros_fp_math = true} {
llvm.return
}
// CHECK: attributes #[[ATTRS]] = { "no-signed-zeros-fp-math"="true" }

// -----

// CHECK-LABEL: define void @no_signed_zeros_fp_math_func_false()
// CHECK-SAME: #[[ATTRS:[0-9]+]]
llvm.func @no_signed_zeros_fp_math_func_false() attributes {no_signed_zeros_fp_math = false} {
llvm.return
}
// CHECK: attributes #[[ATTRS]] = { "no-signed-zeros-fp-math"="false" }

0 comments on commit 748c295

Please sign in to comment.