llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Konstantinos Parasyris (koparasy)

<details>
<summary>Changes</summary>

Clang now supports lowering .cir cc1 input to LLVM IR, assembly, and objects.

The lowering does not execute the cir-to-cir passes; it only translates the 
input CIR to LLVM IR, assembly, and objects. This assumes that the input CIR is 
well-formed and valid and emitted the way -emit-cir emits this today.

There will be some future PR that enables emission earlier and allows the 
pipeline to apply CIR passes before lowering to LLVM IR, assembly, and objects.

---
Full diff: https://github.com/llvm/llvm-project/pull/232506.diff


9 Files Affected:

- (modified) clang/include/clang/Basic/DiagnosticCodeGenKinds.td (+3) 
- (modified) clang/include/clang/Basic/DiagnosticFrontendKinds.td (-2) 
- (modified) clang/include/clang/CIR/LowerToLLVM.h (+3) 
- (modified) clang/lib/CIR/FrontendAction/CIRGenAction.cpp (+15-18) 
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+4-10) 
- (modified) clang/test/CIR/Input/cir-input-invalid.cir (+5-2) 
- (added) clang/test/CIR/Input/cir-input-lower-error.cir (+24) 
- (added) clang/test/CIR/Input/cir-input-lower.cpp (+54) 
- (removed) clang/test/CIR/Input/cir-input-unsupported.cir (-29) 


``````````diff
diff --git a/clang/include/clang/Basic/DiagnosticCodeGenKinds.td 
b/clang/include/clang/Basic/DiagnosticCodeGenKinds.td
index c8b8bb38b20ea2..d01f8bcbf481be 100644
--- a/clang/include/clang/Basic/DiagnosticCodeGenKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCodeGenKinds.td
@@ -27,6 +27,9 @@ def err_cir_verification_failed_pre_passes : Error<
     "CIR module verification error before running CIR-to-CIR passes">,
     DefaultFatal;
 
+def err_cir_to_llvm_lowering_failed : Error<
+    "lowering ClangIR to LLVM IR failed">, DefaultFatal;
+
 // Diagnostics relayed from MLIR-side passes/verifier through the
 // clang::DiagnosticsEngine. The full message text comes from MLIR.
 def err_cir_mlir_diagnostic    : Error<"%0">;
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td 
b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 66eeb08034bf4b..3df87215a0476d 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -146,8 +146,6 @@ def err_fe_action_not_available : Error<
     "action %0 not compiled in">;
 def err_fe_cir_not_built : Error<"clang IR support not available, rebuild "
                                  "clang with -DCLANG_ENABLE_CIR=ON">;
-def err_fe_cir_input_unsupported : Error<
-    "support for ClangIR input is not yet implemented">;
 def err_invalid_cir : Error<"invalid ClangIR input">;
 def err_cir_input_missing_triple : Error<
     "missing target triple in ClangIR input">;
