This revision adds support to import fastmath flags from LLVMIR. It implement the import using a listener attached to the builder. The listener gets notified if an operation is created and then checks if there are fastmath flags to import from LLVM IR to the MLIR. The listener based approach allows us to perform the import without changing the mlirBuilders used to create the imported operations. An alternative solution, could be to update the builders so that they return the created operation using FailureOr<Operation*> instead of LogicalResult. However, this solution implies an LLVM IR instruction always maps to exatly one MLIR operation. While mostly true, there are already exceptions to this such as the PHI instruciton. Additionally, an mlirBuilder based solution also further complicates the builder implementations, which led to the listener based solution. Depends on D139405 Reviewed By: ftynse Differential Revision: https://reviews.llvm.org/D139620
57 lines
2.2 KiB
LLVM
57 lines
2.2 KiB
LLVM
; RUN: mlir-translate -import-llvm -split-input-file %s | FileCheck %s
|
|
|
|
; CHECK-LABEL: @fastmath_inst
|
|
define void @fastmath_inst(float %arg1, float %arg2) {
|
|
; CHECK: llvm.fadd %{{.*}}, %{{.*}} {fastmathFlags = #llvm.fastmath<nnan, ninf>} : f32
|
|
%1 = fadd nnan ninf float %arg1, %arg2
|
|
; CHECK: llvm.fsub %{{.*}}, %{{.*}} {fastmathFlags = #llvm.fastmath<nsz>} : f32
|
|
%2 = fsub nsz float %arg1, %arg2
|
|
; CHECK: llvm.fmul %{{.*}}, %{{.*}} {fastmathFlags = #llvm.fastmath<arcp, contract>} : f32
|
|
%3 = fmul arcp contract float %arg1, %arg2
|
|
; CHECK: llvm.fdiv %{{.*}}, %{{.*}} {fastmathFlags = #llvm.fastmath<afn, reassoc>} : f32
|
|
%4 = fdiv afn reassoc float %arg1, %arg2
|
|
; CHECK: llvm.fneg %{{.*}} {fastmathFlags = #llvm.fastmath<fast>} : f32
|
|
%5 = fneg fast float %arg1
|
|
ret void
|
|
}
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @fastmath_fcmp
|
|
define void @fastmath_fcmp(float %arg1, float %arg2) {
|
|
; CHECK: llvm.fcmp "oge" %{{.*}}, %{{.*}} {fastmathFlags = #llvm.fastmath<nsz>} : f32
|
|
%1 = fcmp nsz oge float %arg1, %arg2
|
|
ret void
|
|
}
|
|
|
|
; // -----
|
|
|
|
declare float @fn(float)
|
|
|
|
; CHECK-LABEL: @fastmath_call
|
|
define void @fastmath_call(float %arg1) {
|
|
; CHECK: llvm.call @fn(%{{.*}}) {fastmathFlags = #llvm.fastmath<ninf>} : (f32) -> f32
|
|
%1 = call ninf float @fn(float %arg1)
|
|
ret void
|
|
}
|
|
|
|
; // -----
|
|
|
|
declare float @llvm.exp.f32(float)
|
|
declare float @llvm.powi.f32.i32(float, i32)
|
|
declare float @llvm.pow.f32(float, float)
|
|
declare float @llvm.fmuladd.f32(float, float, float)
|
|
|
|
; CHECK-LABEL: @fastmath_intr
|
|
define void @fastmath_intr(float %arg1, i32 %arg2) {
|
|
; CHECK: llvm.intr.exp(%{{.*}}) {fastmathFlags = #llvm.fastmath<nnan, ninf>} : (f32) -> f32
|
|
%1 = call nnan ninf float @llvm.exp.f32(float %arg1)
|
|
; CHECK: llvm.intr.powi(%{{.*}}, %{{.*}}) {fastmathFlags = #llvm.fastmath<fast>} : (f32, i32) -> f32
|
|
%2 = call fast float @llvm.powi.f32.i32(float %arg1, i32 %arg2)
|
|
; CHECK: llvm.intr.pow(%{{.*}}, %{{.*}}) {fastmathFlags = #llvm.fastmath<fast>} : (f32, f32) -> f32
|
|
%3 = call fast float @llvm.pow.f32(float %arg1, float %arg1)
|
|
; CHECK: llvm.intr.fmuladd(%{{.*}}, %{{.*}}, %{{.*}}) {fastmathFlags = #llvm.fastmath<fast>} : (f32, f32, f32) -> f32
|
|
%4 = call fast float @llvm.fmuladd.f32(float %arg1, float %arg1, float %arg1)
|
|
ret void
|
|
}
|