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 @@ -581,9 +581,14 @@ template struct UnaryOp> { using Op = Fortran::evaluate::Parentheses; - static hlfir::EntityWithAttributes - gen(mlir::Location loc, fir::FirOpBuilder &, const Op &, hlfir::Entity) { - TODO(loc, "Parentheses lowering to HLFIR"); + static hlfir::EntityWithAttributes gen(mlir::Location loc, + fir::FirOpBuilder &builder, + const Op &op, hlfir::Entity lhs) { + if (lhs.isVariable()) + return hlfir::EntityWithAttributes{ + builder.create(loc, lhs)}; + return hlfir::EntityWithAttributes{ + builder.create(loc, lhs.getType(), lhs)}; } }; diff --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp --- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp +++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp @@ -291,12 +291,19 @@ if (!entity.hasLengthParameters()) return; if (entity.getType().isa()) { + mlir::Value expr = entity; + if (auto reassoc = expr.getDefiningOp()) + expr = reassoc.getVal(); // Going through fir::ExtendedValue would create a temp, // which is not desired for an inquiry. // TODO: make this an interface when adding further character producing ops. - if (auto concat = entity.getDefiningOp()) { + if (auto concat = expr.getDefiningOp()) { result.push_back(concat.getLength()); return; + } else if (auto asExpr = expr.getDefiningOp()) { + hlfir::genLengthParameters(loc, builder, hlfir::Entity{asExpr.getVar()}, + result); + return; } TODO(loc, "inquire type parameters of hlfir.expr"); } diff --git a/flang/test/Lower/HLFIR/unary-ops.f90 b/flang/test/Lower/HLFIR/unary-ops.f90 --- a/flang/test/Lower/HLFIR/unary-ops.f90 +++ b/flang/test/Lower/HLFIR/unary-ops.f90 @@ -1,6 +1,39 @@ ! Test lowering of unary intrinsic operations to HLFIR ! RUN: bbc -emit-fir -hlfir -o - %s 2>&1 | FileCheck %s +subroutine parentheses_numeric_var(x) + integer :: x + call bar((x)) +end subroutine +! CHECK-LABEL: func.func @_QPparentheses_numeric_var( +! CHECK: %[[VAL_2:.*]] = fir.load %{{.*}} : !fir.ref +! CHECK: %[[VAL_3:.*]] = hlfir.no_reassoc %[[VAL_2]] : i32 + +subroutine parentheses_numeric_expr(x) + real :: x + call bar((x+1000.)*2.) +end subroutine +! CHECK-LABEL: func.func @_QPparentheses_numeric_expr( +! CHECK: %[[VAL_4:.*]] = arith.addf +! CHECK: %[[VAL_5:.*]] = hlfir.no_reassoc %[[VAL_4]] : f32 +! CHECK: %[[VAL_7:.*]] = arith.mulf %[[VAL_5]], %{{.*}} + +subroutine parentheses_char_var(x) + character(*) :: x + call bar2((x)) +end subroutine +! CHECK-LABEL: func.func @_QPparentheses_char_var( +! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare +! CHECK: %[[VAL_3:.*]] = hlfir.as_expr %[[VAL_2]]#0 : (!fir.boxchar<1>) -> !hlfir.expr> + +subroutine parentheses_char_expr(x) + character(*) :: x + call bar2((x//x)//x) +end subroutine +! CHECK-LABEL: func.func @_QPparentheses_char_expr( +! CHECK: %[[VAL_4:.*]] = hlfir.concat +! CHECK: %[[VAL_5:.*]] = hlfir.no_reassoc %[[VAL_4]] : !hlfir.expr> +! CHECK: %[[VAL_7:.*]] = hlfir.concat %[[VAL_5]], %{{.*}} len %{{.*}} subroutine test_not(l, x) logical :: l, x l = .not.x