[flang-commits] [flang] 9af92ed - [mlir:LLVM] Rewrite the LLVMIR export to use the debug info attributes

River Riddle via flang-commits flang-commits at lists.llvm.org
Mon Oct 24 22:31:56 PDT 2022


Author: River Riddle
Date: 2022-10-24T22:31:41-07:00
New Revision: 9af92ed8a0da2c35773708dc7a23cd8e56557e2d

URL: https://github.com/llvm/llvm-project/commit/9af92ed8a0da2c35773708dc7a23cd8e56557e2d
DIFF: https://github.com/llvm/llvm-project/commit/9af92ed8a0da2c35773708dc7a23cd8e56557e2d.diff

LOG: [mlir:LLVM] Rewrite the LLVMIR export to use the debug info attributes

This has been a long standing TODO, and actually enables users to generate
debug information for LLVM using the LLVM dialect; as opposed to our
dummy placeholder that generated just enough for line table information.

Differential Revision: https://reviews.llvm.org/D136543

Added: 
    

Modified: 
    flang/test/Driver/emit-asm-aarch64.f90
    flang/test/Driver/emit-asm-x86.f90
    flang/test/Fir/embox.fir
    flang/test/Fir/ignore-missing-type-descriptor.fir
    flang/test/Lower/OpenMP/omp-ordered-threads.f90
    mlir/docs/Dialects/LLVM.md
    mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
    mlir/include/mlir/IR/Location.h
    mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
    mlir/lib/IR/Diagnostics.cpp
    mlir/lib/Target/LLVMIR/DebugTranslation.cpp
    mlir/lib/Target/LLVMIR/DebugTranslation.h
    mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
    mlir/test/Target/LLVMIR/llvmir-debug.mlir
    mlir/test/Target/LLVMIR/llvmir.mlir
    mlir/test/Target/LLVMIR/openmp-llvm.mlir
    mlir/test/Target/LLVMIR/openmp-nested.mlir

Removed: 
    


################################################################################
diff  --git a/flang/test/Driver/emit-asm-aarch64.f90 b/flang/test/Driver/emit-asm-aarch64.f90
index 3713fa04cc0ff..078713329223a 100644
--- a/flang/test/Driver/emit-asm-aarch64.f90
+++ b/flang/test/Driver/emit-asm-aarch64.f90
@@ -6,7 +6,6 @@
 ! RUN: %flang -S -target aarch64-unknown-linux-gnu %s -o - | FileCheck %s
 
 ! CHECK-LABEL: _QQmain:
-! CHECK-NEXT: .Lfunc_begin0:
 ! CHECK: ret
 
 end program

diff  --git a/flang/test/Driver/emit-asm-x86.f90 b/flang/test/Driver/emit-asm-x86.f90
index 47b1e10c63d95..124289bbb27d7 100644
--- a/flang/test/Driver/emit-asm-x86.f90
+++ b/flang/test/Driver/emit-asm-x86.f90
@@ -6,7 +6,6 @@
 ! RUN: %flang -S -target x86_64-unknown-linux-gnu %s -o - | FileCheck %s
 
 ! CHECK-LABEL: _QQmain:
-! CHECK-NEXT: .Lfunc_begin0:
 ! CHECK: ret
 
 end program

