[flang-commits] [flang] [flang][debug] Support complex types. (PR #92559)

Abid Qadeer via flang-commits flang-commits at lists.llvm.org
Tue May 21 05:17:52 PDT 2024


https://github.com/abidh updated https://github.com/llvm/llvm-project/pull/92559

>From 548ebd52b6367e87e48b970356ce0c7c6fbabe70 Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Fri, 17 May 2024 15:29:35 +0100
Subject: [PATCH 1/4] [flang][debug] Support complex types.

This PR adds supports for conversion of complex type to corresponding
DITypeAttr. Both fir and mlir types are supported.

Apart from lit testing, I have also tested the types in debugger and
they work correctly. An exception is 128 bit complex which somehow
requires that its name be different from `complex`. I am going to open
a separate PR to add (kind=n) in the type names similar to what
gfortran does.
---
 .../Transforms/DebugTypeGenerator.cpp         | 10 +++++
 flang/test/Transforms/debug-complex-1.fir     | 39 +++++++++++++++++++
 flang/test/Transforms/debug-complex-2.f90     | 39 +++++++++++++++++++
 3 files changed, 88 insertions(+)
 create mode 100644 flang/test/Transforms/debug-complex-1.fir
 create mode 100644 flang/test/Transforms/debug-complex-2.f90

diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
index 64c6547e06e0f..ad6e4813ef820 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
@@ -57,6 +57,16 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
                         mlir::StringAttr::get(context, logTy.getMnemonic()),
                         kindMapping.getLogicalBitsize(logTy.getFKind()),
                         llvm::dwarf::DW_ATE_boolean);
