Skip to content

Commit

Permalink
[flang] Use libm functions for complex operations by default
Browse files Browse the repository at this point in the history
This patch changes the default lowering for complex operations to use
the more accurate libm operations as opposed to the mlir complex
operations. This is necessary due to precision issues in the mlir
complex dialect that cause failures in e.g. the LAPACK tests.

The mlir complex dialect lowering will still be used when
`-fapprox-func` is set (and by extension `-ffast-math` and `-Ofast`)

Differential Revision: https://reviews.llvm.org/D155310
  • Loading branch information
DavidTruby committed Jul 19, 2023
1 parent 6cf8bde commit 3681a7d
Show file tree
Hide file tree
Showing 9 changed files with 34 additions and 30 deletions.
8 changes: 5 additions & 3 deletions flang/lib/Optimizer/Builder/IntrinsicCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -733,8 +733,9 @@ mlir::Value genComplexMathOp(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::FunctionType mathLibFuncType,
llvm::ArrayRef<mlir::Value> args) {
mlir::Value result;
if (disableMlirComplex ||
(mathRuntimeVersion == preciseVersion && !mathLibFuncName.empty())) {
bool hasApproxFunc = mlir::arith::bitEnumContainsAny(
builder.getFastMathFlags(), mlir::arith::FastMathFlags::afn);
if ((disableMlirComplex || !hasApproxFunc) && !mathLibFuncName.empty()) {
result = genLibCall(builder, loc, mathLibFuncName, mathLibFuncType, args);
LLVM_DEBUG(result.dump(); llvm::dbgs() << "\n");
return result;
Expand Down Expand Up @@ -1204,8 +1205,9 @@ searchMathOperation(fir::FirOpBuilder &builder, llvm::StringRef name,
for (auto iter = range.first; iter != range.second && iter; ++iter) {
const auto &impl = *iter;
auto implType = impl.typeGenerator(builder.getContext(), builder);
if (funcType == implType)
if (funcType == implType) {
return &impl; // exact match
}

FunctionDistance distance(funcType, implType);
if (distance.isSmallerThan(bestMatchDistance)) {
Expand Down
6 changes: 2 additions & 4 deletions flang/test/Lower/HLFIR/binary-ops.f90
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,8 @@ subroutine complex_power(x, y, z)
! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<!fir.complex<4>>
! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<!fir.complex<4>>
! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_6]] : (!fir.complex<4>) -> complex<f32>
! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_7]] : (!fir.complex<4>) -> complex<f32>
! CHECK: %[[VAL_10:.*]] = complex.pow %[[VAL_8]], %[[VAL_9]] : complex<f32>
! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (complex<f32>) -> !fir.complex<4>
! CHECK: %[[VAL_8:.*]] = fir.call @cpowf(%[[VAL_6]], %[[VAL_7]]) fastmath<contract> : (!fir.complex<4>, !fir.complex<4>) -> !fir.complex<4>


subroutine real_to_int_power(x, y, z)
real :: x, y
Expand Down
5 changes: 3 additions & 2 deletions flang/test/Lower/Intrinsics/abs.f90
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
! RUN: bbc -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-FAST"
! RUN: bbc -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-PRECISE"
! RUN: bbc -emit-fir --math-runtime=precise %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
! RUN: bbc --disable-mlir-complex -emit-fir %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-FAST"
! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-PRECISE"
! RUN: %flang_fc1 -emit-fir -mllvm --math-runtime=precise %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
! RUN: %flang_fc1 -emit-fir -mllvm --disable-mlir-complex %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
! RUN: %flang_fc1 -fapprox-func -emit-fir %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-FAST"

! Test abs intrinsic for various types (int, float, complex)

Expand Down
11 changes: 7 additions & 4 deletions flang/test/Lower/Intrinsics/exp.f90
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-FAST"
! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-PRECISE"
! RUN: bbc -emit-fir --math-runtime=precise -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
! RUN: bbc -emit-fir --disable-mlir-complex -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-FAST"
! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-PRECISE"
! RUN: %flang_fc1 -fapprox-func -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-FAST"
! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics -mllvm --math-runtime=precise %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics -mllvm --disable-mlir-complex %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"

Expand Down Expand Up @@ -55,15 +56,17 @@ subroutine exp_testcd(a, b)
! CHECK: %[[RESULT64_OUTLINE:.*]] = math.exp %[[ARG64_OUTLINE]] fastmath<contract> : f64
! CHECK: return %[[RESULT64_OUTLINE]] : f64

! CMPLX-LABEL: private @fir.exp.contract.z4.z4
! CMPLX-FAST-LABEL: private @fir.exp.contract_afn.z4.z4
! CMPLX-PRECISE-LABEL: private @fir.exp.contract.z4.z4
! CMPLX-SAME: (%[[ARG32_OUTLINE:.*]]: !fir.complex<4>) -> !fir.complex<4>
! CMPLX-FAST: %[[C:.*]] = fir.convert %[[ARG32_OUTLINE]] : (!fir.complex<4>) -> complex<f32>
! CMPLX-FAST: %[[E:.*]] = complex.exp %[[C]] : complex<f32>
! CMPLX-FAST: %[[RESULT32_OUTLINE:.*]] = fir.convert %[[E]] : (complex<f32>) -> !fir.complex<4>
! CMPLX-PRECISE: %[[RESULT32_OUTLINE:.*]] = fir.call @cexpf(%[[ARG32_OUTLINE]]) fastmath<contract> : (!fir.complex<4>) -> !fir.complex<4>
! CMPLX: return %[[RESULT32_OUTLINE]] : !fir.complex<4>

! CMPLX-LABEL: private @fir.exp.contract.z8.z8
! CMPLX-FAST-LABEL: private @fir.exp.contract_afn.z8.z8
! CMPLX-PRECISE-LABEL: private @fir.exp.contract.z8.z8
! CMPLX-SAME: (%[[ARG64_OUTLINE:.*]]: !fir.complex<8>) -> !fir.complex<8>
! CMPLX-FAST: %[[C:.*]] = fir.convert %[[ARG64_OUTLINE]] : (!fir.complex<8>) -> complex<f64>
! CMPLX-FAST: %[[E:.*]] = complex.exp %[[C]] : complex<f64>
Expand Down
11 changes: 7 additions & 4 deletions flang/test/Lower/Intrinsics/log.f90
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-FAST"
! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-PRECISE"
! RUN: bbc -emit-fir --math-runtime=precise -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
! RUN: bbc -emit-fir --disable-mlir-complex -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-FAST"
! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-PRECISE"
! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics -mllvm --math-runtime=precise %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics -mllvm --disable-mlir-complex %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
! RUN: %flang_fc1 -fapprox-func -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-FAST"

! CHECK-LABEL: log_testr
! CHECK-SAME: (%[[AREF:.*]]: !fir.ref<f32> {{.*}}, %[[BREF:.*]]: !fir.ref<f32> {{.*}})
Expand Down Expand Up @@ -75,15 +76,17 @@ subroutine log10_testd(a, b)
! CHECK: %[[RESULT64_OUTLINE:.*]] = math.log %[[ARG64_OUTLINE]] fastmath<contract> : f64
! CHECK: return %[[RESULT64_OUTLINE]] : f64

! CMPLX-LABEL: private @fir.log.contract.z4.z4
! CMPLX-FAST-LABEL: private @fir.log.contract_afn.z4.z4
! CMPLX-PRECISE-LABEL: private @fir.log.contract.z4.z4
! CMPLX-SAME: (%[[ARG32_OUTLINE:.*]]: !fir.complex<4>) -> !fir.complex<4>
! CMPLX-FAST: %[[C:.*]] = fir.convert %[[ARG32_OUTLINE]] : (!fir.complex<4>) -> complex<f32>
! CMPLX-FAST: %[[E:.*]] = complex.log %[[C]] : complex<f32>
! CMPLX-FAST: %[[RESULT32_OUTLINE:.*]] = fir.convert %[[E]] : (complex<f32>) -> !fir.complex<4>
! CMPLX-PRECISE: %[[RESULT32_OUTLINE:.*]] = fir.call @clogf(%[[ARG32_OUTLINE]]) fastmath<contract> : (!fir.complex<4>) -> !fir.complex<4>
! CMPLX: return %[[RESULT32_OUTLINE]] : !fir.complex<4>

! CMPLX-LABEL: private @fir.log.contract.z8.z8
! CMPLX-FAST-LABEL: private @fir.log.contract_afn.z8.z8
! CMPLX-PRECISE-LABEL: private @fir.log.contract.z8.z8
! CMPLX-SAME: (%[[ARG64_OUTLINE:.*]]: !fir.complex<8>) -> !fir.complex<8>
! CMPLX-FAST: %[[C:.*]] = fir.convert %[[ARG64_OUTLINE]] : (!fir.complex<8>) -> complex<f64>
! CMPLX-FAST: %[[E:.*]] = complex.log %[[C]] : complex<f64>
Expand Down
10 changes: 2 additions & 8 deletions flang/test/Lower/math-lowering.f90
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,15 @@ function test_complex4(c)
complex(4) :: c, test_complex4
test_complex4 = abs(c)
end function

! ALL-LABEL: @_QPtest_complex4
! FAST: {{%[A-Za-z0-9._]+}} = complex.abs {{%[A-Za-z0-9._]+}} : complex<f32>
! RELAXED: {{%[A-Za-z0-9._]+}} = complex.abs {{%[A-Za-z0-9._]+}} : complex<f32>
! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @cabsf({{%[A-Za-z0-9._]+}}) {{.*}}: (!fir.complex<4>) -> f32
! ALL: {{%[A-Za-z0-9._]+}} = fir.call @cabsf({{%[A-Za-z0-9._]+}}) {{.*}}: (!fir.complex<4>) -> f32

function test_complex8(c)
complex(8) :: c, test_complex8
test_complex8 = abs(c)
end function

! ALL-LABEL: @_QPtest_complex8
! FAST: {{%[A-Za-z0-9._]+}} = complex.abs {{%[A-Za-z0-9._]+}} : complex<f64>
! RELAXED: {{%[A-Za-z0-9._]+}} = complex.abs {{%[A-Za-z0-9._]+}} : complex<f64>
! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @cabs({{%[A-Za-z0-9._]+}}) {{.*}}: (!fir.complex<8>) -> f64
! ALL: {{%[A-Za-z0-9._]+}} = fir.call @cabs({{%[A-Za-z0-9._]+}}) {{.*}}: (!fir.complex<8>) -> f64

! PRECISE-DAG: func.func private @fabsf(f32) -> f32 attributes {fir.bindc_name = "fabsf", fir.runtime}
! PRECISE-DAG: func.func private @fabs(f64) -> f64 attributes {fir.bindc_name = "fabs", fir.runtime}
Expand Down
5 changes: 3 additions & 2 deletions flang/test/Lower/power-operator.f90
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
! RUN: bbc -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,FAST"
! RUN: bbc -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,PRECISE"
! RUN: bbc --math-runtime=precise -emit-fir %s -o - | FileCheck %s --check-prefixes="PRECISE"
! RUN: bbc --disable-mlir-complex -emit-fir %s -o - | FileCheck %s --check-prefixes="PRECISE"
! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,FAST"
! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,PRECISE"
! RUN: %flang_fc1 -fapprox-func -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,FAST"
! RUN: %flang_fc1 -emit-fir -mllvm --math-runtime=precise %s -o - | FileCheck %s --check-prefixes="PRECISE"
! RUN: %flang_fc1 -emit-fir -mllvm --disable-mlir-complex %s -o - | FileCheck %s --check-prefixes="PRECISE"

Expand Down
5 changes: 3 additions & 2 deletions flang/test/Lower/sqrt.f90
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX-FAST"
! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX-PRECISE"
! RUN: bbc --math-runtime=precise -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX-PRECISE"
! RUN: bbc --disable-mlir-complex -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX-PRECISE"
! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX-FAST"
! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX-PRECISE"
! RUN: %flang_fc1 -fapprox-func -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX-FAST"
! RUN: %flang_fc1 -emit-fir -mllvm --math-runtime=precise -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX-PRECISE"
! RUN: %flang_fc1 -emit-fir -mllvm --disable-mlir-complex -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX-PRECISE"

Expand Down
3 changes: 2 additions & 1 deletion flang/test/Lower/trigonometric-intrinsics.f90
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX-FAST"
! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX-PRECISE"
! RUN: bbc --math-runtime=precise -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX-PRECISE"
! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s
! RUN: %flang_fc1 -fapprox-func -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX-FAST"

! CHECK-LABEL: tan_testr
subroutine tan_testr(a, b)
Expand Down

0 comments on commit 3681a7d

Please sign in to comment.