diff  --git a/flang/test/Fir/embox.fir b/flang/test/Fir/embox.fir
index f5e37fbd77d9d..65a536d10c472 100644
--- a/flang/test/Fir/embox.fir
+++ b/flang/test/Fir/embox.fir
@@ -9,14 +9,14 @@ func.func @_QPtest_callee(%arg0: !fir.box<!fir.array<?xi32>>) {
 
 // CHECK-LABEL: define void @_QPtest_slice()
 func.func @_QPtest_slice() {
-// CHECK:  %[[a1:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, align 8,
-// CHECK:  %[[a2:.*]] = alloca [20 x i32], i64 1, align 4,
-// CHECK:  %[[a3:.*]] = getelementptr [20 x i32], ptr %[[a2]], i64 0, i64 0,
+// CHECK:  %[[a1:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, align 8
+// CHECK:  %[[a2:.*]] = alloca [20 x i32], i64 1, align 4
+// CHECK:  %[[a3:.*]] = getelementptr [20 x i32], ptr %[[a2]], i64 0, i64 0
 // CHECK:  %[[a4:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
 // CHECK:  { ptr undef, i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i32 20180515, i8 1, i8 9, i8 0, i8 0, [1 x [3 x i64]]
-// CHECK: [i64 1, i64 5, i64 mul (i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i64 2)]] }, ptr %[[a3]], 0,
+// CHECK: [i64 1, i64 5, i64 mul (i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i64 2)]] }, ptr %[[a3]], 0
 // CHECK:  store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[a4]], ptr %[[a1]], align 8
-// CHECK:  call void @_QPtest_callee(ptr %[[a1]]),
+// CHECK:  call void @_QPtest_callee(ptr %[[a1]])
   %c20 = arith.constant 20 : index
   %c1_i64 = arith.constant 1 : i64
   %c10_i64 = arith.constant 10 : i64
@@ -36,17 +36,17 @@ func.func @_QPtest_dt_callee(%arg0: !fir.box<!fir.array<?xi32>>) {
 
 // CHECK-LABEL: define void @_QPtest_dt_slice()
 func.func @_QPtest_dt_slice() {
-// CHECK:  %[[a1:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, align 8,
-// CHECK:  %[[a3:.*]] = alloca [20 x %_QFtest_dt_sliceTt], i64 1, align 8,
-// CHECK:  %[[a4:.*]] = getelementptr [20 x %_QFtest_dt_sliceTt], ptr %[[a3]], i64 0, i64 0, i32 0,
+// CHECK:  %[[a1:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, align 8
+// CHECK:  %[[a3:.*]] = alloca [20 x %_QFtest_dt_sliceTt], i64 1, align 8
+// CHECK:  %[[a4:.*]] = getelementptr [20 x %_QFtest_dt_sliceTt], ptr %[[a3]], i64 0, i64 0, i32 0
 // CHECK: %[[a5:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
 // CHECK-SAME: { ptr undef, i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i32 20180515, i8 1, i8 9, i8 0, i8 0, [1 x [3 x i64]]
 // CHECK-SAME: [i64 1, i64 5, i64 mul
 // CHECK-SAME: (i64 ptrtoint (ptr getelementptr (%_QFtest_dt_sliceTt, ptr null, i32 1) to i64), i64 2)]] }
 // CHECK-SAME: , ptr %[[a4]], 0
 
-// CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[a5]], ptr %[[a1]], align 8,
-// CHECK:  call void @_QPtest_dt_callee(ptr %[[a1]]),
+// CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[a5]], ptr %[[a1]], align 8
+// CHECK:  call void @_QPtest_dt_callee(ptr %[[a1]])
   %c20 = arith.constant 20 : index
   %c1_i64 = arith.constant 1 : i64
   %c10_i64 = arith.constant 10 : i64
@@ -75,8 +75,8 @@ func.func @emboxSubstring(%arg0: !fir.ref<!fir.array<2x3x!fir.char<1,4>>>) {
   %1 = fir.slice %c1, %c2, %c1, %c1, %c3, %c1 substr %c1_i64, %c2_i64 : (index, index, index, index, index, index, i64, i64) -> !fir.slice<2>
   %2 = fir.embox %arg0(%0) [%1] : (!fir.ref<!fir.array<2x3x!fir.char<1,4>>>, !fir.shape<2>, !fir.slice<2>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
   // CHECK: %[[addr:.*]] = getelementptr [3 x [2 x [4 x i8]]], ptr %[[arg0]], i64 0, i64 0, i64 0, i64 1
-  // CHECK: insertvalue {[[descriptorType:.*]]} { ptr undef, i64 mul (i64 ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64), i64 2), i32 20180515, i8 2, i8 40, i8 0, i8 0,
-  // CHECK-SAME: [2 x [3 x i64]] [{{\[}}3 x i64] [i64 1, i64 2, i64 4], [3 x i64] [i64 1, i64 3, i64 8]] },
+  // CHECK: insertvalue {[[descriptorType:.*]]} { ptr undef, i64 mul (i64 ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64), i64 2), i32 20180515, i8 2, i8 40, i8 0, i8 0
+  // CHECK-SAME: [2 x [3 x i64]] [{{\[}}3 x i64] [i64 1, i64 2, i64 4], [3 x i64] [i64 1, i64 3, i64 8]] }
   // CHECK-SAME: ptr %[[addr]], 0
 
   fir.call @takesRank2CharBox(%2) : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> ()

diff  --git a/flang/test/Fir/ignore-missing-type-descriptor.fir b/flang/test/Fir/ignore-missing-type-descriptor.fir
index 14b210f5a0de7..f55ea1238e47b 100644
--- a/flang/test/Fir/ignore-missing-type-descriptor.fir
+++ b/flang/test/Fir/ignore-missing-type-descriptor.fir
@@ -19,4 +19,4 @@ func.func @test_embox(%addr: !fir.ref<!some_freestyle_type>) {
 // CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }
 // CHECK-SAME: { ptr undef, i64 ptrtoint (ptr getelementptr (%some_not_mangled_type, ptr null, i32 1) to i64),
 // CHECK-SAME: i32 20180515, i8 0, i8 42, i8 0, i8 1, ptr null, [1 x i64] undef },
-// CHECK-SAME: ptr %[[ADDR]], 0,
+// CHECK-SAME: ptr %[[ADDR]], 0

diff  --git a/flang/test/Lower/OpenMP/omp-ordered-threads.f90 b/flang/test/Lower/OpenMP/omp-ordered-threads.f90
index 263832cdcc3da..3b896d24ea6d2 100644
--- a/flang/test/Lower/OpenMP/omp-ordered-threads.f90
+++ b/flang/test/Lower/OpenMP/omp-ordered-threads.f90
@@ -12,29 +12,29 @@ subroutine ordered
 
 !FIRDialect: omp.ordered_region  {
 !LLVMIRDialect: omp.ordered_region  {
-!LLVMIR: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB0:[0-9]+]]), !dbg !{{.*}}
-!LLVMIR-NEXT: call void @__kmpc_ordered(ptr @[[GLOB0]], i32 [[TMP0]]), !dbg !{{.*}}
+!LLVMIR: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB0:[0-9]+]])
+!LLVMIR-NEXT: call void @__kmpc_ordered(ptr @[[GLOB0]], i32 [[TMP0]])
 !$OMP ORDERED
         a(i) = a(i-1) + 1
 !FIRDialect:   omp.terminator
 !FIRDialect-NEXT: }
 !LLVMIRDialect:   omp.terminator
 !LLVMIRDialect-NEXT: }
-!LLVMIR: call void @__kmpc_end_ordered(ptr @[[GLOB0]], i32 [[TMP0]]), !dbg !{{.*}}
+!LLVMIR: call void @__kmpc_end_ordered(ptr @[[GLOB0]], i32 [[TMP0]])
 !$OMP END ORDERED
 
 !FIRDialect: omp.ordered_region  {
 !LLVMIRDialect: omp.ordered_region  {
-!LLVMIR: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]]), !dbg !{{.*}}
-!LLVMIR-NEXT: call void @__kmpc_ordered(ptr @[[GLOB1]], i32 [[TMP1]]), !dbg !{{.*}}
+!LLVMIR: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]])
+!LLVMIR-NEXT: call void @__kmpc_ordered(ptr @[[GLOB1]], i32 [[TMP1]])
 !$OMP ORDERED THREADS
         a(i) = a(i-1) + 1
 !FIRDialect:   omp.terminator
 !FIRDialect-NEXT: }
 !LLVMIRDialect:   omp.terminator
 !LLVMIRDialect-NEXT: }
-!LLVMIR: call void @__kmpc_end_ordered(ptr @[[GLOB1]], i32 [[TMP1]]), !dbg !{{.*}}
-!LLVMIR-NEXT: ret void, !dbg !{{.*}}
+!LLVMIR: call void @__kmpc_end_ordered(ptr @[[GLOB1]], i32 [[TMP1]])
+!LLVMIR-NEXT: ret void
 !$OMP END ORDERED
 
 end

diff  --git a/mlir/docs/Dialects/LLVM.md b/mlir/docs/Dialects/LLVM.md
index d1f589baa977e..53d4dfbf686e7 100644
--- a/mlir/docs/Dialects/LLVM.md
+++ b/mlir/docs/Dialects/LLVM.md
@@ -482,3 +482,13 @@ modeled as first-class operations in the LLVM dialect. Target-specific LLVM IR
 intrinsics, e.g., NVVM or ROCDL, are modeled as separate dialects.
 
 [include "Dialects/LLVMIntrinsicOps.md"]
+
+### Debug Info
+
+Debug information within the LLVM dialect is represented using locations in
+combination with a set of attributes that mirror the DINode structure defined by
+the debug info metadata within LLVM IR. Debug scoping information is attached
+to LLVM IR dialect operations using a fused location (`FusedLoc`) whose metadata
+holds the DIScopeAttr representing the debug scope. Similarly, the subprogram
+of LLVM IR dialect `FuncOp` operations is attached using a fused location whose
+metadata is a DISubprogramAttr.

