Skip to content

Commit 748c295

Browse files
authored
[MLIR][LLVM] Add fast-math related function attribute support (llvm#79812)
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.
1 parent 8774d29 commit 748c295

File tree

6 files changed

+228
-1
lines changed

6 files changed

+228
-1
lines changed

mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1428,7 +1428,12 @@ def LLVM_LLVMFuncOp : LLVM_Op<"func", [
14281428
OptionalAttr<LLVM_VScaleRangeAttr>:$vscale_range,
14291429
OptionalAttr<FramePointerKindAttr>:$frame_pointer,
14301430
OptionalAttr<StrAttr>:$target_cpu,
1431-
OptionalAttr<LLVM_TargetFeaturesAttr>:$target_features
1431+
OptionalAttr<LLVM_TargetFeaturesAttr>:$target_features,
1432+
OptionalAttr<BoolAttr>:$unsafe_fp_math,
1433+
OptionalAttr<BoolAttr>:$no_infs_fp_math,
1434+
OptionalAttr<BoolAttr>:$no_nans_fp_math,
1435+
OptionalAttr<BoolAttr>:$approx_func_fp_math,
1436+
OptionalAttr<BoolAttr>:$no_signed_zeros_fp_math
14321437
);
14331438

14341439
let regions = (region AnyRegion:$body);

mlir/lib/Target/LLVMIR/ModuleImport.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1646,6 +1646,11 @@ static constexpr std::array ExplicitAttributes{
16461646
StringLiteral("vscale_range"),
16471647
StringLiteral("frame-pointer"),
16481648
StringLiteral("target-features"),
1649+
StringLiteral("unsafe-fp-math"),
1650+
StringLiteral("no-infs-fp-math"),
1651+
StringLiteral("no-nans-fp-math"),
1652+
StringLiteral("approx-func-fp-math"),
1653+
StringLiteral("no-signed-zeros-fp-math"),
16491654
};
16501655

16511656
static void processPassthroughAttrs(llvm::Function *func, LLVMFuncOp funcOp) {
@@ -1752,6 +1757,26 @@ void ModuleImport::processFunctionAttributes(llvm::Function *func,
17521757
attr.isStringAttribute())
17531758
funcOp.setTargetFeaturesAttr(
17541759
LLVM::TargetFeaturesAttr::get(context, attr.getValueAsString()));
1760+
1761+
if (llvm::Attribute attr = func->getFnAttribute("unsafe-fp-math");
1762+
attr.isStringAttribute())
1763+
funcOp.setUnsafeFpMath(attr.getValueAsBool());
1764+
1765+
if (llvm::Attribute attr = func->getFnAttribute("no-infs-fp-math");
1766+
attr.isStringAttribute())
1767+
funcOp.setNoInfsFpMath(attr.getValueAsBool());
1768+
1769+
if (llvm::Attribute attr = func->getFnAttribute("no-nans-fp-math");
1770+
attr.isStringAttribute())
1771+
funcOp.setNoNansFpMath(attr.getValueAsBool());
1772+
1773+
if (llvm::Attribute attr = func->getFnAttribute("approx-func-fp-math");
1774+
attr.isStringAttribute())
1775+
funcOp.setApproxFuncFpMath(attr.getValueAsBool());
1776+
1777+
if (llvm::Attribute attr = func->getFnAttribute("no-signed-zeros-fp-math");
1778+
attr.isStringAttribute())
1779+
funcOp.setNoSignedZerosFpMath(attr.getValueAsBool());
17551780
}
17561781

17571782
DictionaryAttr

mlir/lib/Target/LLVMIR/ModuleTranslation.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737

3838
#include "llvm/ADT/PostOrderIterator.h"
3939
#include "llvm/ADT/SetVector.h"
40+
#include "llvm/ADT/StringExtras.h"
4041
#include "llvm/ADT/TypeSwitch.h"
4142
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
4243
#include "llvm/IR/BasicBlock.h"
@@ -1214,6 +1215,23 @@ LogicalResult ModuleTranslation::convertOneFunction(LLVMFuncOp func) {
12141215
getLLVMContext(), attr->getMinRange().getInt(),
12151216
attr->getMaxRange().getInt()));
12161217

