[flang-commits] [flang] 6fd4608 - [flang][debug] Allow non default array lower bounds. (#104467)

via flang-commits flang-commits at lists.llvm.org
Wed Aug 21 08:57:11 PDT 2024


Author: Abid Qadeer
Date: 2024-08-21T16:57:08+01:00
New Revision: 6fd46089c9fbd5b22bb67ac3d6196fe70ba684c6

URL: https://github.com/llvm/llvm-project/commit/6fd46089c9fbd5b22bb67ac3d6196fe70ba684c6
DIFF: https://github.com/llvm/llvm-project/commit/6fd46089c9fbd5b22bb67ac3d6196fe70ba684c6.diff

LOG: [flang][debug] Allow non default array lower bounds. (#104467)

As mentioned in #98877, we currently always use 1 as lower bound for
fixed size arrays. This PR removes this restriction. It passes along
`DeclareOp` to type conversion functions and uses the shift information
(if present) to get the lower bound value. This was suggested by
@jeanPerier in
https://github.com/llvm/llvm-project/pull/96746#issuecomment-2195164553
    
This PR also adds a small cleanup that type conversion functions don't
take Location now. It was initially added so that location of derived
types can be passed. But that information can be extracted from typeInfo
objects and we don't need to pass it along.

This PR will handle the problem for local and global variable. We may
need a bit more work for derived type once the support for derived types
lands.
    
Fixes #98877.

Added: 
    

Modified: 
    flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
    flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
    flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
    flang/test/Integration/debug-fixed-array-type-2.f90
    flang/test/Transforms/debug-fixed-array-type.fir

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index 3c067bf946cfc9..30fc4185575e61 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -65,7 +65,8 @@ class AddDebugInfoPass : public fir::impl::AddDebugInfoBase<AddDebugInfoPass> {
 
   void handleGlobalOp(fir::GlobalOp glocalOp, mlir::LLVM::DIFileAttr fileAttr,
                       mlir::LLVM::DIScopeAttr scope,
-                      mlir::SymbolTable *symbolTable);
+                      mlir::SymbolTable *symbolTable,
+                      fir::cg::XDeclareOp declOp);
   void handleFuncOp(mlir::func::FuncOp funcOp, mlir::LLVM::DIFileAttr fileAttr,
                     mlir::LLVM::DICompileUnitAttr cuAttr,
                     mlir::SymbolTable *symbolTable);
@@ -100,10 +101,9 @@ void AddDebugInfoPass::handleDeclareOp(fir::cg::XDeclareOp declOp,
 
   if (result.first != fir::NameUniquer::NameKind::VARIABLE)
     return;
-
   // If this DeclareOp actually represents a global then treat it as such.
   if (auto global = symbolTable->lookup<fir::GlobalOp>(declOp.getUniqName())) {
-    handleGlobalOp(global, fileAttr, scopeAttr, symbolTable);
+    handleGlobalOp(global, fileAttr, scopeAttr, symbolTable, declOp);
     return;
   }
 
@@ -127,7 +127,7 @@ void AddDebugInfoPass::handleDeclareOp(fir::cg::XDeclareOp declOp,
   }
 
   auto tyAttr = typeGen.convertType(fir::unwrapRefType(declOp.getType()),
-                                    fileAttr, scopeAttr, declOp.getLoc());
+                                    fileAttr, scopeAttr, declOp);
 
   auto localVarAttr = mlir::LLVM::DILocalVariableAttr::get(
       context, scopeAttr, mlir::StringAttr::get(context, result.second.name),
@@ -160,7 +160,8 @@ mlir::LLVM::DIModuleAttr AddDebugInfoPass::getOrCreateModuleAttr(
 void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
                                       mlir::LLVM::DIFileAttr fileAttr,
                                       mlir::LLVM::DIScopeAttr scope,
-                                      mlir::SymbolTable *symbolTable) {
+                                      mlir::SymbolTable *symbolTable,
+                                      fir::cg::XDeclareOp declOp) {
   if (debugInfoIsAlreadySet(globalOp.getLoc()))
     return;
   mlir::ModuleOp module = getOperation();
@@ -200,8 +201,8 @@ void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
     scope = getOrCreateModuleAttr(result.second.modules[0], fileAttr, scope,
                                   line - 1, !globalOp.isInitialized());
   }
-  mlir::LLVM::DITypeAttr diType = typeGen.convertType(
-      globalOp.getType(), fileAttr, scope, globalOp.getLoc());
+  mlir::LLVM::DITypeAttr diType =
+      typeGen.convertType(globalOp.getType(), fileAttr, scope, declOp);
   auto gvAttr = mlir::LLVM::DIGlobalVariableAttr::get(
       context, scope, mlir::StringAttr::get(context, result.second.name),
       mlir::StringAttr::get(context, globalOp.getName()), fileAttr, line,
@@ -246,12 +247,13 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp,
   llvm::SmallVector<mlir::LLVM::DITypeAttr> types;
   fir::DebugTypeGenerator typeGen(module);
   for (auto resTy : funcOp.getResultTypes()) {
-    auto tyAttr = typeGen.convertType(resTy, fileAttr, cuAttr, funcOp.getLoc());
+    auto tyAttr =
+        typeGen.convertType(resTy, fileAttr, cuAttr, /*declOp=*/nullptr);
     types.push_back(tyAttr);
   }
   for (auto inTy : funcOp.getArgumentTypes()) {
     auto tyAttr = typeGen.convertType(fir::unwrapRefType(inTy), fileAttr,
-                                      cuAttr, funcOp.getLoc());
+                                      cuAttr, /*declOp=*/nullptr);
     types.push_back(tyAttr);
   }
 
@@ -358,7 +360,8 @@ void AddDebugInfoPass::runOnOperation() {
   if (debugLevel == mlir::LLVM::DIEmissionKind::Full) {
     // Process 'GlobalOp' only if full debug info is requested.
     for (auto globalOp : module.getOps<fir::GlobalOp>())
-      handleGlobalOp(globalOp, fileAttr, cuAttr, &symbolTable);
+      handleGlobalOp(globalOp, fileAttr, cuAttr, &symbolTable,
+                     /*declOp=*/nullptr);
   }
 }
 

diff  --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
index db559731552df2..860c16c9a13ce9 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
@@ -83,8 +83,8 @@ static mlir::LLVM::DITypeAttr genPlaceholderType(mlir::MLIRContext *context) {
 
 mlir::LLVM::DITypeAttr DebugTypeGenerator::convertBoxedSequenceType(
     fir::SequenceType seqTy, mlir::LLVM::DIFileAttr fileAttr,
-    mlir::LLVM::DIScopeAttr scope, mlir::Location loc, bool genAllocated,
-    bool genAssociated) {
+    mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp,
+    bool genAllocated, bool genAssociated) {
 
   mlir::MLIRContext *context = module.getContext();
   // FIXME: Assumed rank arrays not supported yet
@@ -114,7 +114,7 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertBoxedSequenceType(
 
   llvm::SmallVector<mlir::LLVM::DINodeAttr> elements;
   mlir::LLVM::DITypeAttr elemTy =
-      convertType(seqTy.getEleTy(), fileAttr, scope, loc);
+      convertType(seqTy.getEleTy(), fileAttr, scope, declOp);
   unsigned offset = dimsOffset;
   const unsigned indexSize = dimsSize / 3;
   for ([[maybe_unused]] auto _ : seqTy.getShape()) {
@@ -156,13 +156,14 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertBoxedSequenceType(
 
 mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
     fir::SequenceType seqTy, mlir::LLVM::DIFileAttr fileAttr,
-    mlir::LLVM::DIScopeAttr scope, mlir::Location loc) {
+    mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp) {
   mlir::MLIRContext *context = module.getContext();
 
   llvm::SmallVector<mlir::LLVM::DINodeAttr> elements;
   mlir::LLVM::DITypeAttr elemTy =
-      convertType(seqTy.getEleTy(), fileAttr, scope, loc);
+      convertType(seqTy.getEleTy(), fileAttr, scope, declOp);
 
+  unsigned index = 0;
   for (fir::SequenceType::Extent dim : seqTy.getShape()) {
     if (dim == seqTy.getUnknownExtent()) {
       // FIXME: This path is taken for assumed size arrays but also for arrays
@@ -174,20 +175,20 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
       elements.push_back(subrangeTy);
     } else {
       auto intTy = mlir::IntegerType::get(context, 64);
-      // FIXME: Only supporting lower bound of 1 at the moment. The
-      // 'SequenceType' has information about the shape but not the shift. In
-      // cases where the conversion originated during the processing of
-      // 'DeclareOp', it may be possible to pass on this information. But the
-      // type conversion should ideally be based on what information present in
-      // the type class so that it works from everywhere (e.g. when it is part
-      // of a module or a derived type.)
+      int64_t shift = 1;
+      if (declOp && declOp.getShift().size() > index) {
+        if (std::optional<std::int64_t> optint =
+                getIntIfConstant(declOp.getShift()[index]))
+          shift = *optint;
+      }
       auto countAttr = mlir::IntegerAttr::get(intTy, llvm::APInt(64, dim));
-      auto lowerAttr = mlir::IntegerAttr::get(intTy, llvm::APInt(64, 1));
+      auto lowerAttr = mlir::IntegerAttr::get(intTy, llvm::APInt(64, shift));
       auto subrangeTy = mlir::LLVM::DISubrangeAttr::get(
           context, countAttr, lowerAttr, /*upperBound=*/nullptr,
           /*stride=*/nullptr);
       elements.push_back(subrangeTy);
     }
+    ++index;
   }
   // Apart from arrays, the `DICompositeTypeAttr` is used for other things like
   // structure types. Many of its fields which are not applicable to arrays
@@ -203,7 +204,8 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
 
 mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
     fir::CharacterType charTy, mlir::LLVM::DIFileAttr fileAttr,
-    mlir::LLVM::DIScopeAttr scope, mlir::Location loc, bool hasDescriptor) {
+    mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp,
+    bool hasDescriptor) {
   mlir::MLIRContext *context = module.getContext();
 
   // DWARF 5 says the following about the character encoding in 5.1.1.2.
@@ -250,21 +252,21 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
 
 mlir::LLVM::DITypeAttr DebugTypeGenerator::convertPointerLikeType(
     mlir::Type elTy, mlir::LLVM::DIFileAttr fileAttr,
-    mlir::LLVM::DIScopeAttr scope, mlir::Location loc, bool genAllocated,
-    bool genAssociated) {
+    mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp,
+    bool genAllocated, bool genAssociated) {
   mlir::MLIRContext *context = module.getContext();
 
   // Arrays and character need 
diff erent treatment because DWARF have special
   // constructs for them to get the location from the descriptor. Rest of
   // types are handled like pointer to underlying type.
   if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(elTy))
-    return convertBoxedSequenceType(seqTy, fileAttr, scope, loc, genAllocated,
-                                    genAssociated);
+    return convertBoxedSequenceType(seqTy, fileAttr, scope, declOp,
+                                    genAllocated, genAssociated);
   if (auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(elTy))
-    return convertCharacterType(charTy, fileAttr, scope, loc,
+    return convertCharacterType(charTy, fileAttr, scope, declOp,
                                 /*hasDescriptor=*/true);
 
-  mlir::LLVM::DITypeAttr elTyAttr = convertType(elTy, fileAttr, scope, loc);
+  mlir::LLVM::DITypeAttr elTyAttr = convertType(elTy, fileAttr, scope, declOp);
 
   return mlir::LLVM::DIDerivedTypeAttr::get(
       context, llvm::dwarf::DW_TAG_pointer_type,
@@ -276,7 +278,7 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertPointerLikeType(
 mlir::LLVM::DITypeAttr
 DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
                                 mlir::LLVM::DIScopeAttr scope,
-                                mlir::Location loc) {
+                                fir::cg::XDeclareOp declOp) {
   mlir::MLIRContext *context = module.getContext();
   if (Ty.isInteger()) {
     return genBasicType(context, mlir::StringAttr::get(context, "integer"),
@@ -306,22 +308,22 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
     return genBasicType(context, mlir::StringAttr::get(context, "complex"),
                         bitWidth * 2, llvm::dwarf::DW_ATE_complex_float);
   } else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(Ty)) {
-    return convertSequenceType(seqTy, fileAttr, scope, loc);
+    return convertSequenceType(seqTy, fileAttr, scope, declOp);
   } else if (auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(Ty)) {
-    return convertCharacterType(charTy, fileAttr, scope, loc,
+    return convertCharacterType(charTy, fileAttr, scope, declOp,
                                 /*hasDescriptor=*/false);
   } else if (auto boxTy = mlir::dyn_cast_or_null<fir::BoxType>(Ty)) {
     auto elTy = boxTy.getElementType();
     if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(elTy))
-      return convertBoxedSequenceType(seqTy, fileAttr, scope, loc, false,
+      return convertBoxedSequenceType(seqTy, fileAttr, scope, declOp, false,
                                       false);
     if (auto heapTy = mlir::dyn_cast_or_null<fir::HeapType>(elTy))
       return convertPointerLikeType(heapTy.getElementType(), fileAttr, scope,
-                                    loc, /*genAllocated=*/true,
+                                    declOp, /*genAllocated=*/true,
                                     /*genAssociated=*/false);
     if (auto ptrTy = mlir::dyn_cast_or_null<fir::PointerType>(elTy))
       return convertPointerLikeType(ptrTy.getElementType(), fileAttr, scope,
-                                    loc, /*genAllocated=*/false,
+                                    declOp, /*genAllocated=*/false,
                                     /*genAssociated=*/true);
     return genPlaceholderType(context);
   } else {

diff  --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
index ec881e8be7cadc..5ab6ca5e9f880e 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
@@ -13,6 +13,7 @@
 #ifndef FORTRAN_OPTIMIZER_TRANSFORMS_DEBUGTYPEGENERATOR_H
 #define FORTRAN_OPTIMIZER_TRANSFORMS_DEBUGTYPEGENERATOR_H
 
+#include "flang/Optimizer/CodeGen/CGOps.h"
 #include "flang/Optimizer/Dialect/FIRType.h"
 #include "flang/Optimizer/Dialect/Support/FIRContext.h"
 #include "flang/Optimizer/Dialect/Support/KindMapping.h"
@@ -28,33 +29,34 @@ class DebugTypeGenerator {
   mlir::LLVM::DITypeAttr convertType(mlir::Type Ty,
                                      mlir::LLVM::DIFileAttr fileAttr,
                                      mlir::LLVM::DIScopeAttr scope,
-                                     mlir::Location loc);
+                                     fir::cg::XDeclareOp declOp);
 
 private:
   mlir::LLVM::DITypeAttr convertSequenceType(fir::SequenceType seqTy,
                                              mlir::LLVM::DIFileAttr fileAttr,
                                              mlir::LLVM::DIScopeAttr scope,
-                                             mlir::Location loc);
+                                             fir::cg::XDeclareOp declOp);
 
   /// The 'genAllocated' is true when we want to generate 'allocated' field
   /// in the DICompositeType. It is needed for the allocatable arrays.
   /// Similarly, 'genAssociated' is used with 'pointer' type to generate
   /// 'associated' field.
-  mlir::LLVM::DITypeAttr
-  convertBoxedSequenceType(fir::SequenceType seqTy,
-                           mlir::LLVM::DIFileAttr fileAttr,
-                           mlir::LLVM::DIScopeAttr scope, mlir::Location loc,
-                           bool genAllocated, bool genAssociated);
+  mlir::LLVM::DITypeAttr convertBoxedSequenceType(
+      fir::SequenceType seqTy, mlir::LLVM::DIFileAttr fileAttr,
+      mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp,
+      bool genAllocated, bool genAssociated);
   mlir::LLVM::DITypeAttr convertCharacterType(fir::CharacterType charTy,
                                               mlir::LLVM::DIFileAttr fileAttr,
                                               mlir::LLVM::DIScopeAttr scope,
-                                              mlir::Location loc,
+                                              fir::cg::XDeclareOp declOp,
                                               bool hasDescriptor);
 
-  mlir::LLVM::DITypeAttr
-  convertPointerLikeType(mlir::Type elTy, mlir::LLVM::DIFileAttr fileAttr,
-                         mlir::LLVM::DIScopeAttr scope, mlir::Location loc,
-                         bool genAllocated, bool genAssociated);
+  mlir::LLVM::DITypeAttr convertPointerLikeType(mlir::Type elTy,
+                                                mlir::LLVM::DIFileAttr fileAttr,
+                                                mlir::LLVM::DIScopeAttr scope,
+                                                fir::cg::XDeclareOp declOp,
+                                                bool genAllocated,
+                                                bool genAssociated);
 
   mlir::ModuleOp module;
   KindMapping kindMapping;

diff  --git a/flang/test/Integration/debug-fixed-array-type-2.f90 b/flang/test/Integration/debug-fixed-array-type-2.f90
index b34413458ad8d3..705c1da593c705 100644
--- a/flang/test/Integration/debug-fixed-array-type-2.f90
+++ b/flang/test/Integration/debug-fixed-array-type-2.f90
@@ -1,19 +1,22 @@
 ! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
 
-program mn
-
+module test
   integer d1(3)
-  integer d2(2, 5)
-  real d3(6, 8, 7)
+  integer d2(1:4, -1:3)
+  real d3(-2:6, 0:5, 3:7)
+end
+
+program mn
+  use test
 
   i8 = fn1(d1, d2, d3)
 contains
   function fn1(a1, b1, c1) result (res)
     integer a1(3)
-    integer b1(2, 5)
-    real c1(6, 8, 7)
+    integer b1(-1:0, 5:9)
+    real c1(-2:6, 0:5, 3:7)
     integer res
-    res = a1(1) + b1(1,2) + c1(3, 3, 4)
+    res = a1(1) + b1(0,6) + c1(3, 3, 4)
   end function
 
 end program
@@ -24,17 +27,26 @@ function fn1(a1, b1, c1) result (res)
 ! CHECK-DAG: ![[SUB1:.*]] = !{![[R1]]}
 ! CHECK-DAG: ![[D1TY:.*]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[INT]], elements: ![[SUB1]])
 
-! CHECK-DAG: ![[R21:.*]] = !DISubrange(count: 2, lowerBound: 1)
-! CHECK-DAG: ![[R22:.*]] = !DISubrange(count: 5, lowerBound: 1)
+! CHECK-DAG: ![[R21:.*]] = !DISubrange(count: 4, lowerBound: 1)
+! CHECK-DAG: ![[R22:.*]] = !DISubrange(count: 5, lowerBound: -1)
 ! CHECK-DAG: ![[SUB2:.*]] = !{![[R21]], ![[R22]]}
 ! CHECK-DAG: ![[D2TY:.*]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[INT]], elements: ![[SUB2]])
 
-! CHECK-DAG: ![[R31:.*]] = !DISubrange(count: 6, lowerBound: 1)
-! CHECK-DAG: ![[R32:.*]] = !DISubrange(count: 8, lowerBound: 1)
-! CHECK-DAG: ![[R33:.*]] = !DISubrange(count: 7, lowerBound: 1)
+! CHECK-DAG: ![[R31:.*]] = !DISubrange(count: 9, lowerBound: -2)
+! CHECK-DAG: ![[R32:.*]] = !DISubrange(count: 6, lowerBound: 0)
+! CHECK-DAG: ![[R33:.*]] = !DISubrange(count: 5, lowerBound: 3)
 ! CHECK-DAG: ![[SUB3:.*]] = !{![[R31]], ![[R32]], ![[R33]]}
 ! CHECK-DAG: ![[D3TY:.*]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[REAL]], elements: ![[SUB3]])
 
+! CHECK-DAG: ![[B11:.*]] = !DISubrange(count: 2, lowerBound: -1)
+! CHECK-DAG: ![[B12:.*]] = !DISubrange(count: 5, lowerBound: 5)
+! CHECK-DAG: ![[B1:.*]] = !{![[B11]], ![[B12]]}
+! CHECK-DAG: ![[B1TY:.*]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[INT]], elements: ![[B1]])
+
+! CHECK-DAG: {{.*}}!DIGlobalVariable(name: "d1"{{.*}}type: ![[D1TY]]{{.*}})
+! CHECK-DAG: {{.*}}!DIGlobalVariable(name: "d2"{{.*}}type: ![[D2TY]]{{.*}})
+! CHECK-DAG: {{.*}}!DIGlobalVariable(name: "d3"{{.*}}type: ![[D3TY]]{{.*}})
+
 ! CHECK-DAG: !DILocalVariable(name: "a1", arg: 1{{.*}}type: ![[D1TY]])
-! CHECK-DAG: !DILocalVariable(name: "b1", arg: 2{{.*}}type: ![[D2TY]])
+! CHECK-DAG: !DILocalVariable(name: "b1", arg: 2{{.*}}type: ![[B1TY]])
 ! CHECK-DAG: !DILocalVariable(name: "c1", arg: 3{{.*}}type: ![[D3TY]])

diff  --git a/flang/test/Transforms/debug-fixed-array-type.fir b/flang/test/Transforms/debug-fixed-array-type.fir
index d4ed0b97020898..1a7d8115908a07 100644
--- a/flang/test/Transforms/debug-fixed-array-type.fir
+++ b/flang/test/Transforms/debug-fixed-array-type.fir
@@ -8,12 +8,16 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
     %c5 = arith.constant 5 : index
     %c2 = arith.constant 2 : index
     %c3 = arith.constant 3 : index
+    %c-2 = arith.constant -2 : index loc(#loc3)
+    %c4 = arith.constant 4 : index loc(#loc3)
     %0 = fir.alloca !fir.array<3xi32> {bindc_name = "d1", uniq_name = "_QFEd1"}
     %1 = fircg.ext_declare %0(%c3) {uniq_name = "_QFEd1"} : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<!fir.array<3xi32>> loc(#loc1)
     %2 = fir.address_of(@_QFEd2) : !fir.ref<!fir.array<2x5xi32>>
     %3 = fircg.ext_declare %2(%c2, %c5) {uniq_name = "_QFEd2"} : (!fir.ref<!fir.array<2x5xi32>>, index, index) -> !fir.ref<!fir.array<2x5xi32>> loc(#loc2)
     %4 = fir.address_of(@_QFEd3) : !fir.ref<!fir.array<6x8x7xf32>>
     %5 = fircg.ext_declare %4(%c6, %c8, %c7) {uniq_name = "_QFEd3"} : (!fir.ref<!fir.array<6x8x7xf32>>, index, index, index) -> !fir.ref<!fir.array<6x8x7xf32>> loc(#loc3)
+    %6 = fir.address_of(@_QFEd4) : !fir.ref<!fir.array<6x7xi32>>
+    %7 = fircg.ext_declare %6(%c6, %c7) origin %c-2, %c4 {uniq_name = "_QFEd4"} : (!fir.ref<!fir.array<6x7xi32>>, index, index, index, index) -> !fir.ref<!fir.array<6x7xi32>> loc(#loc5)
     return
   } loc(#loc4)
 }
@@ -22,6 +26,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
 #loc2 = loc("test.f90":6:11)
 #loc3 = loc("test.f90":7:11)
 #loc4 = loc("test.f90":2:8)
+#loc5 = loc("test.f90":8:11)
 
 
 // CHECK-DAG: #[[INT:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer", sizeInBits = 32, encoding = DW_ATE_signed>
@@ -29,6 +34,8 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
 // CHECK-DAG: #[[D1TY:.*]] = #llvm.di_composite_type<tag = DW_TAG_array_type{{.*}}baseType = #[[INT]], elements = #llvm.di_subrange<count = 3 : i64, lowerBound = 1 : i64>>
 // CHECK-DAG: #[[D2TY:.*]] = #llvm.di_composite_type<tag = DW_TAG_array_type{{.*}}baseType = #[[INT]], elements = #llvm.di_subrange<count = 2 : i64, lowerBound = 1 : i64>, #llvm.di_subrange<count = 5 : i64, lowerBound = 1 : i64>>
 // CHECK-DAG: #[[D3TY:.*]] = #llvm.di_composite_type<tag = DW_TAG_array_type{{.*}}baseType = #[[REAL]], elements = #llvm.di_subrange<count = 6 : i64, lowerBound = 1 : i64>, #llvm.di_subrange<count = 8 : i64, lowerBound = 1 : i64>, #llvm.di_subrange<count = 7 : i64, lowerBound = 1 : i64>>
+// CHECK-DAG: #[[D4TY:.*]] = #llvm.di_composite_type<tag = DW_TAG_array_type, baseType = #di_basic_type, elements = #llvm.di_subrange<count = 6 : i64, lowerBound = -2 : i64>, #llvm.di_subrange<count = 7 : i64, lowerBound = 4 : i64>>
 // CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "d1"{{.*}}type = #[[D1TY]]>
 // CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "d2"{{.*}}type = #[[D2TY]]>
 // CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "d3"{{.*}}type = #[[D3TY]]>
+// CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "d4"{{.*}}type = #[[D4TY]]>


        


More information about the flang-commits mailing list