[flang] Lower power to HLFIR

Differential Revision: https://reviews.llvm.org/D139117
This commit is contained in:
Jean Perier 2022-12-01 17:49:29 +01:00
parent 440e9baa62
commit 89af7de9de
2 changed files with 87 additions and 0 deletions

View File

@ -17,6 +17,7 @@
#include "flang/Lower/ConvertCall.h" #include "flang/Lower/ConvertCall.h"
#include "flang/Lower/ConvertConstant.h" #include "flang/Lower/ConvertConstant.h"
#include "flang/Lower/ConvertType.h" #include "flang/Lower/ConvertType.h"
#include "flang/Lower/IntrinsicCall.h"
#include "flang/Lower/StatementContext.h" #include "flang/Lower/StatementContext.h"
#include "flang/Lower/SymbolMap.h" #include "flang/Lower/SymbolMap.h"
#include "flang/Optimizer/Builder/Todo.h" #include "flang/Optimizer/Builder/Todo.h"
@ -284,6 +285,31 @@ GENBIN(Divide, Integer, mlir::arith::DivSIOp)
GENBIN(Divide, Real, mlir::arith::DivFOp) GENBIN(Divide, Real, mlir::arith::DivFOp)
GENBIN(Divide, Complex, fir::DivcOp) GENBIN(Divide, Complex, fir::DivcOp)
template <Fortran::common::TypeCategory TC, int KIND>
struct BinaryOp<Fortran::evaluate::Power<Fortran::evaluate::Type<TC, KIND>>> {
static hlfir::EntityWithAttributes gen(mlir::Location loc,
fir::FirOpBuilder &builder,
hlfir::Entity lhs, hlfir::Entity rhs) {
mlir::Type ty = Fortran::lower::getFIRType(builder.getContext(), TC, KIND,
/*params=*/llvm::None);
return hlfir::EntityWithAttributes{
Fortran::lower::genPow(builder, loc, ty, lhs, rhs)};
}
};
template <Fortran::common::TypeCategory TC, int KIND>
struct BinaryOp<
Fortran::evaluate::RealToIntPower<Fortran::evaluate::Type<TC, KIND>>> {
static hlfir::EntityWithAttributes gen(mlir::Location loc,
fir::FirOpBuilder &builder,
hlfir::Entity lhs, hlfir::Entity rhs) {
mlir::Type ty = Fortran::lower::getFIRType(builder.getContext(), TC, KIND,
/*params=*/llvm::None);
return hlfir::EntityWithAttributes{
Fortran::lower::genPow(builder, loc, ty, lhs, rhs)};
}
};
/// Lower Expr to HLFIR. /// Lower Expr to HLFIR.
class HlfirBuilder { class HlfirBuilder {
public: public:

View File

@ -132,3 +132,64 @@ end subroutine
! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !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_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<!fir.complex<4>>
! CHECK: %[[VAL_8:.*]] = fir.divc %[[VAL_6]], %[[VAL_7]] : !fir.complex<4> ! CHECK: %[[VAL_8:.*]] = fir.divc %[[VAL_6]], %[[VAL_7]] : !fir.complex<4>
subroutine int_power(x, y, z)
integer :: x, y, z
x = y**z
end subroutine
! CHECK-LABEL: func.func @_QPint_power(
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}}y"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<i32>
! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<i32>
! CHECK: %[[VAL_8:.*]] = math.ipowi %[[VAL_6]], %[[VAL_7]] : i32
subroutine real_power(x, y, z)
real :: x, y, z
x = y**z
end subroutine
! CHECK-LABEL: func.func @_QPreal_power(
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}}y"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<f32>
! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<f32>
! CHECK: %[[VAL_8:.*]] = math.powf %[[VAL_6]], %[[VAL_7]] fastmath<contract> : f32
subroutine complex_power(x, y, z)
complex :: x, y, z
x = y**z
end subroutine
! CHECK-LABEL: func.func @_QPcomplex_power(
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}}y"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
! 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>
subroutine real_to_int_power(x, y, z)
real :: x, y
integer :: z
x = y**z
end subroutine
! CHECK-LABEL: func.func @_QPreal_to_int_power(
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}}y"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<f32>
! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<i32>
! CHECK: %[[VAL_8:.*]] = fir.call @llvm.powi.f32.i32(%[[VAL_6]], %[[VAL_7]]) fastmath<contract> : (f32, i32) -> f32
subroutine complex_to_int_power(x, y, z)
complex :: x, y
integer :: z
x = y**z
end subroutine
! CHECK-LABEL: func.func @_QPcomplex_to_int_power(
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}}y"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<!fir.complex<4>>
! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<i32>
! CHECK: %[[VAL_8:.*]] = fir.call @_FortranAcpowi(%[[VAL_6]], %[[VAL_7]]) fastmath<contract> : (!fir.complex<4>, i32) -> !fir.complex<4>