1218+
if (auto unsafeFpMath = func.getUnsafeFpMath())
1219+
llvmFunc->addFnAttr("unsafe-fp-math", llvm::toStringRef(*unsafeFpMath));
1220+
1221+
if (auto noInfsFpMath = func.getNoInfsFpMath())
1222+
llvmFunc->addFnAttr("no-infs-fp-math", llvm::toStringRef(*noInfsFpMath));
1223+
1224+
if (auto noNansFpMath = func.getNoNansFpMath())
1225+
llvmFunc->addFnAttr("no-nans-fp-math", llvm::toStringRef(*noNansFpMath));
1226+
1227+
if (auto approxFuncFpMath = func.getApproxFuncFpMath())
1228+
llvmFunc->addFnAttr("approx-func-fp-math",
1229+
llvm::toStringRef(*approxFuncFpMath));
1230+
1231+
if (auto noSignedZerosFpMath = func.getNoSignedZerosFpMath())
1232+
llvmFunc->addFnAttr("no-signed-zeros-fp-math",
1233+
llvm::toStringRef(*noSignedZerosFpMath));
1234+
12171235
// Add function attribute frame-pointer, if found.
12181236
if (FramePointerKindAttr attr = func.getFramePointerAttr())
12191237
llvmFunc->addFnAttr("frame-pointer",

mlir/test/Dialect/LLVMIR/func.mlir

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,36 @@ module {
257257
llvm.func @frame_pointer_roundtrip() attributes {frame_pointer = #llvm.framePointerKind<"non-leaf">} {
258258
llvm.return
259259
}
260+
261+
llvm.func @unsafe_fp_math_roundtrip() attributes {unsafe_fp_math = true} {
262+
// CHECK: @unsafe_fp_math_roundtrip
263+
// CHECK-SAME: attributes {unsafe_fp_math = true}
264+
llvm.return
265+
}
266+
267+
llvm.func @no_infs_fp_math_roundtrip() attributes {no_infs_fp_math = true} {
268+
// CHECK: @no_infs_fp_math_roundtrip
269+
// CHECK-SAME: attributes {no_infs_fp_math = true}
270+
llvm.return
271+
}
272+
273+
llvm.func @no_nans_fp_math_roundtrip() attributes {no_nans_fp_math = true} {
274+
// CHECK: @no_nans_fp_math_roundtrip
275+
// CHECK-SAME: attributes {no_nans_fp_math = true}
276+
llvm.return
277+
}
278+
279+
llvm.func @approx_func_fp_math_roundtrip() attributes {approx_func_fp_math = true} {
280+
// CHECK: @approx_func_fp_math_roundtrip
281+
// CHECK-SAME: attributes {approx_func_fp_math = true}
282+
llvm.return
283+
}
284+
285+
llvm.func @no_signed_zeros_fp_math_roundtrip() attributes {no_signed_zeros_fp_math = true} {
286+
// CHECK: @no_signed_zeros_fp_math_roundtrip
287+
// CHECK-SAME: attributes {no_signed_zeros_fp_math = true}
288+
llvm.return
289+
}
260290
}
261291

262292
// -----

mlir/test/Target/LLVMIR/Import/function-attributes.ll

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,3 +272,63 @@ define void @align_func() align 2 {
272272
; CHECK-LABEL: @align_decl
273273
; CHECK-SAME: attributes {alignment = 64 : i64}
274274
declare void @align_decl() align 64
275+
276+
; // -----
277+
278+
; CHECK-LABEL: @func_attr_unsafe_fp_math_true
279+
; CHECK-SAME: attributes {unsafe_fp_math = true}
280+
declare void @func_attr_unsafe_fp_math_true() "unsafe-fp-math"="true"
281+
282+
; // -----
283+
284+
; CHECK-LABEL: @func_attr_unsafe_fp_math_false
285+
; CHECK-SAME: attributes {unsafe_fp_math = false}
286+
declare void @func_attr_unsafe_fp_math_false() "unsafe-fp-math"="false"
287+
288+
; // -----
289+
290+
; CHECK-LABEL: @func_attr_no_infs_fp_math_true
291+
; CHECK-SAME: attributes {no_infs_fp_math = true}
292+
declare void @func_attr_no_infs_fp_math_true() "no-infs-fp-math"="true"
293+
294+
; // -----
295+
296+
; CHECK-LABEL: @func_attr_no_infs_fp_math_false
297+
; CHECK-SAME: attributes {no_infs_fp_math = false}
298+
declare void @func_attr_no_infs_fp_math_false() "no-infs-fp-math"="false"
299+
300+
; // -----
301+
302+
; CHECK-LABEL: @func_attr_no_nans_fp_math_true
303+
; CHECK-SAME: attributes {no_nans_fp_math = true}
304+
declare void @func_attr_no_nans_fp_math_true() "no-nans-fp-math"="true"
305+
306+
; // -----
307+
308+
; CHECK-LABEL: @func_attr_no_nans_fp_math_false
309+
; CHECK-SAME: attributes {no_nans_fp_math = false}
310+
declare void @func_attr_no_nans_fp_math_false() "no-nans-fp-math"="false"
311+
312+
; // -----
313+
314+
; CHECK-LABEL: @func_attr_approx_func_fp_math_true
315+
; CHECK-SAME: attributes {approx_func_fp_math = true}
316+
declare void @func_attr_approx_func_fp_math_true() "approx-func-fp-math"="true"
317+
318+
; // -----
319+
320+
; CHECK-LABEL: @func_attr_approx_func_fp_math_false
321+
; CHECK-SAME: attributes {approx_func_fp_math = false}
322+
declare void @func_attr_approx_func_fp_math_false() "approx-func-fp-math"="false"
323+
324+
; // -----
325+
326+
; CHECK-LABEL: @func_attr_no_signed_zeros_fp_math_true
327+
; CHECK-SAME: attributes {no_signed_zeros_fp_math = true}
328+
declare void @func_attr_no_signed_zeros_fp_math_true() "no-signed-zeros-fp-math"="true"
329+
330+
; // -----
331+
332+
; CHECK-LABEL: @func_attr_no_signed_zeros_fp_math_false
333+
; CHECK-SAME: attributes {no_signed_zeros_fp_math = false}
334+
declare void @func_attr_no_signed_zeros_fp_math_false() "no-signed-zeros-fp-math"="false"
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// RUN: mlir-translate -mlir-to-llvmir -split-input-file %s | FileCheck %s
2+
3+
// CHECK-LABEL: define void @unsafe_fp_math_func_true()
4+
// CHECK-SAME: #[[ATTRS:[0-9]+]]
5+
llvm.func @unsafe_fp_math_func_true() attributes {unsafe_fp_math = true} {
6+
llvm.return
7+
}
8+
// CHECK: attributes #[[ATTRS]] = { "unsafe-fp-math"="true" }
9+
10+
// -----
11+
12+
// CHECK-LABEL: define void @unsafe_fp_math_func_false()
13+
// CHECK-SAME: #[[ATTRS:[0-9]+]]
14+
llvm.func @unsafe_fp_math_func_false() attributes {unsafe_fp_math = false} {
15+
llvm.return
16+
}
17+
// CHECK: attributes #[[ATTRS]] = { "unsafe-fp-math"="false" }
18+
19+
// -----
20+
21+
// CHECK-LABEL: define void @no_infs_fp_math_func_true()
22+
// CHECK-SAME: #[[ATTRS:[0-9]+]]
23+
llvm.func @no_infs_fp_math_func_true() attributes {no_infs_fp_math = true} {
24+
llvm.return
25+
}
26+
// CHECK: attributes #[[ATTRS]] = { "no-infs-fp-math"="true" }
27+
28+
// -----
29+
30+
// CHECK-LABEL: define void @no_infs_fp_math_func_false()
31+
// CHECK-SAME: #[[ATTRS:[0-9]+]]
32+
llvm.func @no_infs_fp_math_func_false() attributes {no_infs_fp_math = false} {
33+
llvm.return
34+
}
35+
// CHECK: attributes #[[ATTRS]] = { "no-infs-fp-math"="false" }
36+
37+
// -----
38+
39+
// CHECK-LABEL: define void @no_nans_fp_math_func_true()
40+
// CHECK-SAME: #[[ATTRS:[0-9]+]]
41+
llvm.func @no_nans_fp_math_func_true() attributes {no_nans_fp_math = true} {
42+
llvm.return
43+
}
44+
// CHECK: attributes #[[ATTRS]] = { "no-nans-fp-math"="true" }
45+
46+
// -----
47+
48+
// CHECK-LABEL: define void @no_nans_fp_math_func_false()
49+
// CHECK-SAME: #[[ATTRS:[0-9]+]]
50+
llvm.func @no_nans_fp_math_func_false() attributes {no_nans_fp_math = false} {
51+
llvm.return
52+
}
53+
// CHECK: attributes #[[ATTRS]] = { "no-nans-fp-math"="false" }
54+
55+
// -----
56+
57+
// CHECK-LABEL: define void @approx_func_fp_math_func_true()
58+
// CHECK-SAME: #[[ATTRS:[0-9]+]]
59+
llvm.func @approx_func_fp_math_func_true() attributes {approx_func_fp_math = true} {
60+
llvm.return
61+
}
62+
// CHECK: attributes #[[ATTRS]] = { "approx-func-fp-math"="true" }
63+
64+
// -----
65+
//
66+
// CHECK-LABEL: define void @approx_func_fp_math_func_false()
67+
// CHECK-SAME: #[[ATTRS:[0-9]+]]
68+
llvm.func @approx_func_fp_math_func_false() attributes {approx_func_fp_math = false} {
69+
llvm.return
70+
}
71+
// CHECK: attributes #[[ATTRS]] = { "approx-func-fp-math"="false" }
72+
73+
// -----
74+
75+
// CHECK-LABEL: define void @no_signed_zeros_fp_math_func_true()
76+
// CHECK-SAME: #[[ATTRS:[0-9]+]]
77+
llvm.func @no_signed_zeros_fp_math_func_true() attributes {no_signed_zeros_fp_math = true} {
78+
llvm.return
79+
}
80+
// CHECK: attributes #[[ATTRS]] = { "no-signed-zeros-fp-math"="true" }
81+
82+
// -----
83+
84+
// CHECK-LABEL: define void @no_signed_zeros_fp_math_func_false()
85+
// CHECK-SAME: #[[ATTRS:[0-9]+]]
86+
llvm.func @no_signed_zeros_fp_math_func_false() attributes {no_signed_zeros_fp_math = false} {
87+
llvm.return
88+
}
89+
// CHECK: attributes #[[ATTRS]] = { "no-signed-zeros-fp-math"="false" }

0 commit comments

Comments
 (0)