+  } else if (fir::isa_complex(Ty)) {
+    unsigned bitWidth;
+    if (auto cplxTy = mlir::dyn_cast_or_null<mlir::ComplexType>(Ty)) {
+      auto floatTy = mlir::cast<mlir::FloatType>(cplxTy.getElementType());
+      bitWidth = floatTy.getWidth();
+    } else if (auto cplxTy = mlir::dyn_cast_or_null<fir::ComplexType>(Ty))
+      bitWidth = kindMapping.getRealBitsize(cplxTy.getFKind());
+
+    return genBasicType(context, mlir::StringAttr::get(context, "complex"),
+                        bitWidth * 2, llvm::dwarf::DW_ATE_complex_float);
   } else {
     // FIXME: These types are currently unhandled. We are generating a
     // placeholder type to allow us to test supported bits.
diff --git a/flang/test/Transforms/debug-complex-1.fir b/flang/test/Transforms/debug-complex-1.fir
new file mode 100644
index 0000000000000..fe50da5914476
--- /dev/null
+++ b/flang/test/Transforms/debug-complex-1.fir
@@ -0,0 +1,39 @@
+// RUN: fir-opt --cg-rewrite="preserve-declare=true" --mlir-print-debuginfo %s | fir-opt --add-debug-info --mlir-print-debuginfo | FileCheck %s
+
+// check conversion of complex type of different size. Both fir and mlir
+// variants are checked.
+
+module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.target_triple = "native"} {
+  func.func @test1(%x : !fir.complex<4>) -> !fir.complex<8> {
+  %1 = fir.convert %x : (!fir.complex<4>) -> !fir.complex<8>
+  return %1 : !fir.complex<8>
+  }loc(#loc1)
+  func.func @test2(%x : !fir.complex<4>) -> complex<f64> {
+  %1 = fir.convert %x : (!fir.complex<4>) -> complex<f64>
+  return %1 : complex<f64>
+  }loc(#loc2)
+  func.func @test3(%x : !fir.complex<4>) -> !fir.complex<16> {
+  %1 = fir.convert %x : (!fir.complex<4>) -> !fir.complex<16>
+  return %1 : !fir.complex<16>
+  }loc(#loc3)
+  func.func @test4(%x : !fir.complex<4>) -> complex<f128> {
+  %1 = fir.convert %x : (!fir.complex<4>) -> complex<f128>
+  return %1 : complex<f128>
+  }loc(#loc4)
+}
+#loc1 = loc("./simple.f90":2:1)
+#loc2 = loc("./simple.f90":5:1)
+#loc3 = loc("./simple.f90":8:1)
+#loc4 = loc("./simple.f90":11:1)
+
+// CHECK-DAG: #[[CMPX8:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "complex", sizeInBits = 128, encoding = DW_ATE_complex_float>
+// CHECK-DAG: #[[CMPX4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "complex", sizeInBits = 64, encoding = DW_ATE_complex_float>
+// CHECK-DAG: #[[CMPX16:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "complex", sizeInBits = 256, encoding = DW_ATE_complex_float>
+
+// CHECK-DAG: #[[TY1:.*]] = #llvm.di_subroutine_type<{{.*}}types = #[[CMPX8]], #[[CMPX4]]>
+// CHECK-DAG: #[[TY2:.*]] = #llvm.di_subroutine_type<{{.*}}types = #[[CMPX16]], #[[CMPX4]]>
+
+// CHECK-DAG: #llvm.di_subprogram<{{.*}}name = "test1"{{.*}}type = #[[TY1]]>
+// CHECK-DAG: #llvm.di_subprogram<{{.*}}name = "test2"{{.*}}type = #[[TY1]]>
+// CHECK-DAG: #llvm.di_subprogram<{{.*}}name = "test3"{{.*}}type = #[[TY2]]>
+// CHECK-DAG: #llvm.di_subprogram<{{.*}}name = "test4"{{.*}}type = #[[TY2]]>
diff --git a/flang/test/Transforms/debug-complex-2.f90 b/flang/test/Transforms/debug-complex-2.f90
new file mode 100644
index 0000000000000..9d44a80a9e34d
--- /dev/null
+++ b/flang/test/Transforms/debug-complex-2.f90
@@ -0,0 +1,39 @@
+! RUN: %flang_fc1 -emit-fir -debug-info-kind=standalone -mmlir --mlir-print-debuginfo %s -o - | \
+! RUN: fir-opt --cg-rewrite="preserve-declare=true" --mlir-print-debuginfo | fir-opt --add-debug-info --mlir-print-debuginfo | FileCheck %s
+! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck  --check-prefix=LLVM %s
+
+program mn
+  complex(kind=4) :: c4
+  complex(kind=8) :: c8
+  complex(kind=16) :: r
+  r = fn1(c4, c8)
+  print *, r
+contains
+  function fn1(a, b) result (c)
+    complex(kind=4), intent(in) :: a
+    complex(kind=8), intent(in) :: b
+    complex(kind=16) :: c
+    c = a + b
+  end function
+end program
+
+! CHECK-DAG: #[[CMPX4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "complex", sizeInBits = 64, encoding = DW_ATE_complex_float>
+! CHECK-DAG: #[[CMPX8:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "complex", sizeInBits = 128, encoding = DW_ATE_complex_float>
+! CHECK-DAG: #[[CMPX16:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "complex", sizeInBits = 256, encoding = DW_ATE_complex_float>
+
+! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "c4"{{.*}}type = #[[CMPX4]]>
+! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "c8"{{.*}}type = #[[CMPX8]]>
+! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "r"{{.*}}type = #[[CMPX16]]>
+! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "a"{{.*}}type = #[[CMPX4]]>
+! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "b"{{.*}}type = #[[CMPX8]]>
+! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "c"{{.*}}type = #[[CMPX16]]>
+
+! LLVM-DAG: ![[C4:.*]] = !DIBasicType(name: "complex", size: 64, encoding: DW_ATE_complex_float)
+! LLVM-DAG: ![[C8:.*]] = !DIBasicType(name: "complex", size: 128, encoding: DW_ATE_complex_float)
+! LLVM-DAG: ![[C16:.*]] = !DIBasicType(name: "complex", size: 256, encoding: DW_ATE_complex_float)
+! LLVM-DAG: !DILocalVariable(name: "c4"{{.*}}type: ![[C4]])
+! LLVM-DAG: !DILocalVariable(name: "c8"{{.*}}type: ![[C8]])
+! LLVM-DAG: !DILocalVariable(name: "r"{{.*}}type: ![[C16]])
+! LLVM-DAG: !DILocalVariable(name: "a"{{.*}}type: ![[C4]])
+! LLVM-DAG: !DILocalVariable(name: "b"{{.*}}type: ![[C8]])
+! LLVM-DAG: !DILocalVariable(name: "c"{{.*}}type: ![[C16]])

>From 9725619e4d3523a304d431a8b248a04a7e33bed8 Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Mon, 20 May 2024 11:32:51 +0100
Subject: [PATCH 2/4] Move LLVM IR tests to integration folder. (NFC)

---
 flang/test/Integration/debug-complex-1.f90 | 26 ++++++++++++++++++++++
 flang/test/Transforms/debug-complex-2.f90  | 11 ---------
 2 files changed, 26 insertions(+), 11 deletions(-)
 create mode 100644 flang/test/Integration/debug-complex-1.f90

diff --git a/flang/test/Integration/debug-complex-1.f90 b/flang/test/Integration/debug-complex-1.f90
new file mode 100644
index 0000000000000..c8d0da4c4baa2
--- /dev/null
+++ b/flang/test/Integration/debug-complex-1.f90
@@ -0,0 +1,26 @@
+! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck  %s
+
+program mn
+  complex(kind=4) :: c4
+  complex(kind=8) :: c8
+  complex(kind=16) :: r
+  r = fn1(c4, c8)
+  print *, r
+contains
+  function fn1(a, b) result (c)
+    complex(kind=4), intent(in) :: a
+    complex(kind=8), intent(in) :: b
+    complex(kind=16) :: c
+    c = a + b
+  end function
+end program
+
+! CHECK-DAG: ![[C4:.*]] = !DIBasicType(name: "complex", size: 64, encoding: DW_ATE_complex_float)
+! CHECK-DAG: ![[C8:.*]] = !DIBasicType(name: "complex", size: 128, encoding: DW_ATE_complex_float)
+! CHECK-DAG: ![[C16:.*]] = !DIBasicType(name: "complex", size: 256, encoding: DW_ATE_complex_float)
+! CHECK-DAG: !DILocalVariable(name: "c4"{{.*}}type: ![[C4]])
+! CHECK-DAG: !DILocalVariable(name: "c8"{{.*}}type: ![[C8]])
+! CHECK-DAG: !DILocalVariable(name: "r"{{.*}}type: ![[C16]])
+! CHECK-DAG: !DILocalVariable(name: "a"{{.*}}type: ![[C4]])
+! CHECK-DAG: !DILocalVariable(name: "b"{{.*}}type: ![[C8]])
+! CHECK-DAG: !DILocalVariable(name: "c"{{.*}}type: ![[C16]])
diff --git a/flang/test/Transforms/debug-complex-2.f90 b/flang/test/Transforms/debug-complex-2.f90
index 9d44a80a9e34d..bb73ad50287ef 100644
--- a/flang/test/Transforms/debug-complex-2.f90
+++ b/flang/test/Transforms/debug-complex-2.f90
@@ -1,6 +1,5 @@
 ! RUN: %flang_fc1 -emit-fir -debug-info-kind=standalone -mmlir --mlir-print-debuginfo %s -o - | \
 ! RUN: fir-opt --cg-rewrite="preserve-declare=true" --mlir-print-debuginfo | fir-opt --add-debug-info --mlir-print-debuginfo | FileCheck %s
-! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck  --check-prefix=LLVM %s
 
 program mn
   complex(kind=4) :: c4
@@ -27,13 +26,3 @@ function fn1(a, b) result (c)
 ! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "a"{{.*}}type = #[[CMPX4]]>
 ! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "b"{{.*}}type = #[[CMPX8]]>
 ! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "c"{{.*}}type = #[[CMPX16]]>
-
-! LLVM-DAG: ![[C4:.*]] = !DIBasicType(name: "complex", size: 64, encoding: DW_ATE_complex_float)
-! LLVM-DAG: ![[C8:.*]] = !DIBasicType(name: "complex", size: 128, encoding: DW_ATE_complex_float)
-! LLVM-DAG: ![[C16:.*]] = !DIBasicType(name: "complex", size: 256, encoding: DW_ATE_complex_float)
-! LLVM-DAG: !DILocalVariable(name: "c4"{{.*}}type: ![[C4]])
-! LLVM-DAG: !DILocalVariable(name: "c8"{{.*}}type: ![[C8]])
-! LLVM-DAG: !DILocalVariable(name: "r"{{.*}}type: ![[C16]])
-! LLVM-DAG: !DILocalVariable(name: "a"{{.*}}type: ![[C4]])
-! LLVM-DAG: !DILocalVariable(name: "b"{{.*}}type: ![[C8]])
-! LLVM-DAG: !DILocalVariable(name: "c"{{.*}}type: ![[C16]])

>From 5ef9735ac8567731dcb57d3546fee27b67e108f5 Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Mon, 20 May 2024 12:46:00 +0100
Subject: [PATCH 3/4] Handle review comments.

---
 flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
index ad6e4813ef820..372b6c0052262 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
@@ -62,9 +62,9 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
     if (auto cplxTy = mlir::dyn_cast_or_null<mlir::ComplexType>(Ty)) {
       auto floatTy = mlir::cast<mlir::FloatType>(cplxTy.getElementType());
       bitWidth = floatTy.getWidth();
-    } else if (auto cplxTy = mlir::dyn_cast_or_null<fir::ComplexType>(Ty))
+    } else if (auto cplxTy = mlir::dyn_cast_or_null<fir::ComplexType>(Ty)) {
       bitWidth = kindMapping.getRealBitsize(cplxTy.getFKind());
-
+    }
     return genBasicType(context, mlir::StringAttr::get(context, "complex"),
                         bitWidth * 2, llvm::dwarf::DW_ATE_complex_float);
   } else {

>From c81e07e5d93ccb2e10f48ad689b25e524b700fd2 Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Tue, 21 May 2024 13:06:00 +0100
Subject: [PATCH 4/4] Handle review comments

1. Remove the fortran testcase as it was redundant.
2. Remove redundant command from RUN line.
3. Add an llvm_unreachable if we get a complex type which is not
   fir or mlir complex type.
---
 .../Transforms/DebugTypeGenerator.cpp         |  2 ++
 flang/test/Transforms/debug-complex-1.fir     |  2 +-
 flang/test/Transforms/debug-complex-2.f90     | 28 -------------------
 3 files changed, 3 insertions(+), 29 deletions(-)
 delete mode 100644 flang/test/Transforms/debug-complex-2.f90

diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
index 372b6c0052262..1e46d5ac255ec 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
@@ -64,6 +64,8 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
       bitWidth = floatTy.getWidth();
     } else if (auto cplxTy = mlir::dyn_cast_or_null<fir::ComplexType>(Ty)) {
       bitWidth = kindMapping.getRealBitsize(cplxTy.getFKind());
+    } else {
+      llvm_unreachable("Unhandled complex type");
     }
     return genBasicType(context, mlir::StringAttr::get(context, "complex"),
                         bitWidth * 2, llvm::dwarf::DW_ATE_complex_float);
diff --git a/flang/test/Transforms/debug-complex-1.fir b/flang/test/Transforms/debug-complex-1.fir
index fe50da5914476..a3cbd767d8a58 100644
--- a/flang/test/Transforms/debug-complex-1.fir
+++ b/flang/test/Transforms/debug-complex-1.fir
@@ -1,4 +1,4 @@
-// RUN: fir-opt --cg-rewrite="preserve-declare=true" --mlir-print-debuginfo %s | fir-opt --add-debug-info --mlir-print-debuginfo | FileCheck %s
+// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
 
 // check conversion of complex type of different size. Both fir and mlir
 // variants are checked.
diff --git a/flang/test/Transforms/debug-complex-2.f90 b/flang/test/Transforms/debug-complex-2.f90
deleted file mode 100644
index bb73ad50287ef..0000000000000
--- a/flang/test/Transforms/debug-complex-2.f90
+++ /dev/null
@@ -1,28 +0,0 @@
-! RUN: %flang_fc1 -emit-fir -debug-info-kind=standalone -mmlir --mlir-print-debuginfo %s -o - | \
-! RUN: fir-opt --cg-rewrite="preserve-declare=true" --mlir-print-debuginfo | fir-opt --add-debug-info --mlir-print-debuginfo | FileCheck %s
-
-program mn
-  complex(kind=4) :: c4
-  complex(kind=8) :: c8
-  complex(kind=16) :: r
-  r = fn1(c4, c8)
-  print *, r
-contains
-  function fn1(a, b) result (c)
-    complex(kind=4), intent(in) :: a
-    complex(kind=8), intent(in) :: b
-    complex(kind=16) :: c
-    c = a + b
-  end function
-end program
-
-! CHECK-DAG: #[[CMPX4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "complex", sizeInBits = 64, encoding = DW_ATE_complex_float>
-! CHECK-DAG: #[[CMPX8:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "complex", sizeInBits = 128, encoding = DW_ATE_complex_float>
-! CHECK-DAG: #[[CMPX16:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "complex", sizeInBits = 256, encoding = DW_ATE_complex_float>
-
-! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "c4"{{.*}}type = #[[CMPX4]]>
-! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "c8"{{.*}}type = #[[CMPX8]]>
-! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "r"{{.*}}type = #[[CMPX16]]>
-! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "a"{{.*}}type = #[[CMPX4]]>
-! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "b"{{.*}}type = #[[CMPX8]]>
-! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "c"{{.*}}type = #[[CMPX16]]>



More information about the flang-commits mailing list