diff --git a/clang/include/clang/CIR/LowerToLLVM.h 
b/clang/include/clang/CIR/LowerToLLVM.h
index d97ac5265c282b..f746a5e211c3bc 100644
--- a/clang/include/clang/CIR/LowerToLLVM.h
+++ b/clang/include/clang/CIR/LowerToLLVM.h
@@ -28,6 +28,9 @@ class ModuleOp;
 namespace cir {
 
 namespace direct {
+/// Lowers \p mlirModule, a CIR module, to an LLVM module in \p llvmCtx.
+/// Returns null if lowering fails; the error has then been reported through
+/// the MLIR diagnostic engine of \p mlirModule's context.
 std::unique_ptr<llvm::Module>
 lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp mlirModule,
                              llvm::LLVMContext &llvmCtx, bool enableOpenMP,
diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp 
b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
index c1f7c5117c54bb..b0d35d0ddc56ad 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -173,6 +173,13 @@ static void emitCIRModuleOutput(
     std::unique_ptr<llvm::Module> LLVMModule =
         lowerFromCIRToLLVMIR(MlirModule, LLVMCtx, EnableOpenMP,
                              mlirSaveTempsOutFile, &CI.getVirtualFileSystem());
+    if (!LLVMModule) {
+      // Lowering errors are already routed through the MLIR diagnostic
+      // handler. Only emit the generic error if nothing was reported.
+      if (!CI.getDiagnostics().hasErrorOccurred())
+        CI.getDiagnostics().Report(diag::err_cir_to_llvm_lowering_failed);
+      return;
+    }
 
     LLVMModule->setDataLayout(CI.getTarget().getDataLayoutString());
 
@@ -432,24 +439,14 @@ void CIRGenAction::ExecuteAction() {
     return;
   }
 
-  switch (Action) {
-  case OutputType::EmitCIR:
-    // The CIR-to-CIR pipeline is not run: CIR printed by -emit-cir has already
-    // been through it, and its lowering passes are not idempotent.
-    printCIRModule(*Module, *OS);
-    break;
-  case OutputType::EmitCIRBC:
-    if (failed(mlir::writeBytecodeToFile(*Module, *OS)) &&
-        !Diags.hasErrorOccurred())
-      Diags.Report(diag::err_cir_bc_write_failed);
-    break;
-  case OutputType::EmitLLVM:
-  case OutputType::EmitBC:
-  case OutputType::EmitObj:
-  case OutputType::EmitAssembly:
-    Diags.Report(diag::err_fe_cir_input_unsupported);
-    break;
-  }
+  // The CIR-to-CIR pipeline is not run: CIR printed by -emit-cir has already
+  // been through it, and its lowering passes are not idempotent.
+  // TODO: Decide from a pipeline-stage attribute on the module which passes
+  // still have to run, once -emit-cir can stop before ABI lowering.
+  BackendDiagnosticConsumer DiagConsumer(Diags, CI.getCodeGenOpts());
+  DiagConsumer.setSourceManager(&SM);
+  emitCIRModuleOutput(Action, CI, *Module, *Ctx, LinkModules, DiagConsumer,
+                      std::move(OS));
 }
 
 static std::unique_ptr<raw_pwrite_stream>
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index ddfc28da80388d..60ad37198fcfbe 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -6441,11 +6441,10 @@ lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp mlirModule, 
LLVMContext &llvmCtx,
 
   (void)mlir::applyPassManagerCLOptions(pm);
 
-  if (mlir::failed(pm.run(mlirModule))) {
-    // FIXME: Handle any errors where they occurs and return a nullptr here.
-    report_fatal_error(
-        "The pass manager failed to lower CIR to LLVMIR dialect!");
-  }
+  // The failing pass has already reported its error through the MLIR
+  // diagnostic engine.
+  if (mlir::failed(pm.run(mlirModule)))
+    return nullptr;
 
   if (!mlirSaveTempsOutFile.empty()) {
     std::error_code ec;
@@ -6465,11 +6464,6 @@ lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp mlirModule, 
LLVMContext &llvmCtx,
   std::unique_ptr<llvm::Module> llvmModule = mlir::translateModuleToLLVMIR(
       mlirModule, llvmCtx, moduleName, /*disableVerification=*/false, fs);
 
-  if (!llvmModule) {
-    // FIXME: Handle any errors where they occurs and return a nullptr here.
-    report_fatal_error("Lowering from LLVMIR dialect to llvm IR failed!");
-  }
-
   return llvmModule;
 }
 } // namespace direct
diff --git a/clang/test/CIR/Input/cir-input-invalid.cir 
b/clang/test/CIR/Input/cir-input-invalid.cir
index 1a791d843bb0a4..cc64546eed3580 100644
--- a/clang/test/CIR/Input/cir-input-invalid.cir
+++ b/clang/test/CIR/Input/cir-input-invalid.cir
@@ -1,6 +1,5 @@
 // Invalid ClangIR input is diagnosed, not crashed on, before any output is
-// produced. Backend outputs, which are not supported from ClangIR input yet,
-// report the same errors.
+// produced. Backend outputs report the same errors.
 
 // RUN: rm -rf %t && split-file %s %t
 
@@ -12,6 +11,8 @@
 
 // RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir 
%t/verifier.cir -o - 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=VERIFIER --implicit-check-not=error:
+// RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-obj 
%t/verifier.cir -o /dev/null 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=VERIFIER --implicit-check-not=error:
 // VERIFIER: verifier.cir:5:5: error: 'cir.return' op returns '!cir.int<s, 
64>' but enclosing function returns '!cir.int<s, 32>'
 
 // Ops in CIR emitted by CIRGen are located in the original source, which is 
not
@@ -33,6 +34,8 @@
 
 // RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir 
%t/mismatch.cir -o - 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=MISMATCH --implicit-check-not=error:
+// RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-obj 
%t/mismatch.cir -o /dev/null 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=MISMATCH --implicit-check-not=error:
 // MISMATCH: error: target triple 'aarch64-unknown-linux-gnu' of ClangIR input 
does not match the target 'x86_64-unknown-linux-gnu'
 
 //--- syntax.cir
diff --git a/clang/test/CIR/Input/cir-input-lower-error.cir 
b/clang/test/CIR/Input/cir-input-lower-error.cir
new file mode 100644
index 00000000000000..2f135bdd0f9a39
--- /dev/null
+++ b/clang/test/CIR/Input/cir-input-lower-error.cir
@@ -0,0 +1,24 @@
+// Errors from lowering ClangIR input to LLVM IR are diagnosed, not crashed on.
+// The ctor region of @gs is only removed by LoweringPrepare, which is not run
+// on ClangIR input.
+
+// RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - 
2>&1 \
+// RUN:   | FileCheck %s --implicit-check-not=error:
+// RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-obj %s -o 
/dev/null 2>&1 \
+// RUN:   | FileCheck %s --implicit-check-not=error:
+
+// No partial output is left behind.
+// RUN: rm -f %t.o && not %clang_cc1 -triple x86_64-unknown-linux-gnu 
-emit-obj %s -o %t.o 2>/dev/null
+// RUN: not ls %t.o
+
+// CHECK: cir-input-lower-error.cir:[[@LINE+6]]:3: error: GlobalOp ctor and 
dtor regions should be removed in LoweringPrepare
+// CHECK: cir-input-lower-error.cir:[[@LINE+5]]:3: error: failed to legalize 
operation 'cir.global'
+
+!rec_S = !cir.struct<"S" {data !cir.int<s, 32>}>
+module attributes {cir.triple = "x86_64-unknown-linux-gnu"} {
+  cir.func private @_ZN1SC1Ev(!cir.ptr<!rec_S>)
+  cir.global external @gs = #cir.zero : !rec_S ctor {
+    %0 = cir.get_global @gs : !cir.ptr<!rec_S>
+    cir.call @_ZN1SC1Ev(%0) : (!cir.ptr<!rec_S>) -> ()
+  }
+}
diff --git a/clang/test/CIR/Input/cir-input-lower.cpp 
b/clang/test/CIR/Input/cir-input-lower.cpp
new file mode 100644
index 00000000000000..0459deed07c2db
--- /dev/null
+++ b/clang/test/CIR/Input/cir-input-lower.cpp
@@ -0,0 +1,54 @@
+// Lowering ClangIR input to LLVM IR, assembly, bitcode or an object gives the
+// same result as compiling the source directly. The CIR-to-CIR pipeline is not
+// run again on input printed by -emit-cir, whose lowering passes are not
+// idempotent; the code below exercises the calling convention, global
+// constructor and TLS wrapper lowering.
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o 
%t.cir
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o 
%t.direct.ll
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %t.cir -o %t.ll
+// RUN: diff %t.direct.ll %t.ll
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -S %s -o 
%t.direct.s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -S %t.cir -o %t.s
+// RUN: diff %t.direct.s %t.s
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-obj %s -o 
%t.direct.o
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-obj %t.cir -o %t.o
+// RUN: cmp %t.direct.o %t.o
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm-bc %s 
-o %t.direct.bc
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc %t.cir -o 
%t.bc
+// RUN: cmp %t.direct.bc %t.bc
+
+// Without -o, the output is named after the input.
+// RUN: rm -rf %t.dir && mkdir -p %t.dir && cd %t.dir
+// RUN: cp %t.cir input.cir
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-obj input.cir
+// RUN: cmp %t.direct.o input.o
+
+// Code generation options still come from the command line.
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -fclangir -emit-cir %s 
-o %t.O2.cir
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -fclangir -emit-llvm 
%s -o %t.O2.direct.ll
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -emit-llvm -x cir 
%t.O2.cir -o %t.O2.ll
+// RUN: diff %t.O2.direct.ll %t.O2.ll
+
+typedef float v2f __attribute__((vector_size(8)));
+
+v2f mk(float a) { return (v2f){a, a}; }
+
+struct S {
+  S();
+  ~S();
+  int v;
+};
+
+S gs;
+
+thread_local int tl = 3;
+
+int get() {
+  static S local;
+  return local.v + tl;
+}
diff --git a/clang/test/CIR/Input/cir-input-unsupported.cir 
b/clang/test/CIR/Input/cir-input-unsupported.cir
deleted file mode 100644
index b087871af1d04e..00000000000000
--- a/clang/test/CIR/Input/cir-input-unsupported.cir
+++ /dev/null
@@ -1,29 +0,0 @@
-// A .cir input is routed to the ClangIR frontend action instead of being
-// parsed as C. Only -emit-cir is supported from ClangIR input so far, so every
-// other CIR action reports a single diagnostic.
-
-// RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm 
-x cir %s -o - 2>&1 \
-// RUN:   | FileCheck %s --implicit-check-not=error:
-// RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-obj -x 
cir %s -o /dev/null 2>&1 \
-// RUN:   | FileCheck %s --implicit-check-not=error:
-// RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -S -x cir %s 
-o - 2>&1 \
-// RUN:   | FileCheck %s --implicit-check-not=error:
-// RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir 
-emit-llvm-bc -x cir %s -o /dev/null 2>&1 \
-// RUN:   | FileCheck %s --implicit-check-not=error:
-
-// ClangIR input implies -fclangir.
-// RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -x cir %s 
-o - 2>&1 \
-// RUN:   | FileCheck %s --implicit-check-not=error:
-
-// The .cir extension selects ClangIR input without -x.
-// RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-obj %s -o 
/dev/null 2>&1 \
-// RUN:   | FileCheck %s --implicit-check-not=error:
-
-// CHECK: error: support for ClangIR input is not yet implemented
-
-!s32i = !cir.int<s, 32>
-module attributes {cir.triple = "x86_64-unknown-linux-gnu"} {
-  cir.func @f(%arg0: !s32i) -> !s32i {
-    cir.return %arg0 : !s32i
-  }
-}

``````````

</details>


https://github.com/llvm/llvm-project/pull/232506
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to