diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp --- a/flang/lib/Lower/ConvertExprToHLFIR.cpp +++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp @@ -457,6 +457,36 @@ } }; +template +struct BinaryOp> { + using Op = Fortran::evaluate::LogicalOperation; + static hlfir::EntityWithAttributes gen(mlir::Location loc, + fir::FirOpBuilder &builder, + const Op &op, hlfir::Entity lhs, + hlfir::Entity rhs) { + mlir::Type i1Type = builder.getI1Type(); + mlir::Value i1Lhs = builder.createConvert(loc, i1Type, lhs); + mlir::Value i1Rhs = builder.createConvert(loc, i1Type, rhs); + switch (op.logicalOperator) { + case Fortran::evaluate::LogicalOperator::And: + return hlfir::EntityWithAttributes{ + builder.create(loc, i1Lhs, i1Rhs)}; + case Fortran::evaluate::LogicalOperator::Or: + return hlfir::EntityWithAttributes{ + builder.create(loc, i1Lhs, i1Rhs)}; + case Fortran::evaluate::LogicalOperator::Eqv: + return hlfir::EntityWithAttributes{builder.create( + loc, mlir::arith::CmpIPredicate::eq, i1Lhs, i1Rhs)}; + case Fortran::evaluate::LogicalOperator::Neqv: + return hlfir::EntityWithAttributes{builder.create( + loc, mlir::arith::CmpIPredicate::ne, i1Lhs, i1Rhs)}; + case Fortran::evaluate::LogicalOperator::Not: + // lib/evaluate expression for .NOT. is Fortran::evaluate::Not. + llvm_unreachable(".NOT. is not a binary operator"); + } + } +}; + /// Lower Expr to HLFIR. class HlfirBuilder { public: diff --git a/flang/test/Lower/HLFIR/binary-ops.f90 b/flang/test/Lower/HLFIR/binary-ops.f90 --- a/flang/test/Lower/HLFIR/binary-ops.f90 +++ b/flang/test/Lower/HLFIR/binary-ops.f90 @@ -289,3 +289,37 @@ ! CHECK: %[[VAL_12:.*]] = fir.call @_FortranACharacterCompareScalar1(%[[VAL_8]], %[[VAL_9]], %[[VAL_10]], %[[VAL_11]]) fastmath : (!fir.ref, !fir.ref, i64, i64) -> i32 ! CHECK: %[[VAL_13:.*]] = arith.constant 0 : i32 ! CHECK: %[[VAL_14:.*]] = arith.cmpi eq, %[[VAL_12]], %[[VAL_13]] : i32 + +subroutine logical_and(x, y, z) + logical :: x, y, z + x = y.and.z +end subroutine +! CHECK-LABEL: func.func @_QPlogical_and( +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}}y"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref> +! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref> +! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_6]] : (!fir.logical<4>) -> i1 +! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_7]] : (!fir.logical<4>) -> i1 +! CHECK: %[[VAL_10:.*]] = arith.andi %[[VAL_8]], %[[VAL_9]] : i1 + +subroutine logical_or(x, y, z) + logical :: x, y, z + x = y.or.z +end subroutine +! CHECK-LABEL: func.func @_QPlogical_or( +! CHECK: %[[VAL_10:.*]] = arith.ori + +subroutine logical_eqv(x, y, z) + logical :: x, y, z + x = y.eqv.z +end subroutine +! CHECK-LABEL: func.func @_QPlogical_eqv( +! CHECK: %[[VAL_10:.*]] = arith.cmpi eq + +subroutine logical_neqv(x, y, z) + logical :: x, y, z + x = y.neqv.z +end subroutine +! CHECK-LABEL: func.func @_QPlogical_neqv( +! CHECK: %[[VAL_10:.*]] = arith.cmpi ne