[flang-commits] [flang] [flang] Handle absent optional in LOC (PR #73530)

via flang-commits flang-commits at lists.llvm.org
Wed Nov 29 01:12:55 PST 2023


https://github.com/jeanPerier updated https://github.com/llvm/llvm-project/pull/73530

>From 3855862c5b15b958953df29af09d562128a4e57c Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Mon, 27 Nov 2023 07:24:11 -0800
Subject: [PATCH 1/2] [flang] Handle absent optional in LOC

LOC is a GNU extension, so gfortran is the reference for it, and it
accepts absent OPTIONAL and returns zero. Support this use case in
flang too.

Update the LOC test to use HLFIR while touching it.

Fixes https://github.com/llvm/llvm-project/issues/72823.
---
 flang/lib/Optimizer/Builder/IntrinsicCall.cpp |  39 ++-
 flang/test/Lower/Intrinsics/loc.f90           | 259 ++++++++----------
 2 files changed, 150 insertions(+), 148 deletions(-)

diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 24fdbe97856b3ab..edf7a0b805839b7 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -4138,17 +4138,46 @@ IntrinsicLibrary::genCharacterCompare(mlir::Type resultType,
       fir::getBase(args[1]), fir::getLen(args[1]));
 }
 
+static bool isOptional(mlir::Value value) {
+  auto varIface = mlir::dyn_cast_or_null<fir::FortranVariableOpInterface>(
+      value.getDefiningOp());
+  return varIface && varIface.isOptional();
+}
+
 // LOC
 fir::ExtendedValue
 IntrinsicLibrary::genLoc(mlir::Type resultType,
                          llvm::ArrayRef<fir::ExtendedValue> args) {
   assert(args.size() == 1);
-  mlir::Value argValue = fir::getBase(args[0]);
-  assert(fir::isa_box_type(argValue.getType()) &&
+  mlir::Value box = fir::getBase(args[0]);
+  assert(fir::isa_box_type(box.getType()) &&
          "argument must have been lowered to box type");
-  bool isFunc = argValue.getType().isa<fir::BoxProcType>();
-  mlir::Value argAddr = getAddrFromBox(builder, loc, args[0], isFunc);
-  return builder.createConvert(loc, fir::unwrapRefType(resultType), argAddr);
+  bool isFunc = box.getType().isa<fir::BoxProcType>();
+  if (!isOptional(box)) {
+    // Optional assumed shape case. Note that the other OPTIONAL cases do
+    // not fall here since `box` was created when preparing the argument cases,
+    // but the box can be safely be used for all those cases and the address
+    // will be null if absent.
+    mlir::Value argAddr = getAddrFromBox(builder, loc, args[0], isFunc);
+    return builder.createConvert(loc, resultType, argAddr);
+  }
+  // Although this is not specified in this GNU intrinsic extension, it accepts
+  // absent optional and returns zero in that case.
+  mlir::Value isPresent =
+      builder.create<fir::IsPresentOp>(loc, builder.getI1Type(), box);
+  return builder
+      .genIfOp(loc, {resultType}, isPresent,
+               /*withElseRegion=*/true)
+      .genThen([&]() {
+        mlir::Value argAddr = getAddrFromBox(builder, loc, args[0], isFunc);
+        mlir::Value cast = builder.createConvert(loc, resultType, argAddr);
+        builder.create<fir::ResultOp>(loc, cast);
+      })
+      .genElse([&]() {
+        mlir::Value zero = builder.createIntegerConstant(loc, resultType, 0);
+        builder.create<fir::ResultOp>(loc, zero);
+      })
+      .getResults()[0];
 }
 
 // MASKL, MASKR
diff --git a/flang/test/Lower/Intrinsics/loc.f90 b/flang/test/Lower/Intrinsics/loc.f90
index a7d7124b9ddf97a..70e3ae7ae3316f4 100644
--- a/flang/test/Lower/Intrinsics/loc.f90
+++ b/flang/test/Lower/Intrinsics/loc.f90
@@ -1,5 +1,5 @@
-! RUN: bbc --use-desc-for-alloc=false -emit-fir -hlfir=false %s -o - | FileCheck %s
-! RUN: %flang_fc1 -mllvm --use-desc-for-alloc=false -emit-fir -flang-deprecated-no-hlfir %s -o - | FileCheck %s
+! RUN: bbc -emit-hlfir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s
 
 ! Test LOC intrinsic
 
@@ -8,12 +8,12 @@ subroutine loc_scalar()
   integer(8) :: p
   integer :: x
   p = loc(x)
-! CHECK: %[[p:.*]] = fir.alloca i64 {{.*}}
-! CHECK: %[[x:.*]] = fir.alloca i32 {{.*}}
-! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ref<i32>) -> !fir.box<i32>
-! CHECK: %[[xaddr:.*]] = fir.box_addr %[[xbox]] : (!fir.box<i32>) -> !fir.ref<i32>
-! CHECK: %[[xaddrval:.*]] = fir.convert %[[xaddr]] : (!fir.ref<i32>) -> i64
-! CHECK: fir.store %[[xaddrval]] to %[[p]] : !fir.ref<i64>
+! CHECK:  %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]]  {{.*}}Ep
+! CHECK:  %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2:[a-z0-9]*]]  {{.*}}Ex
+! CHECK:  %[[VAL_4:.*]] = fir.embox %[[VAL_3]]#1 : (!fir.ref<i32>) -> !fir.box<i32>
+! CHECK:  %[[VAL_5:.*]] = fir.box_addr %[[VAL_4]] : (!fir.box<i32>) -> !fir.ref<i32>
+! CHECK:  %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (!fir.ref<i32>) -> i64
+! CHECK:  hlfir.assign %[[VAL_6]] to %[[VAL_1]]#0 : i64, !fir.ref<i64>
 end
 
 ! CHECK-LABEL: func.func @_QPloc_char() {
@@ -21,12 +21,12 @@ subroutine loc_char()
   integer(8) :: p
   character(5) :: x = "abcde"
   p = loc(x)
-! CHECK: %[[p:.*]] = fir.alloca i64 {{.*}}
-! CHECK: %[[x:.*]] = fir.address_of(@_QFloc_charEx) : !fir.ref<!fir.char<1,5>>
-! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ref<!fir.char<1,5>>) -> !fir.box<!fir.char<1,5>>
-! CHECK: %[[xaddr:.*]] = fir.box_addr %[[xbox]] : (!fir.box<!fir.char<1,5>>) -> !fir.ref<!fir.char<1,5>>
-! CHECK: %[[xaddrval:.*]] = fir.convert %[[xaddr]] : (!fir.ref<!fir.char<1,5>>) -> i64
-! CHECK: fir.store %[[xaddrval]] to %[[p]] : !fir.ref<i64>
+! CHECK:  %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]]  {{.*}}Ep
+! CHECK:  %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_2:[a-z0-9]*]] typeparams %[[VAL_3:[a-z0-9]*]]  {{.*}}Ex
+! CHECK:  %[[VAL_5:.*]] = fir.embox %[[VAL_4]]#1 : (!fir.ref<!fir.char<1,5>>) -> !fir.box<!fir.char<1,5>>
+! CHECK:  %[[VAL_6:.*]] = fir.box_addr %[[VAL_5]] : (!fir.box<!fir.char<1,5>>) -> !fir.ref<!fir.char<1,5>>
+! CHECK:  %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (!fir.ref<!fir.char<1,5>>) -> i64
+! CHECK:  hlfir.assign %[[VAL_7]] to %[[VAL_1]]#0 : i64, !fir.ref<i64>
 end
 
 ! CHECK-LABEL: func.func @_QPloc_substring() {
@@ -34,26 +34,16 @@ subroutine loc_substring()
   integer(8) :: p
   character(5) :: x = "abcde"
   p = loc(x(2:))
-! CHECK: %[[p:.*]] = fir.alloca i64 {{.*}}
-! CHECK: %[[x:.*]] = fir.address_of(@_QFloc_substringEx) : !fir.ref<!fir.char<1,5>>
-! CHECK: %[[sslb:.*]] = arith.constant 2 : i64
-! CHECK: %[[ssub:.*]] = arith.constant 5 : i64
-! CHECK: %[[sslbidx:.*]] = fir.convert %[[sslb]] : (i64) -> index
-! CHECK: %[[ssubidx:.*]] = fir.convert %[[ssub]] : (i64) -> index
-! CHECK: %[[one:.*]] = arith.constant 1 : index
-! CHECK: %[[lboffset:.*]] = arith.subi %[[sslbidx]], %c1 : index
-! CHECK: %[[xarr:.*]] = fir.convert %[[x]] : (!fir.ref<!fir.char<1,5>>) -> !fir.ref<!fir.array<5x!fir.char<1>>>
-! CHECK: %[[xarrcoord:.*]] = fir.coordinate_of %[[xarr]], %[[lboffset]] : (!fir.ref<!fir.array<5x!fir.char<1>>>, index) -> !fir.ref<!fir.char<1>>
-! CHECK: %[[xss:.*]] = fir.convert %[[xarrcoord]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<!fir.char<1,?>>
-! CHECK: %[[rng:.*]] = arith.subi %[[ssubidx]], %[[sslbidx]] : index
-! CHECK: %[[rngp1:.*]] = arith.addi %[[rng]], %[[one]] : index
-! CHECK: %[[zero:.*]] = arith.constant 0 : index
-! CHECK: %[[cmpval:.*]] = arith.cmpi slt, %[[rngp1]], %[[zero]] : index
-! CHECK: %[[sltval:.*]] = arith.select %[[cmpval]], %[[zero]], %[[rngp1]] : index
-! CHECK: %[[xssbox:.*]] = fir.embox %[[xss]] typeparams %[[sltval]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.box<!fir.char<1,?>>
-! CHECK: %[[xssaddr:.*]] = fir.box_addr %[[xssbox]] : (!fir.box<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,?>>
-! CHECK: %[[xssaddrval:.*]] = fir.convert %[[xssaddr]] : (!fir.ref<!fir.char<1,?>>) -> i64
-! CHECK: fir.store %[[xssaddrval]] to %[[p]] : !fir.ref<i64>
+! CHECK:  %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]]  {{.*}}Ep
+! CHECK:  %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_2:[a-z0-9]*]] typeparams %[[VAL_3:[a-z0-9]*]]  {{.*}}Ex
+! CHECK:  %[[VAL_5:.*]] = arith.constant 2 : index
+! CHECK:  %[[VAL_6:.*]] = arith.constant 5 : index
+! CHECK:  %[[VAL_7:.*]] = arith.constant 4 : index
+! CHECK:  %[[VAL_8:.*]] = hlfir.designate %[[VAL_4]]#0  substr %[[VAL_5]], %[[VAL_6]]  typeparams %[[VAL_7]] : (!fir.ref<!fir.char<1,5>>, index, index, index) -> !fir.ref<!fir.char<1,4>>
+! CHECK:  %[[VAL_9:.*]] = fir.embox %[[VAL_8]] : (!fir.ref<!fir.char<1,4>>) -> !fir.box<!fir.char<1,4>>
+! CHECK:  %[[VAL_10:.*]] = fir.box_addr %[[VAL_9]] : (!fir.box<!fir.char<1,4>>) -> !fir.ref<!fir.char<1,4>>
+! CHECK:  %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (!fir.ref<!fir.char<1,4>>) -> i64
+! CHECK:  hlfir.assign %[[VAL_11]] to %[[VAL_1]]#0 : i64, !fir.ref<i64>
 end
 
 ! CHECK-LABEL: func.func @_QPloc_array() {
@@ -61,14 +51,12 @@ subroutine loc_array
   integer(8) :: p
   integer :: x(10)
   p = loc(x)
-! CHECK: %[[p:.*]] = fir.alloca i64 {{.*}}
-! CHECK: %[[ten:.*]] = arith.constant 10 : index
-! CHECK: %[[x:.*]] = fir.alloca !fir.array<10xi32> {{.*}}
-! CHECK: %[[xshp:.*]] = fir.shape %[[ten]] : (index) -> !fir.shape<1>
-! CHECK: %[[xbox:.*]] = fir.embox %[[x]](%[[xshp]]) : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<10xi32>>
-! CHECK: %[[xaddr:.*]] = fir.box_addr %[[xbox]] : (!fir.box<!fir.array<10xi32>>) -> !fir.ref<!fir.array<10xi32>>
-! CHECK: %[[xaddrval:.*]] = fir.convert %[[xaddr]] : (!fir.ref<!fir.array<10xi32>>) -> i64
-! CHECK: fir.store %[[xaddrval]] to %[[p]] : !fir.ref<i64>
+! CHECK:  %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]]  {{.*}}Ep
+! CHECK:  %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_3:[a-z0-9]*]](%[[VAL_4:[a-z0-9]*]])  {{.*}}Ex
+! CHECK:  %[[VAL_7:.*]] = fir.embox %[[VAL_5]]#1(%{{.*}}) : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<10xi32>>
+! CHECK:  %[[VAL_8:.*]] = fir.box_addr %[[VAL_7]] : (!fir.box<!fir.array<10xi32>>) -> !fir.ref<!fir.array<10xi32>>
+! CHECK:  %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (!fir.ref<!fir.array<10xi32>>) -> i64
+! CHECK:  hlfir.assign %[[VAL_9]] to %[[VAL_1]]#0 : i64, !fir.ref<i64>
 end
 
 ! CHECK-LABEL: func.func @_QPloc_chararray() {
@@ -76,14 +64,12 @@ subroutine loc_chararray()
   integer(8) :: p
   character(5) :: x(2)
   p = loc(x)
-! CHECK: %[[p:.*]] = fir.alloca i64 {{.*}}
-! CHECK: %[[two:.*]] = arith.constant 2 : index
-! CHECK: %[[x:.*]] = fir.alloca !fir.array<2x!fir.char<1,5>> {{.*}}
-! CHECK: %[[xshp:.*]] = fir.shape %[[two]] : (index) -> !fir.shape<1>
-! CHECK: %[[xbox:.*]] = fir.embox %[[x]](%[[xshp]]) : (!fir.ref<!fir.array<2x!fir.char<1,5>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1,5>>>
-! CHECK: %[[xaddr:.*]] = fir.box_addr %[[xbox]] : (!fir.box<!fir.array<2x!fir.char<1,5>>>) -> !fir.ref<!fir.array<2x!fir.char<1,5>>>
-! CHECK: %[[xaddrval:.*]] = fir.convert %[[xaddr]] : (!fir.ref<!fir.array<2x!fir.char<1,5>>>) -> i64
-! CHECK: fir.store %[[xaddrval]] to %[[p]] : !fir.ref<i64>
+! CHECK:  %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]]  {{.*}}Ep
+! CHECK:  %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_4:[a-z0-9]*]](%[[VAL_5:[a-z0-9]*]]) typeparams %[[VAL_2:[a-z0-9]*]]  {{.*}}Ex
+! CHECK:  %[[VAL_8:.*]] = fir.embox %[[VAL_6]]#1(%{{.*}}) : (!fir.ref<!fir.array<2x!fir.char<1,5>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1,5>>>
+! CHECK:  %[[VAL_9:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box<!fir.array<2x!fir.char<1,5>>>) -> !fir.ref<!fir.array<2x!fir.char<1,5>>>
+! CHECK:  %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (!fir.ref<!fir.array<2x!fir.char<1,5>>>) -> i64
+! CHECK:  hlfir.assign %[[VAL_10]] to %[[VAL_1]]#0 : i64, !fir.ref<i64>
 end
 
 ! CHECK-LABEL: func.func @_QPloc_arrayelement() {
@@ -91,16 +77,14 @@ subroutine loc_arrayelement()
   integer(8) :: p
   integer :: x(10)
   p = loc(x(7))
-! CHECK: %[[p:.*]] = fir.alloca i64 {{.*}}
-! CHECK: %[[x:.*]] = fir.alloca !fir.array<10xi32> {{.*}}
-! CHECK: %[[idx:.*]] = arith.constant 7 : i64
-! CHECK: %[[lb:.*]] = arith.constant 1 : i64
-! CHECK: %[[offset:.*]] = arith.subi %[[idx]], %[[lb]] : i64
-! CHECK: %[[xelemcoord:.*]] = fir.coordinate_of %[[x]], %[[offset]] : (!fir.ref<!fir.array<10xi32>>, i64) -> !fir.ref<i32>
-! CHECK: %[[xelembox:.*]] = fir.embox %[[xelemcoord]] : (!fir.ref<i32>) -> !fir.box<i32>
-! CHECK: %[[xelemaddr:.*]] = fir.box_addr %[[xelembox]] : (!fir.box<i32>) -> !fir.ref<i32>
-! CHECK: %[[xelemaddrval:.*]] = fir.convert %[[xelemaddr]] : (!fir.ref<i32>) -> i64
-! CHECK: fir.store %[[xelemaddrval]] to %[[p]] : !fir.ref<i64>
+! CHECK:  %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]]  {{.*}}Ep
+! CHECK:  %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_3:[a-z0-9]*]](%[[VAL_4:[a-z0-9]*]])  {{.*}}Ex
+! CHECK:  %[[VAL_6:.*]] = arith.constant 7 : index
+! CHECK:  %[[VAL_7:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_6]])  : (!fir.ref<!fir.array<10xi32>>, index) -> !fir.ref<i32>
+! CHECK:  %[[VAL_8:.*]] = fir.embox %[[VAL_7]] : (!fir.ref<i32>) -> !fir.box<i32>
+! CHECK:  %[[VAL_9:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box<i32>) -> !fir.ref<i32>
+! CHECK:  %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (!fir.ref<i32>) -> i64
+! CHECK:  hlfir.assign %[[VAL_10]] to %[[VAL_1]]#0 : i64, !fir.ref<i64>
 end
 
 ! CHECK-LABEL: func.func @_QPloc_arraysection(
@@ -110,23 +94,13 @@ subroutine loc_arraysection(i)
   integer :: i
   real :: x(11)
   p = loc(x(i:))
-! CHECK: %[[p:.*]] = fir.alloca i64 {{.*}}
-! CHECK: %[[eleven:.*]] = arith.constant 11 : index
-! CHECK: %[[x:.*]] = fir.alloca !fir.array<11xf32> {{.*}}
-! CHECK: %[[one:.*]] = arith.constant 1 : index
-! CHECK: %[[i:.*]] = fir.load %[[arg]] : !fir.ref<i32>
-! CHECK: %[[il:.*]] = fir.convert %[[i]] : (i32) -> i64
-! CHECK: %[[iidx:.*]] = fir.convert %[[il]] : (i64) -> index
-! CHECK: %[[onel:.*]] = arith.constant 1 : i64
-! CHECK: %[[stpidx:.*]] = fir.convert %[[onel]] : (i64) -> index
-! CHECK: %[[xrng:.*]] = arith.addi %[[one]], %[[eleven]] : index
-! CHECK: %[[xub:.*]] = arith.subi %[[xrng]], %[[one]] : index
-! CHECK: %[[xshp:.*]] = fir.shape %[[eleven]] : (index) -> !fir.shape<1>
-! CHECK: %[[xslice:.*]] = fir.slice %[[iidx]], %[[xub]], %[[stpidx]] : (index, index, index) -> !fir.slice<1>
-! CHECK: %[[xbox:.*]] = fir.embox %[[x]](%[[xshp]]) [%[[xslice]]] : (!fir.ref<!fir.array<11xf32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<?xf32>>
-! CHECK: %[[xaddr:.*]] = fir.box_addr %[[xbox]] : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>
-! CHECK: %[[xaddrval:.*]] = fir.convert %[[xaddr]] : (!fir.ref<!fir.array<?xf32>>) -> i64
-! CHECK: fir.store %[[xaddrval]] to %[[p]] : !fir.ref<i64>
+! CHECK:  %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]]  {{.*}}Ei
+! CHECK:  %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2:[a-z0-9]*]]  {{.*}}Ep
+! CHECK:  %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_5:[a-z0-9]*]](%[[VAL_6:[a-z0-9]*]])  {{.*}}Ex
+! CHECK:  %[[VAL_19:.*]] = hlfir.designate %[[VAL_7]]#0 (%{{.*}}:%{{.*}}:%{{.*}})  shape %{{.*}} : (!fir.ref<!fir.array<11xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
+! CHECK:  %[[VAL_20:.*]] = fir.box_addr %[[VAL_19]] : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>
+! CHECK:  %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (!fir.ref<!fir.array<?xf32>>) -> i64
+! CHECK:  hlfir.assign %[[VAL_21]] to %[[VAL_3]]#0 : i64, !fir.ref<i64>
 end
 
 ! CHECK-LABEL: func.func @_QPloc_non_save_pointer_scalar() {
@@ -136,19 +110,15 @@ subroutine loc_non_save_pointer_scalar()
   real, target :: t
   x => t
   p = loc(x)
-! CHECK: %[[p:.*]] = fir.alloca i64 {{.*}}
-! CHECK: %[[t:.*]] = fir.alloca f32 {{.*}}
-! CHECK: %2 = fir.alloca !fir.box<!fir.ptr<f32>> {{.*}}
-! CHECK: %[[xa:.*]] = fir.alloca !fir.ptr<f32> {{.*}}
-! CHECK: %[[zero:.*]] = fir.zero_bits !fir.ptr<f32>
-! CHECK: fir.store %[[zero]] to %[[xa]] : !fir.ref<!fir.ptr<f32>>
-! CHECK: %[[taddr:.*]] = fir.convert %[[t]] : (!fir.ref<f32>) -> !fir.ptr<f32>
-! CHECK: fir.store %[[taddr]] to %[[xa]] : !fir.ref<!fir.ptr<f32>>
-! CHECK: %[[x:.*]] = fir.load %[[xa]] : !fir.ref<!fir.ptr<f32>>
-! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ptr<f32>) -> !fir.box<f32>
-! CHECK: %[[xaddr:.*]] = fir.box_addr %[[xbox]] : (!fir.box<f32>) -> !fir.ref<f32>
-! CHECK: %[[xaddrval:.*]] = fir.convert %[[xaddr]] : (!fir.ref<f32>) -> i64
-! CHECK: fir.store %[[xaddrval]] to %[[p]] : !fir.ref<i64>
+! CHECK:  %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]]  {{.*}}Ep
+! CHECK:  %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2:[a-z0-9]*]]  {{.*}}Et
+! CHECK:  %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_4:[a-z0-9]*]]  {{.*}}Ex
+! CHECK:  %[[VAL_8:.*]] = fir.embox %[[VAL_3]]#1 : (!fir.ref<f32>) -> !fir.box<!fir.ptr<f32>>
+! CHECK:  fir.store %[[VAL_8]] to %[[VAL_7]]#1 : !fir.ref<!fir.box<!fir.ptr<f32>>>
+! CHECK:  %[[VAL_9:.*]] = fir.load %[[VAL_7]]#1 : !fir.ref<!fir.box<!fir.ptr<f32>>>
+! CHECK:  %[[VAL_10:.*]] = fir.box_addr %[[VAL_9]] : (!fir.box<!fir.ptr<f32>>) -> !fir.ptr<f32>
+! CHECK:  %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (!fir.ptr<f32>) -> i64
+! CHECK:  hlfir.assign %[[VAL_11]] to %[[VAL_1]]#0 : i64, !fir.ref<i64>
 end
 
 ! CHECK-LABEL: func.func @_QPloc_save_pointer_scalar() {
@@ -156,15 +126,13 @@ subroutine loc_save_pointer_scalar()
   integer :: p
   real, pointer, save :: x
   p = loc(x)
-! CHECK: %[[p:.*]] = fir.alloca i32 {{.*}}
-! CHECK: %[[x:.*]] = fir.address_of(@_QFloc_save_pointer_scalarEx) : !fir.ref<!fir.box<!fir.ptr<f32>>>
-! CHECK: %[[xref:.*]] = fir.load %[[x]] : !fir.ref<!fir.box<!fir.ptr<f32>>>
-! CHECK: %[[xaddr:.*]] = fir.box_addr %[[xref]] : (!fir.box<!fir.ptr<f32>>) -> !fir.ptr<f32>
-! CHECK: %[[xbox:.*]] = fir.embox %[[xaddr]] : (!fir.ptr<f32>) -> !fir.box<f32>
-! CHECK: %[[xaddr2:.*]] = fir.box_addr %[[xbox]] : (!fir.box<f32>) -> !fir.ref<f32>
-! CHECK: %[[xaddr2vall:.*]] = fir.convert %[[xaddr2]] : (!fir.ref<f32>) -> i64
-! CHECK: %[[xaddr2val:.*]] = fir.convert %[[xaddr2vall]] : (i64) -> i32
-! CHECK: fir.store %[[xaddr2val]] to %[[p]] : !fir.ref<i32>
+! CHECK:  %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]]  {{.*}}Ep
+! CHECK:  %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2:[a-z0-9]*]]  {{.*}}Ex
+! CHECK:  %[[VAL_4:.*]] = fir.load %[[VAL_3]]#1 : !fir.ref<!fir.box<!fir.ptr<f32>>>
+! CHECK:  %[[VAL_5:.*]] = fir.box_addr %[[VAL_4]] : (!fir.box<!fir.ptr<f32>>) -> !fir.ptr<f32>
+! CHECK:  %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (!fir.ptr<f32>) -> i64
+! CHECK:  %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (i64) -> i32
+! CHECK:  hlfir.assign %[[VAL_7]] to %[[VAL_1]]#0 : i32, !fir.ref<i32>
 end
 
 ! CHECK-LABEL: func.func @_QPloc_derived_type() {
@@ -175,12 +143,12 @@ subroutine loc_derived_type
   end type
   type(dt) :: xdt
   p = loc(xdt)
-! CHECK: %[[p:.*]] = fir.alloca i64 {{.*}}
-! CHECK: %[[xdt:.*]] = fir.alloca !fir.type<_QFloc_derived_typeTdt{i:i32}> {{.*}}
-! CHECK: %[[xdtbox:.*]] = fir.embox %[[xdt]] : (!fir.ref<!fir.type<_QFloc_derived_typeTdt{i:i32}>>) -> !fir.box<!fir.type<_QFloc_derived_typeTdt{i:i32}>>
-! CHECK: %[[xdtaddr:.*]] = fir.box_addr %[[xdtbox]] : (!fir.box<!fir.type<_QFloc_derived_typeTdt{i:i32}>>) -> !fir.ref<!fir.type<_QFloc_derived_typeTdt{i:i32}>>
-! CHECK: %[[xdtaddrval:.*]] = fir.convert %[[xdtaddr]] : (!fir.ref<!fir.type<_QFloc_derived_typeTdt{i:i32}>>) -> i64
-! CHECK: fir.store %[[xdtaddrval]] to %[[p]] : !fir.ref<i64>
+! CHECK:  %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]]  {{.*}}Ep
+! CHECK:  %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2:[a-z0-9]*]]  {{.*}}Exdt
+! CHECK:  %[[VAL_4:.*]] = fir.embox %[[VAL_3]]#1 : (!fir.ref<!fir.type<_QFloc_derived_typeTdt{i:i32}>>) -> !fir.box<!fir.type<_QFloc_derived_typeTdt{i:i32}>>
+! CHECK:  %[[VAL_5:.*]] = fir.box_addr %[[VAL_4]] : (!fir.box<!fir.type<_QFloc_derived_typeTdt{i:i32}>>) -> !fir.ref<!fir.type<_QFloc_derived_typeTdt{i:i32}>>
+! CHECK:  %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (!fir.ref<!fir.type<_QFloc_derived_typeTdt{i:i32}>>) -> i64
+! CHECK:  hlfir.assign %[[VAL_6]] to %[[VAL_1]]#0 : i64, !fir.ref<i64>
 end
 
 ! CHECK-LABEL: func.func @_QPloc_pointer_array() {
@@ -188,17 +156,12 @@ subroutine loc_pointer_array
   integer(8) :: p
   integer, pointer :: x(:)
   p = loc(x)
-! CHECK: %[[p:.*]] = fir.alloca i64 {{.*}}
-! CHECK: %[[x:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?xi32>>> {{.*}}
-! CHECK: %2 = fir.zero_bits !fir.ptr<!fir.array<?xi32>>
-! CHECK: %[[zero:.*]] = arith.constant 0 : index
-! CHECK: %[[xshp:.*]] = fir.shape %[[zero]] : (index) -> !fir.shape<1>
-! CHECK: %[[xbox0:.*]] = fir.embox %2(%[[xshp]]) : (!fir.ptr<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>>
-! CHECK: fir.store %[[xbox0]] to %[[x]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
-! CHECK: %[[xbox:.*]] = fir.load %[[x]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
-! CHECK: %[[xaddr:.*]] = fir.box_addr %[[xbox]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> !fir.ptr<!fir.array<?xi32>>
-! CHECK: %[[xaddrval:.*]] = fir.convert %[[xaddr]] : (!fir.ptr<!fir.array<?xi32>>) -> i64
-! CHECK: fir.store %[[xaddrval]] to %[[p]] : !fir.ref<i64>
+! CHECK:  %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]]  {{.*}}Ep
+! CHECK:  %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_2:[a-z0-9]*]]  {{.*}}Ex
+! CHECK:  %[[VAL_8:.*]] = fir.load %[[VAL_7]]#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+! CHECK:  %[[VAL_9:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> !fir.ptr<!fir.array<?xi32>>
+! CHECK:  %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (!fir.ptr<!fir.array<?xi32>>) -> i64
+! CHECK:  hlfir.assign %[[VAL_10]] to %[[VAL_1]]#0 : i64, !fir.ref<i64>
 end
 
 ! CHECK-LABEL: func.func @_QPloc_allocatable_array() {
@@ -206,21 +169,12 @@ subroutine loc_allocatable_array
   integer(8) :: p
   integer, allocatable :: x(:)
   p = loc(x)
-! CHECK: %[[p:.*]] = fir.alloca i64 {{.*}}
-! CHECK: %1 = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>> {{.*}}
-! CHECK: %[[stg:.*]] = fir.alloca !fir.heap<!fir.array<?xi32>> {{.*}}
-! CHECK: %[[lb:.*]] = fir.alloca index {{.*}}
-! CHECK: %[[ext:.*]] = fir.alloca index {{.*}}
-! CHECK: %[[zstg:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
-! CHECK: fir.store %[[zstg]] to %[[stg]] : !fir.ref<!fir.heap<!fir.array<?xi32>>>
-! CHECK: %[[lbval:.*]] = fir.load %[[lb]] : !fir.ref<index>
-! CHECK: %[[extval:.*]] = fir.load %[[ext]] : !fir.ref<index>
-! CHECK: %[[stgaddr:.*]] = fir.load %[[stg]] : !fir.ref<!fir.heap<!fir.array<?xi32>>>
-! CHECK: %[[ss:.*]] = fir.shape_shift %[[lbval]], %[[extval]] : (index, index) -> !fir.shapeshift<1>
-! CHECK: %[[xbox:.*]] = fir.embox %[[stgaddr]](%[[ss]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<?xi32>>
-! CHECK: %[[xaddr:.*]] = fir.box_addr %[[xbox]] : (!fir.box<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
-! CHECK: %[[xaddrval:.*]] = fir.convert %[[xaddr]] : (!fir.ref<!fir.array<?xi32>>) -> i64
-! CHECK: fir.store %[[xaddrval]] to %[[p]] : !fir.ref<i64>
+! CHECK:  %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]]  {{.*}}Ep
+! CHECK:  %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_2:[a-z0-9]*]]  {{.*}}Ex
+! CHECK:  %[[VAL_8:.*]] = fir.load %[[VAL_7]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK:  %[[VAL_9:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
+! CHECK:  %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (!fir.heap<!fir.array<?xi32>>) -> i64
+! CHECK:  hlfir.assign %[[VAL_10]] to %[[VAL_1]]#0 : i64, !fir.ref<i64>
 end
 
 ! CHECK-LABEL: func.func @_QPtest_external() {
@@ -228,12 +182,12 @@ subroutine test_external()
   integer(8) :: p
   integer, external :: f
   p = loc(x=f)
-! CHECK: %[[p:.*]] = fir.alloca i64 {{.*}}
-! CHECK: %[[f:.*]] = fir.address_of(@_QPf) : () -> i32
-! CHECK: %[[fbox:.*]] = fir.emboxproc %[[f]] : (() -> i32) -> !fir.boxproc<() -> i32>
-! CHECK: %[[faddr:.*]] = fir.box_addr %[[fbox]] : (!fir.boxproc<() -> i32>) -> (() -> i32)
-! CHECK: %[[faddrval:.*]] = fir.convert %[[faddr]] : (() -> i32) -> i64
-! CHECK: fir.store %[[faddrval]] to %[[p]] : !fir.ref<i64>
+! CHECK:  %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]]  {{.*}}Ep
+! CHECK:  %[[VAL_2:.*]] = fir.address_of(@_QPf) : () -> i32
+! CHECK:  %[[VAL_3:.*]] = fir.emboxproc %[[VAL_2]] : (() -> i32) -> !fir.boxproc<() -> ()>
+! CHECK:  %[[VAL_4:.*]] = fir.box_addr %[[VAL_3]] : (!fir.boxproc<() -> ()>) -> (() -> ())
+! CHECK:  %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (() -> ()) -> i64
+! CHECK:  hlfir.assign %[[VAL_5]] to %[[VAL_1]]#0 : i64, !fir.ref<i64>
 end
 
 ! CHECK-LABEL: func.func @_QPtest_proc() {
@@ -241,10 +195,29 @@ subroutine test_proc()
   integer(8) :: p
   procedure() :: g
   p = loc(x=g)
-! CHECK: %[[p:.*]] = fir.alloca i64 {{.*}}
-! CHECK: %[[g:.*]] = fir.address_of(@_QPg) : () -> ()
-! CHECK: %[[gbox:.*]] = fir.emboxproc %[[g]] : (() -> ()) -> !fir.boxproc<() -> ()>
-! CHECK: %[[gaddr:.*]] = fir.box_addr %[[gbox]] : (!fir.boxproc<() -> ()>) -> (() -> ())
-! CHECK: %[[gaddrval:.*]] = fir.convert %[[gaddr]] : (() -> ()) -> i64
-! CHECK: fir.store %[[gaddrval]] to %[[p]] : !fir.ref<i64>
+! CHECK:  %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]]  {{.*}}Ep
+! CHECK:  %[[VAL_2:.*]] = fir.address_of(@_QPg) : () -> ()
+! CHECK:  %[[VAL_3:.*]] = fir.emboxproc %[[VAL_2]] : (() -> ()) -> !fir.boxproc<() -> ()>
+! CHECK:  %[[VAL_4:.*]] = fir.box_addr %[[VAL_3]] : (!fir.boxproc<() -> ()>) -> (() -> ())
+! CHECK:  %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (() -> ()) -> i64
+! CHECK:  hlfir.assign %[[VAL_5]] to %[[VAL_1]]#0 : i64, !fir.ref<i64>
 end
+
+! CHECK-LABEL:   func.func @_QPtest_assumed_shape_optional(
+subroutine test_assumed_shape_optional(x)
+  integer(8) :: p
+  real, optional :: x(:)
+  p = loc(x=x)
+! CHECK:  %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1:[a-z0-9]*]]  {{.*}}Ep
+! CHECK:  %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]]  {{.*}}Ex
+! CHECK:  %[[VAL_4:.*]] = fir.is_present %[[VAL_3]]#1 : (!fir.box<!fir.array<?xf32>>) -> i1
+! CHECK:  %[[VAL_5:.*]] = fir.if %[[VAL_4]] -> (i64) {
+! CHECK:    %[[VAL_6:.*]] = fir.box_addr %[[VAL_3]]#1 : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>
+! CHECK:    %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (!fir.ref<!fir.array<?xf32>>) -> i64
+! CHECK:    fir.result %[[VAL_7]] : i64
+! CHECK:  } else {
+! CHECK:    %[[VAL_8:.*]] = arith.constant 0 : i64
+! CHECK:    fir.result %[[VAL_8]] : i64
+! CHECK:  }
+! CHECK:  hlfir.assign %[[VAL_5]] to %[[VAL_2]]#0 : i64, !fir.ref<i64>
+end subroutine

>From d7ed17be228bf32aea10c64fab348e8485f50c6b Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Wed, 29 Nov 2023 01:11:53 -0800
Subject: [PATCH 2/2] move comment

---
 flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index edf7a0b805839b7..7f354d7e77560f6 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -4154,15 +4154,15 @@ IntrinsicLibrary::genLoc(mlir::Type resultType,
          "argument must have been lowered to box type");
   bool isFunc = box.getType().isa<fir::BoxProcType>();
   if (!isOptional(box)) {
-    // Optional assumed shape case. Note that the other OPTIONAL cases do
-    // not fall here since `box` was created when preparing the argument cases,
-    // but the box can be safely be used for all those cases and the address
-    // will be null if absent.
     mlir::Value argAddr = getAddrFromBox(builder, loc, args[0], isFunc);
     return builder.createConvert(loc, resultType, argAddr);
   }
-  // Although this is not specified in this GNU intrinsic extension, it accepts
-  // absent optional and returns zero in that case.
+  // Optional assumed shape case.  Although this is not specified in this GNU
+  // intrinsic extension, LOC accepts absent optional and returns zero in that
+  // case.
+  // Note that the other OPTIONAL cases do not fall here since `box` was
+  // created when preparing the argument cases, but the box can be safely be
+  // used for all those cases and the address will be null if absent.
   mlir::Value isPresent =
       builder.create<fir::IsPresentOp>(loc, builder.getI1Type(), box);
   return builder



More information about the flang-commits mailing list