diff  --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
index d78efa5c608e7..efb60e2e03c1a 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
@@ -233,21 +233,37 @@ def LLVM_CoroResumeOp : LLVM_IntrOp<"coro.resume", [], [], [], 0> {
 // Debug function intrinsics.
 //
 
-def LLVM_DbgAddrOp : LLVM_Op<"dbg.addr"> {
+class LLVM_DbgIntrOp<string name> : LLVM_Op<name> {
+  let llvmBuilder = [{
+    llvm::Module *module = builder.GetInsertBlock()->getModule();
+    llvm::LLVMContext &ctx = module->getContext();
+    llvm::Function *fn =
+      llvm::Intrinsic::getDeclaration(module, llvm::Intrinsic::}]
+       # !subst(".", "_", name) # [{);
+    builder.CreateCall(fn, {
+        llvm::MetadataAsValue::get(ctx,
+            llvm::ValueAsMetadata::get(moduleTranslation.lookupValue(opInst.getOperand(0)))),
+        llvm::MetadataAsValue::get(ctx, moduleTranslation.translateDebugInfo($varInfo)),
+        llvm::MetadataAsValue::get(ctx, llvm::DIExpression::get(ctx, llvm::None)),
+      });
+  }];
+}
+
+def LLVM_DbgAddrOp : LLVM_DbgIntrOp<"dbg.addr"> {
   let summary = "Describe the current address of a local debug info variable.";
   let arguments = (ins LLVM_AnyPointer:$addr, LLVM_DILocalVariableAttr:$varInfo);
 
   let assemblyFormat = "qualified($varInfo) `=` $addr `:` type($addr) attr-dict";
 }
 
-def LLVM_DbgDeclareOp : LLVM_Op<"dbg.declare"> {
+def LLVM_DbgDeclareOp : LLVM_DbgIntrOp<"dbg.declare"> {
   let summary = "Declare the address of a local debug info variable.";
   let arguments = (ins LLVM_AnyPointer:$addr, LLVM_DILocalVariableAttr:$varInfo);
 
   let assemblyFormat = "qualified($varInfo) `=` $addr `:` type($addr) attr-dict";
 }
 
-def LLVM_DbgValueOp : LLVM_Op<"dbg.value"> {
+def LLVM_DbgValueOp : LLVM_DbgIntrOp<"dbg.value"> {
   let summary = "Describe the current value of a local debug info variable.";
   let arguments = (ins LLVM_Type:$value, LLVM_DILocalVariableAttr:$varInfo);
 

diff  --git a/mlir/include/mlir/IR/Location.h b/mlir/include/mlir/IR/Location.h
index 6691c2f769b9f..03f6e4e55896e 100644
--- a/mlir/include/mlir/IR/Location.h
+++ b/mlir/include/mlir/IR/Location.h
@@ -36,6 +36,21 @@ class LocationAttr : public Attribute {
   /// Walk all of the locations nested under, and including, the current.
   WalkResult walk(function_ref<WalkResult(Location)> walkFn);
 
+  /// Return an instance of the given location type if one is nested under the
+  /// current location. Returns nullptr if one could not be found.
+  template <typename T>
+  T findInstanceOf() {
+    T result = {};
+    walk([&](auto loc) {
+      if (auto typedLoc = llvm::dyn_cast<T>(loc)) {
+        result = typedLoc;
+        return WalkResult::interrupt();
+      }
+      return WalkResult::advance();
+    });
+    return result;
+  }
+
   /// Methods for support type inquiry through isa, cast, and dyn_cast.
   static bool classof(Attribute attr);
 };
@@ -118,6 +133,29 @@ inline ::llvm::hash_code hash_value(Location arg) {
 
 namespace mlir {
 
+//===----------------------------------------------------------------------===//
+// FusedLoc
+//===----------------------------------------------------------------------===//
+
+/// This class represents a fused location whose metadata is known to be an
+/// instance of the given type.
+template <typename MetadataT>
+class FusedLocWith : public FusedLoc {
+public:
+  using FusedLoc::FusedLoc;
+
+  /// Return the metadata associated with this fused location.
+  MetadataT getMetadata() const {
+    return FusedLoc::getMetadata().template cast<MetadataT>();
+  }
+
+  /// Support llvm style casting.
+  static bool classof(Attribute attr) {
+    auto fusedLoc = attr.dyn_cast<FusedLoc>();
+    return fusedLoc && fusedLoc.getMetadata().isa_and_nonnull<MetadataT>();
+  }
+};
+
 //===----------------------------------------------------------------------===//
 // OpaqueLoc
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
index 3dd0d769007c8..af84f8a2d7f67 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
@@ -42,6 +42,7 @@ namespace detail {
 class DebugTranslation;
 } // namespace detail
 
+class DINodeAttr;
 class LLVMFuncOp;
 
 /// Implementation class for module translation. Holds a reference to the module
@@ -175,6 +176,9 @@ class ModuleTranslation {
   /// Translates the given location.
   const llvm::DILocation *translateLoc(Location loc, llvm::DILocalScope *scope);
 
+  /// Translates the given LLVM debug info metadata.
+  llvm::Metadata *translateDebugInfo(LLVM::DINodeAttr attr);
+
   /// Translates the contents of the given block to LLVM IR using this
   /// translator. The LLVM IR basic block corresponding to the given block is
   /// expected to exist in the mapping of this translator. Uses `builder` to

diff  --git a/mlir/lib/IR/Diagnostics.cpp b/mlir/lib/IR/Diagnostics.cpp
index 14aa44f26064e..ca99c6caec61f 100644
--- a/mlir/lib/IR/Diagnostics.cpp
+++ b/mlir/lib/IR/Diagnostics.cpp
@@ -389,19 +389,6 @@ struct SourceMgrDiagnosticHandlerImpl {
 } // namespace detail
 } // namespace mlir
 
-/// Return a processable FileLineColLoc from the given location.
-static Optional<FileLineColLoc> getFileLineColLoc(Location loc) {
-  Optional<FileLineColLoc> firstFileLoc;
-  loc->walk([&](Location loc) {
-    if (FileLineColLoc fileLoc = loc.dyn_cast<FileLineColLoc>()) {
-      firstFileLoc = fileLoc;
-      return WalkResult::interrupt();
-    }
-    return WalkResult::advance();
-  });
-  return firstFileLoc;
-}
-
 /// Return a processable CallSiteLoc from the given location.
 static Optional<CallSiteLoc> getCallSiteLoc(Location loc) {
   if (auto nameLoc = dyn_cast<NameLoc>(loc))
@@ -454,7 +441,7 @@ void SourceMgrDiagnosticHandler::emitDiagnostic(Location loc, Twine message,
                                                 DiagnosticSeverity kind,
                                                 bool displaySourceLine) {
   // Extract a file location from this loc.
-  auto fileLoc = getFileLineColLoc(loc);
+  auto fileLoc = loc->findInstanceOf<FileLineColLoc>();
 
   // If one doesn't exist, then print the raw message without a source location.
   if (!fileLoc) {
@@ -469,7 +456,7 @@ void SourceMgrDiagnosticHandler::emitDiagnostic(Location loc, Twine message,
   // Otherwise if we are displaying the source line, try to convert the file
   // location to an SMLoc.
   if (displaySourceLine) {
-    auto smloc = convertLocToSMLoc(*fileLoc);
+    auto smloc = convertLocToSMLoc(fileLoc);
     if (smloc.isValid())
       return mgr.PrintMessage(os, smloc, getDiagKind(kind), message);
   }
@@ -479,8 +466,8 @@ void SourceMgrDiagnosticHandler::emitDiagnostic(Location loc, Twine message,
   // the constructor of SMDiagnostic that takes a location.
   std::string locStr;
   llvm::raw_string_ostream locOS(locStr);
-  locOS << fileLoc->getFilename().getValue() << ":" << fileLoc->getLine() << ":"
-        << fileLoc->getColumn();
+  locOS << fileLoc.getFilename().getValue() << ":" << fileLoc.getLine() << ":"
+        << fileLoc.getColumn();
   llvm::SMDiagnostic diag(locOS.str(), getDiagKind(kind), message.str());
   diag.print(nullptr, os);
 }
@@ -853,8 +840,8 @@ void SourceMgrDiagnosticVerifierHandler::process(Diagnostic &diag) {
   auto kind = diag.getSeverity();
 
   // Process a FileLineColLoc.
-  if (auto fileLoc = getFileLineColLoc(diag.getLocation()))
-    return process(*fileLoc, diag.str(), kind);
+  if (auto fileLoc = diag.getLocation()->findInstanceOf<FileLineColLoc>())
+    return process(fileLoc, diag.str(), kind);
 
   emitDiagnostic(diag.getLocation(),
                  "unexpected " + getDiagKindStr(kind) + ": " + diag.str(),

diff  --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
index 925a7dbe0215f..6de8febdd56a8 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
@@ -8,6 +8,7 @@
 
 #include "DebugTranslation.h"
 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "llvm/ADT/TypeSwitch.h"
 #include "llvm/IR/Metadata.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/FileSystem.h"
@@ -25,23 +26,15 @@ static WalkResult interruptIfValidLocation(Operation *op) {
 }
 
 DebugTranslation::DebugTranslation(Operation *module, llvm::Module &llvmModule)
-    : builder(llvmModule), llvmCtx(llvmModule.getContext()),
-      compileUnit(nullptr) {
-
+    : debugEmissionIsEnabled(false), llvmModule(llvmModule),
+      llvmCtx(llvmModule.getContext()) {
   // If the module has no location information, there is nothing to do.
   if (!module->walk(interruptIfValidLocation).wasInterrupted())
     return;
+  debugEmissionIsEnabled = true;
 
-  // TODO: Several parts of this are incorrect. Different source
-  // languages may interpret 
diff erent parts of the debug information
-  // 
diff erently. Frontends will also want to pipe in various information, like
-  // flags. This is fine for now as we only emit line-table information and not
-  // types or variables. This should disappear as the debug information story
-  // evolves; i.e. when we have proper attributes for LLVM debug metadata.
-  compileUnit = builder.createCompileUnit(
-      llvm::dwarf::DW_LANG_C,
-      builder.createFile(llvmModule.getModuleIdentifier(), "/"),
-      /*Producer=*/"mlir", /*isOptimized=*/true, /*Flags=*/"", /*RV=*/0);
+  // TODO: The version information should be encoded on the LLVM module itself,
+  // not implicitly set here.
 
   // Mark this module as having debug information.
   StringRef debugVersionKey = "Debug Info Version";
@@ -62,24 +55,11 @@ DebugTranslation::DebugTranslation(Operation *module, llvm::Module &llvmModule)
 }
 
 /// Finalize the translation of debug information.
-void DebugTranslation::finalize() { builder.finalize(); }
-
-/// Attempt to extract a filename for the given loc.
-static FileLineColLoc extractFileLoc(Location loc) {
-  if (auto fileLoc = loc.dyn_cast<FileLineColLoc>())
-    return fileLoc;
-  if (auto nameLoc = loc.dyn_cast<NameLoc>())
-    return extractFileLoc(nameLoc.getChildLoc());
-  if (auto opaqueLoc = loc.dyn_cast<OpaqueLoc>())
-    return extractFileLoc(opaqueLoc.getFallbackLocation());
-  return FileLineColLoc();
-}
+void DebugTranslation::finalize() {}
 
 /// Translate the debug information for the given function.
 void DebugTranslation::translate(LLVMFuncOp func, llvm::Function &llvmFunc) {
-  // If the function doesn't have location information, there is nothing to
-  // translate.
-  if (!compileUnit || !func.walk(interruptIfValidLocation).wasInterrupted())
+  if (!debugEmissionIsEnabled)
     return;
 
   // If we are to create debug info for the function, we need to ensure that all
@@ -96,23 +76,150 @@ void DebugTranslation::translate(LLVMFuncOp func, llvm::Function &llvmFunc) {
   if (hasCallWithoutDebugInfo)
     return;
 
-  FileLineColLoc fileLoc = extractFileLoc(func.getLoc());
-  auto *file =
-      translateFile(fileLoc ? fileLoc.getFilename().strref() : "<unknown>");
-  unsigned line = fileLoc ? fileLoc.getLine() : 0;
-
-  // TODO: This is the bare essentials for now. We will likely end
-  // up with wrapper metadata around LLVMs metadata in the future, so this
-  // doesn't need to be smart until then.
-  llvm::DISubroutineType *type =
-      builder.createSubroutineType(builder.getOrCreateTypeArray(llvm::None));
-  llvm::DISubprogram::DISPFlags spFlags = llvm::DISubprogram::SPFlagDefinition |
-                                          llvm::DISubprogram::SPFlagOptimized;
-  llvm::DISubprogram *program =
-      builder.createFunction(compileUnit, func.getName(), func.getName(), file,
-                             line, type, line, llvm::DINode::FlagZero, spFlags);
-  llvmFunc.setSubprogram(program);
-  builder.finalizeSubprogram(program);
+  // Look for a sub program attached to the function.
+  auto spLoc =
+      func.getLoc()->findInstanceOf<FusedLocWith<LLVM::DISubprogramAttr>>();
+  if (!spLoc)
+    return;
+  llvmFunc.setSubprogram(translate(spLoc.getMetadata()));
+}
+
+//===----------------------------------------------------------------------===//
+// Attributes
+//===----------------------------------------------------------------------===//
+
+llvm::DIBasicType *DebugTranslation::translateImpl(DIBasicTypeAttr attr) {
+  return llvm::DIBasicType::get(
+      llvmCtx, attr.getTag(), attr.getName(), attr.getSizeInBits(),
+      /*AlignInBits=*/0, attr.getEncoding(), llvm::DINode::FlagZero);
+}
+
+llvm::DICompileUnit *DebugTranslation::translateImpl(DICompileUnitAttr attr) {
+  llvm::DIBuilder builder(llvmModule);
+  return builder.createCompileUnit(
+      attr.getSourceLanguage(), translate(attr.getFile()), attr.getProducer(),
+      attr.getIsOptimized(), /*Flags=*/"", /*RV=*/0);
+}
+
+llvm::DICompositeType *
+DebugTranslation::translateImpl(DICompositeTypeAttr attr) {
+  SmallVector<llvm::Metadata *> elements;
+  for (auto member : attr.getElements())
+    elements.push_back(translate(member));
+  return llvm::DICompositeType::get(
+      llvmCtx, attr.getTag(), attr.getName(), translate(attr.getFile()),
+      attr.getLine(), translate(attr.getScope()), /*BaseType=*/nullptr,
+      attr.getSizeInBits(), attr.getAlignInBits(),
+      /*OffsetInBits=*/0, /*Flags=*/llvm::DINode::FlagZero,
+      llvm::MDNode::get(llvmCtx, elements),
+      /*RuntimeLang=*/0, /*VTableHolder=*/nullptr);
+}
+
+llvm::DIDerivedType *DebugTranslation::translateImpl(DIDerivedTypeAttr attr) {
+  return llvm::DIDerivedType::get(
+      llvmCtx, attr.getTag(), attr.getName(), /*File=*/nullptr, /*Line=*/0,
+      /*Scope=*/nullptr, translate(attr.getBaseType()), attr.getSizeInBits(),
+      attr.getAlignInBits(), attr.getOffsetInBits(),
+      /*DWARFAddressSpace=*/llvm::None, /*Flags=*/llvm::DINode::FlagZero);
+}
+
+llvm::DIFile *DebugTranslation::translateImpl(DIFileAttr attr) {
+  return llvm::DIFile::get(llvmCtx, attr.getName(), attr.getDirectory());
+}
+
+llvm::DILexicalBlock *DebugTranslation::translateImpl(DILexicalBlockAttr attr) {
+  return llvm::DILexicalBlock::getDistinct(llvmCtx, translate(attr.getScope()),
+                                           translate(attr.getFile()),
+                                           attr.getLine(), attr.getColumn());
+}
+
+llvm::DILexicalBlockFile *
+DebugTranslation::translateImpl(DILexicalBlockFileAttr attr) {
+  return llvm::DILexicalBlockFile::getDistinct(
+      llvmCtx, translate(attr.getScope()), translate(attr.getFile()),
+      attr.getDescriminator());
+}
+
+llvm::DILocalVariable *
+DebugTranslation::translateImpl(DILocalVariableAttr attr) {
+  return llvm::DILocalVariable::get(
+      llvmCtx, translate(attr.getScope()),
+      llvm::MDString::get(llvmCtx, attr.getName()), translate(attr.getFile()),
+      attr.getLine(), translate(attr.getType()), attr.getArg(),
+      /*Flags=*/llvm::DINode::FlagZero, attr.getAlignInBits(),
+      /*Annotations=*/nullptr);
+}
+
+llvm::DIScope *DebugTranslation::translateImpl(DIScopeAttr attr) {
+  return cast<llvm::DIScope>(translate(DINodeAttr(attr)));
+}
+
+/// Return a new subprogram that is either distinct or not, depending on
+/// `isDistinct`.
+template <class... Ts>
+static llvm::DISubprogram *getSubprogram(bool isDistinct, Ts &&...args) {
+  if (isDistinct)
+    return llvm::DISubprogram::getDistinct(std::forward<Ts>(args)...);
+  return llvm::DISubprogram::get(std::forward<Ts>(args)...);
+}
+
+llvm::DISubprogram *DebugTranslation::translateImpl(DISubprogramAttr attr) {
+  bool isDefinition = static_cast<bool>(attr.getSubprogramFlags() &
+                                        LLVM::DISubprogramFlags::Definition);
+  return getSubprogram(
+      isDefinition, llvmCtx, translate(attr.getScope()),
+      llvm::MDString::get(llvmCtx, attr.getName()),
+      llvm::MDString::get(llvmCtx, attr.getLinkageName()),
+      translate(attr.getFile()), attr.getLine(), translate(attr.getType()),
+      attr.getScopeLine(), /*ContainingType=*/nullptr, /*VirtualIndex=*/0,
+      /*ThisAdjustment=*/0, llvm::DINode::FlagZero,
+      static_cast<llvm::DISubprogram::DISPFlags>(attr.getSubprogramFlags()),
+      translate(attr.getCompileUnit()));
+}
+
+llvm::DISubrange *DebugTranslation::translateImpl(DISubrangeAttr attr) {
+  auto getMetadataOrNull = [&](IntegerAttr attr) -> llvm::Metadata * {
+    if (!attr)
+      return nullptr;
+    return llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
+        llvm::Type::getInt64Ty(llvmCtx), attr.getInt()));
+  };
+  return llvm::DISubrange::get(llvmCtx, getMetadataOrNull(attr.getCount()),
+                               getMetadataOrNull(attr.getLowerBound()),
+                               getMetadataOrNull(attr.getUpperBound()),
+                               getMetadataOrNull(attr.getStride()));
+}
+
+llvm::DISubroutineType *
+DebugTranslation::translateImpl(DISubroutineTypeAttr attr) {
+  SmallVector<llvm::Metadata *> types;
+  for (auto type : attr.getTypes())
+    types.push_back(translate(type));
+  return llvm::DISubroutineType::get(
+      llvmCtx, llvm::DINode::FlagZero, attr.getCallingConvention(),
+      llvm::DITypeRefArray(llvm::MDNode::get(llvmCtx, types)));
+}
+
+llvm::DIType *DebugTranslation::translateImpl(DITypeAttr attr) {
+  return cast<llvm::DIType>(translate(DINodeAttr(attr)));
+}
+
+llvm::DINode *DebugTranslation::translate(DINodeAttr attr) {
+  if (!attr)
+    return nullptr;
+  // Check for a cached instance.
+  if (llvm::DINode *node = attrToNode.lookup(attr))
+    return node;
+
+  llvm::DINode *node =
+      TypeSwitch<DINodeAttr, llvm::DINode *>(attr)
+          .Case<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
+                DIDerivedTypeAttr, DIFileAttr, DILexicalBlockAttr,
+                DILexicalBlockFileAttr, DILocalVariableAttr, DISubprogramAttr,
+                DISubroutineTypeAttr>(
+              [&](auto attr) { return translateImpl(attr); });
+  attrToNode.insert({attr, node});
+  return node;
 }
 
 //===----------------------------------------------------------------------===//
@@ -122,8 +229,12 @@ void DebugTranslation::translate(LLVMFuncOp func, llvm::Function &llvmFunc) {
 /// Translate the given location to an llvm debug location.
 const llvm::DILocation *
 DebugTranslation::translateLoc(Location loc, llvm::DILocalScope *scope) {
-  if (!compileUnit)
+  if (!debugEmissionIsEnabled)
     return nullptr;
+
+  // Check for a scope encoded with the location.
+  if (auto scopedLoc = loc->findInstanceOf<FusedLocWith<LLVM::DIScopeAttr>>())
+    scope = cast<llvm::DILocalScope>(translate(scopedLoc.getMetadata()));
   return translateLoc(loc, scope, /*inlinedAt=*/nullptr);
 }
 
@@ -148,7 +259,8 @@ DebugTranslation::translateLoc(Location loc, llvm::DILocalScope *scope,
 
   } else if (auto fileLoc = loc.dyn_cast<FileLineColLoc>()) {
     auto *file = translateFile(fileLoc.getFilename());
-    auto *fileScope = builder.createLexicalBlockFile(scope, file);
+    auto *fileScope = llvm::DILexicalBlockFile::get(llvmCtx, scope, file,
+                                                    /*Discriminator=*/0);
     llvmLoc = llvm::DILocation::get(llvmCtx, fileLoc.getLine(),
                                     fileLoc.getColumn(), fileScope,
                                     const_cast<llvm::DILocation *>(inlinedAt));
@@ -210,5 +322,5 @@ llvm::DIFile *DebugTranslation::translateFile(StringRef fileName) {
       fileName = fileBuf;
     }
   }
-  return (file = builder.createFile(fileName, directory));
+  return (file = llvm::DIFile::get(llvmCtx, fileName, directory));
 }

diff  --git a/mlir/lib/Target/LLVMIR/DebugTranslation.h b/mlir/lib/Target/LLVMIR/DebugTranslation.h
index 3706d06fb7c9c..14bd3b5162fa7 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.h
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.h
@@ -14,6 +14,7 @@
 #ifndef MLIR_LIB_TARGET_LLVMIR_DEBUGTRANSLATION_H_
 #define MLIR_LIB_TARGET_LLVMIR_DEBUGTRANSLATION_H_
 
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
 #include "mlir/IR/Location.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringMap.h"
@@ -39,6 +40,17 @@ class DebugTranslation {
   /// Translate the debug information for the given function.
   void translate(LLVMFuncOp func, llvm::Function &llvmFunc);
 
+  /// Translate the given LLVM debug metadata to LLVM.
+  llvm::DINode *translate(DINodeAttr attr);
+
+  /// Translate the given derived LLVM debug metadata to LLVM.
+  template <typename DIAttrT>
+  auto translate(DIAttrT attr) {
+    // Infer the LLVM type from the attribute type.
+    using LLVMTypeT = std::remove_pointer_t<decltype(translateImpl(attr))>;
+    return cast_or_null<LLVMTypeT>(translate(DINodeAttr(attr)));
+  }
+
 private:
   /// Translate the given location to an llvm debug location with the given
   /// scope and inlinedAt parameters.
@@ -48,11 +60,30 @@ class DebugTranslation {
   /// Create an llvm debug file for the given file path.
   llvm::DIFile *translateFile(StringRef fileName);
 
+  /// Translate the given attribute to the corresponding llvm debug metadata.
+  llvm::DIBasicType *translateImpl(DIBasicTypeAttr attr);
+  llvm::DICompileUnit *translateImpl(DICompileUnitAttr attr);
+  llvm::DICompositeType *translateImpl(DICompositeTypeAttr attr);
+  llvm::DIDerivedType *translateImpl(DIDerivedTypeAttr attr);
+  llvm::DIFile *translateImpl(DIFileAttr attr);
+  llvm::DILexicalBlock *translateImpl(DILexicalBlockAttr attr);
+  llvm::DILexicalBlockFile *translateImpl(DILexicalBlockFileAttr attr);
+  llvm::DILocalVariable *translateImpl(DILocalVariableAttr attr);
+  llvm::DIScope *translateImpl(DIScopeAttr attr);
+  llvm::DISubprogram *translateImpl(DISubprogramAttr attr);
+  llvm::DISubrange *translateImpl(DISubrangeAttr attr);
+  llvm::DISubroutineType *translateImpl(DISubroutineTypeAttr attr);
+  llvm::DIType *translateImpl(DITypeAttr attr);
+
   /// A mapping between mlir location+scope and the corresponding llvm debug
   /// metadata.
   DenseMap<std::pair<Location, llvm::DILocalScope *>, const llvm::DILocation *>
       locationToLoc;
 
+  /// A mapping between debug attribute and the corresponding llvm debug
+  /// metadata.
+  DenseMap<Attribute, llvm::DINode *> attrToNode;
+
   /// A mapping between filename and llvm debug file.
   /// TODO: Change this to DenseMap<Identifier, ...> when we can
   /// access the Identifier filename in FileLineColLoc.
@@ -61,10 +92,12 @@ class DebugTranslation {
   /// A string containing the current working directory of the compiler.
   SmallString<256> currentWorkingDir;
 
+  /// Flag indicating if debug information should be emitted.
+  bool debugEmissionIsEnabled;
+
   /// Debug information fields.
-  llvm::DIBuilder builder;
+  llvm::Module &llvmModule;
   llvm::LLVMContext &llvmCtx;
-  llvm::DICompileUnit *compileUnit;
 };
 
 } // namespace detail

diff  --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 5e27dab3521c9..d1cdc77e4b968 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1139,6 +1139,10 @@ ModuleTranslation::translateLoc(Location loc, llvm::DILocalScope *scope) {
   return debugTranslation->translateLoc(loc, scope);
 }
 
+llvm::Metadata *ModuleTranslation::translateDebugInfo(LLVM::DINodeAttr attr) {
+  return debugTranslation->translate(attr);
+}
+
 llvm::NamedMDNode *
 ModuleTranslation::getOrInsertNamedModuleMetadata(StringRef name) {
   return llvmModule->getOrInsertNamedMetadata(name);

diff  --git a/mlir/test/Target/LLVMIR/llvmir-debug.mlir b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
index b839a825bdfe2..fd95e176e1941 100644
--- a/mlir/test/Target/LLVMIR/llvmir-debug.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
@@ -17,9 +17,38 @@ llvm.func @func_no_debug() {
   llvm.return loc(unknown)
 } loc(unknown)
 
-// CHECK-LABEL: define void @func_with_debug()
-// CHECK-SAME: !dbg ![[FUNC_LOC:[0-9]+]]
-llvm.func @func_with_debug() {
+
+#si64 = #llvm.di_basic_type<
+  tag = DW_TAG_base_type, name = "si64", sizeInBits = 0,
+  encoding = DW_ATE_signed
+>
+#file = #llvm.di_file<"foo.mlir" in "/test/">
+#cu = #llvm.di_compile_unit<
+  sourceLanguage = DW_LANG_C, file = #file, producer = "MLIR",
+  isOptimized = true, emissionKind = Full
+>
+#spType = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #si64>
+#sp = #llvm.di_subprogram<
+  compileUnit = #cu, scope = #file, name = "intrinsics", linkageName = "intrinsics",
+  file = #file, line = 3, scopeLine = 3, subprogramFlags = "Definition|Optimized", type = #spType
+>
+#fileScope = #llvm.di_lexical_block_file<scope = #sp, file = #file, descriminator = 0>
+#variable = #llvm.di_local_variable<scope = #fileScope, name = "arg", file = #file, line = 6, arg = 1, alignInBits = 0, type = #si64>
+
+// CHECK-LABEL: define void @func_with_debug(
+// CHECK-SAME: i64 %[[ARG:.*]]) !dbg ![[FUNC_LOC:[0-9]+]]
+llvm.func @func_with_debug(%arg: i64) {
+  // CHECK: %[[ALLOC:.*]] = alloca
+  %allocCount = llvm.mlir.constant(1 : i32) : i32
+  %alloc = llvm.alloca %allocCount x i64 : (i32) -> !llvm.ptr<i64>
+
+  // CHECK: call void @llvm.dbg.value(metadata i64 %[[ARG]], metadata ![[VAR_LOC:[0-9]+]], metadata !DIExpression())
+  // CHECK: call void @llvm.dbg.addr(metadata ptr %[[ALLOC]], metadata ![[VAR_LOC]], metadata !DIExpression())
+  // CHECK: call void @llvm.dbg.declare(metadata ptr %[[ALLOC]], metadata ![[VAR_LOC]], metadata !DIExpression())
+  llvm.dbg.value #variable = %arg : i64
+  llvm.dbg.addr #variable = %alloc : !llvm.ptr<i64>
+  llvm.dbg.declare #variable = %alloc : !llvm.ptr<i64>
+
   // CHECK: call void @func_no_debug(), !dbg ![[CALLSITE_LOC:[0-9]+]]
   llvm.call @func_no_debug() : () -> () loc(callsite("mysource.cc":3:4 at "mysource.cc":5:6))
 
@@ -33,9 +62,19 @@ llvm.func @func_with_debug() {
   llvm.call @func_no_debug() : () -> () loc(fused[callsite("mysource.cc":1:1 at "mysource.cc":5:6), "mysource.cc":1:1])
 
   llvm.return
-} loc("foo.mlir":1:1)
+} loc(fused<#sp>["foo.mlir":1:1])
+
+// CHECK: ![[CU_LOC:.*]] = distinct !DICompileUnit(language: DW_LANG_C, file: ![[CU_FILE_LOC:.*]], producer: "MLIR", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
+// CHECK: ![[CU_FILE_LOC]] = !DIFile(filename: "foo.mlir", directory: "/test/")
+
+// CHECK: ![[FUNC_LOC]] = distinct !DISubprogram(name: "intrinsics", linkageName: "intrinsics", scope: ![[CU_FILE_LOC]], file: ![[CU_FILE_LOC]], line: 3, type: ![[FUNC_TYPE:.*]], scopeLine: 3, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: ![[CU_LOC]])
+// CHECK: ![[FUNC_TYPE]] = !DISubroutineType(cc: DW_CC_normal, types: ![[ARG_TYPES:.*]])
+// CHECK: ![[ARG_TYPES]] = !{![[ARG_TYPE:.*]]}
+// CHECK: ![[ARG_TYPE]] = !DIBasicType(name: "si64", encoding: DW_ATE_signed)
+
+// CHECK: ![[VAR_LOC]] = !DILocalVariable(name: "arg", arg: 1, scope: ![[VAR_SCOPE:.*]], file: ![[CU_FILE_LOC]], line: 6, type: ![[ARG_TYPE]])
+// CHECK: ![[VAR_SCOPE]] = distinct !DILexicalBlockFile(scope: ![[FUNC_LOC]], file: ![[CU_FILE_LOC]], discriminator: 0)
 
-// CHECK-DAG: ![[FUNC_LOC]] = distinct !DISubprogram{{.*}}, line: 1
 // CHECK-DAG: ![[CALLSITE_LOC]] = !DILocation(line: 3, column: 4,
 // CHECK-DAG: ![[FILE_LOC]] = !DILocation(line: 1, column: 2,
 // CHECK-DAG: ![[NAMED_LOC]] = !DILocation(line: 10, column: 10

diff  --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index 8bf1070a63942..bc9c287fa9a81 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -1615,25 +1615,25 @@ llvm.func @useInlineAsm(%arg0: i32) {
   // Constraints string is checked at LLVM InlineAsm instruction construction time.
   // So we can't just use "bar" everywhere, number of in/out arguments has to match.
 
-  // CHECK-NEXT:  call void asm "foo", "r"(i32 {{.*}}), !dbg !7
+  // CHECK-NEXT:  call void asm "foo", "r"(i32 {{.*}})
   llvm.inline_asm "foo", "r" %arg0 : (i32) -> ()
 
-  // CHECK-NEXT:  call i8 asm "foo", "=r,r"(i32 {{.*}}), !dbg !9
+  // CHECK-NEXT:  call i8 asm "foo", "=r,r"(i32 {{.*}})
   %0 = llvm.inline_asm "foo", "=r,r" %arg0 : (i32) -> i8
 
-  // CHECK-NEXT:  call i8 asm "foo", "=r,r,r"(i32 {{.*}}, i32 {{.*}}), !dbg !10
+  // CHECK-NEXT:  call i8 asm "foo", "=r,r,r"(i32 {{.*}}, i32 {{.*}})
   %1 = llvm.inline_asm "foo", "=r,r,r" %arg0, %arg0 : (i32, i32) -> i8
 
-  // CHECK-NEXT:  call i8 asm sideeffect "foo", "=r,r,r"(i32 {{.*}}, i32 {{.*}}), !dbg !11
+  // CHECK-NEXT:  call i8 asm sideeffect "foo", "=r,r,r"(i32 {{.*}}, i32 {{.*}})
   %2 = llvm.inline_asm has_side_effects "foo", "=r,r,r" %arg0, %arg0 : (i32, i32) -> i8
 
-  // CHECK-NEXT:  call i8 asm alignstack "foo", "=r,r,r"(i32 {{.*}}, i32 {{.*}}), !dbg !12
+  // CHECK-NEXT:  call i8 asm alignstack "foo", "=r,r,r"(i32 {{.*}}, i32 {{.*}})
   %3 = llvm.inline_asm is_align_stack "foo", "=r,r,r" %arg0, %arg0 : (i32, i32) -> i8
 
-  // CHECK-NEXT:  call i8 asm inteldialect "foo", "=r,r,r"(i32 {{.*}}, i32 {{.*}}), !dbg !13
+  // CHECK-NEXT:  call i8 asm inteldialect "foo", "=r,r,r"(i32 {{.*}}, i32 {{.*}})
   %4 = llvm.inline_asm asm_dialect = "intel" "foo", "=r,r,r" %arg0, %arg0 : (i32, i32) -> i8
 
-  // CHECK-NEXT:  call { i8, i8 } asm "foo", "=r,=r,r"(i32 {{.*}}), !dbg !14
+  // CHECK-NEXT:  call { i8, i8 } asm "foo", "=r,=r,r"(i32 {{.*}})
   %5 = llvm.inline_asm "foo", "=r,=r,r" %arg0 : (i32) -> !llvm.struct<(i8, i8)>
 
   llvm.return

diff  --git a/mlir/test/Target/LLVMIR/openmp-llvm.mlir b/mlir/test/Target/LLVMIR/openmp-llvm.mlir
index da6f99c9fcd6e..82a9c1fa53609 100644
--- a/mlir/test/Target/LLVMIR/openmp-llvm.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-llvm.mlir
@@ -356,11 +356,8 @@ llvm.func @test_omp_master() -> () {
 // -----
 
 // CHECK: %struct.ident_t = type
-// CHECK: @[[$parallel_loc:.*]] = private unnamed_addr constant {{.*}} c";LLVMDialectModule;wsloop_simple;{{[0-9]+}};{{[0-9]+}};;\00"
-// CHECK: @[[$parallel_loc_struct:.*]] = private unnamed_addr constant %struct.ident_t {{.*}} @[[$parallel_loc]] {{.*}}
-
-// CHECK: @[[$wsloop_loc:.*]] = private unnamed_addr constant {{.*}} c";LLVMDialectModule;wsloop_simple;{{[0-9]+}};{{[0-9]+}};;\00"
-// CHECK: @[[$wsloop_loc_struct:.*]] = private unnamed_addr constant %struct.ident_t {{.*}} @[[$wsloop_loc]] {{.*}}
+// CHECK: @[[$loc:.*]] = private unnamed_addr constant {{.*}} c";unknown;unknown;{{[0-9]+}};{{[0-9]+}};;\00"
+// CHECK: @[[$loc_struct:.*]] = private unnamed_addr constant %struct.ident_t {{.*}} @[[$loc]] {{.*}}
 
 // CHECK-LABEL: @wsloop_simple
 llvm.func @wsloop_simple(%arg0: !llvm.ptr<f32>) {
@@ -373,12 +370,12 @@ llvm.func @wsloop_simple(%arg0: !llvm.ptr<f32>) {
       // The form of the emitted IR is controlled by OpenMPIRBuilder and
       // tested there. Just check that the right functions are called.
       // CHECK: call i32 @__kmpc_global_thread_num
-      // CHECK: call void @__kmpc_for_static_init_{{.*}}(ptr @[[$wsloop_loc_struct]],
+      // CHECK: call void @__kmpc_for_static_init_{{.*}}(ptr @[[$loc_struct]],
       %3 = llvm.mlir.constant(2.000000e+00 : f32) : f32
       %4 = llvm.getelementptr %arg0[%arg1] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
       llvm.store %3, %4 : !llvm.ptr<f32>
       omp.yield
-      // CHECK: call void @__kmpc_for_static_fini(ptr @[[$wsloop_loc_struct]],
+      // CHECK: call void @__kmpc_for_static_fini(ptr @[[$loc_struct]],
     }) {operand_segment_sizes = array<i32: 1, 1, 1, 0, 0, 0, 0>} : (i64, i64, i64) -> ()
     omp.terminator
   }
@@ -2317,7 +2314,7 @@ llvm.func @omp_task(%x: i32, %y: i32, %zaddr: !llvm.ptr<i32>) {
 // CHECK-SAME: (i32 %[[x:.+]], i32 %[[y:.+]], ptr %[[zaddr:.+]])
 module attributes {llvm.target_triple = "x86_64-unknown-linux-gnu"} {
   llvm.func @omp_task(%x: i32, %y: i32, %zaddr: !llvm.ptr<i32>) {
-    // CHECK: %[[
diff :.+]] = sub i32 %[[x]], %[[y]],
+    // CHECK: %[[
diff :.+]] = sub i32 %[[x]], %[[y]]
     %
diff  = llvm.sub %x, %y : i32
     // CHECK: store i32 %[[
diff ]], ptr %2
     llvm.store %
diff , %zaddr : !llvm.ptr<i32>

diff  --git a/mlir/test/Target/LLVMIR/openmp-nested.mlir b/mlir/test/Target/LLVMIR/openmp-nested.mlir
index 3c4c0770dc270..6e0fa4295bdd5 100644
--- a/mlir/test/Target/LLVMIR/openmp-nested.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-nested.mlir
@@ -38,4 +38,4 @@ module {
 
 // CHECK: define internal void @[[inner1]]
 // CHECK: %[[structArg:.+]] = alloca { ptr }
-// CHECK: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @3, i32 1, ptr @[[inner2:.+]], ptr %[[structArg]])
+// CHECK: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @1, i32 1, ptr @[[inner2:.+]], ptr %[[structArg]])


        


More information about the flang-commits mailing list