https://github.com/andykaylor updated 
https://github.com/llvm/llvm-project/pull/195972

>From 9ec5ea0cdf013f2dac87e926c5e0cb9de0b67c38 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <[email protected]>
Date: Tue, 5 May 2026 17:19:41 -0700
Subject: [PATCH 1/2] [CIR] Implement weak ref and alias attribute handling

This adds handling for globals with the WeakRefAttr (not emitted) or
AliasAttr attributes set. CIR already had support for function aliases,
but we weren't handling the explicit alias attribute, and we didn't have
any support for global variable aliases. This change adds the global
variable alias support and adds the code to handle the explicit attribute
for variables and functions.

Assisted-by: Cursor / claude-opus-4.7-thinking-xhigh
---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  |  7 +-
 clang/include/clang/CIR/MissingFeatures.h     |  2 +
 clang/lib/CIR/CodeGen/CIRGenModule.cpp        | 97 ++++++++++++++++++-
 clang/lib/CIR/CodeGen/CIRGenModule.h          |  3 +
 clang/lib/CIR/Dialect/IR/CIRDialect.cpp       | 52 ++++++----
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 17 ++++
 clang/test/CIR/CodeGen/attr-alias.c           | 71 ++++++++++++++
 clang/test/CIR/CodeGen/attr-weakref.c         | 26 +++++
 clang/test/CIR/IR/invalid-global.cir          | 42 ++++++++
 9 files changed, 292 insertions(+), 25 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/attr-alias.c
 create mode 100644 clang/test/CIR/CodeGen/attr-weakref.c
 create mode 100644 clang/test/CIR/IR/invalid-global.cir

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index db3ac6340eccb..b7437ce1731b0 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -2871,7 +2871,8 @@ def CIR_GlobalOp : CIR_Op<"global", [
                        OptionalAttr<I64Attr>:$alignment,
                        OptionalAttr<ASTVarDeclInterface>:$ast,
                        OptionalAttr<StrAttr>:$section,
-                       OptionalAttr<CIR_AnnotationArrayAttr>:$annotations
+                       OptionalAttr<CIR_AnnotationArrayAttr>:$annotations,
+                       OptionalAttr<FlatSymbolRefAttr>:$aliasee
                        );
 
   let regions = (region AnyRegion:$ctorRegion,
@@ -2888,6 +2889,7 @@ def CIR_GlobalOp : CIR_Op<"global", [
     (`static_local_guard` `` $static_local_guard^)?
     (` ` custom<GlobalAddressSpaceValue>($addr_space)^ )?
     $sym_name
+    (`alias` `(` $aliasee^ `)`)?
     custom<GlobalOpTypeAndInitialValue>($sym_type, $initial_value,
                                         $ctorRegion, $dtorRegion)
     ($annotations^)?
@@ -2896,6 +2898,9 @@ def CIR_GlobalOp : CIR_Op<"global", [
 
   let extraClassDeclaration = [{
     bool isDeclaration() {
+      // Aliases are always definitions.
+      if (getAliasee())
+        return false;
       return !getInitialValue() && getCtorRegion().empty() && 
getDtorRegion().empty();
     }
     bool hasInitializer() { return !isDeclaration(); }
diff --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index c85fcf6556f7b..d068874bfd567 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -144,6 +144,8 @@ struct MissingFeatures {
 
   // Various handling of deferred processing in CIRGenModule.
   static bool cgmRelease() { return false; }
+  static bool checkAliases() { return false; }
+  static bool shouldSkipAliasEmission() { return false; }
   static bool deferredFuncDecls() { return false; }
 
   // CXXABI
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp 
b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index af8fd52bef017..bf6b5a22e6c4e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -464,11 +464,19 @@ void CIRGenModule::emitGlobal(clang::GlobalDecl gd) {
 
   const auto *global = cast<ValueDecl>(gd.getDecl());
 
+  // Weak references don't produce any output by themselves.
   if (global->hasAttr<WeakRefAttr>())
-    errorNYI(global->getSourceRange(), "emitGlobal: WeakRefAttr");
+    return;
 
-  if (global->hasAttr<AliasAttr>())
-    errorNYI(global->getSourceRange(), "emitGlobal: AliasAttr");
+  // If this is an alias definition (which otherwise looks like a declaration)
+  // emit it now.
+  if (global->hasAttr<AliasAttr>()) {
+    // Classic codegen calls shouldSkipAliasEmission here to skip alias
+    // emission for OpenMP target device and CUDA configurations.
+    assert(!cir::MissingFeatures::shouldSkipAliasEmission());
+    emitAliasDefinition(gd);
+    return;
+  }
 
   // If this is CUDA, be selective about which declarations we emit.
   // Non-constexpr non-lambda implicit host device functions are not emitted
@@ -3371,10 +3379,93 @@ void CIRGenModule::release() {
 
   emitLLVMUsed();
 
+  // Classic codegen calls `checkAliases` here to validate any alias
+  // definitions emitted during codegen.
+  assert(!cir::MissingFeatures::checkAliases());
+
   // There's a lot of code that is not implemented yet.
   assert(!cir::MissingFeatures::cgmRelease());
 }
 
+void CIRGenModule::emitAliasDefinition(GlobalDecl gd) {
+  const auto *d = cast<ValueDecl>(gd.getDecl());
+  const AliasAttr *aa = d->getAttr<AliasAttr>();
+  assert(aa && "Not an alias?");
+
+  StringRef mangledName = getMangledName(gd);
+
+  if (aa->getAliasee() == mangledName) {
+    diags.Report(aa->getLocation(), diag::err_cyclic_alias) << 0;
+    return;
+  }
+
+  // If there is a definition in the module, then it wins over the alias.
+  // This is dubious, but allow it to be safe. Just ignore the alias.
+  mlir::Operation *entry = getGlobalValue(mangledName);
+  if (entry) {
+    auto entryGV = mlir::dyn_cast<cir::CIRGlobalValueInterface>(entry);
+    if (entryGV && !entryGV.isDeclaration())
+      return;
+  }
+
+  // Classic codegen pushes the alias onto an `Aliases` list at this point so
+  // that `checkAliases` can later validate the alias and recover on error.
+  assert(!cir::MissingFeatures::checkAliases());
+
+  mlir::Location loc = getLoc(d->getSourceRange());
+  const bool isFunction = isa<FunctionDecl>(d);
+
+  // Get the linkage and the type of the alias.
+  cir::GlobalLinkageKind linkage;
+  mlir::Type declTy;
+  if (isFunction) {
+    declTy = getTypes().getFunctionType(gd);
+    linkage = getFunctionLinkage(gd);
+  } else {
+    declTy = getTypes().convertTypeForMem(d->getType());
+    if (const auto *vd = dyn_cast<VarDecl>(d))
+      linkage = getCIRLinkageVarDefinition(vd);
+    else
+      linkage = getFunctionLinkage(gd);
+  }
+
+  // Aliases that target weak symbols must themselves be marked weak.
+  if (d->hasAttr<WeakAttr>() || d->hasAttr<WeakRefAttr>() ||
+      d->isWeakImported())
+    linkage = cir::GlobalLinkageKind::WeakAnyLinkage;
+
+  // Create the alias op. If there is an existing declaration with the same
+  // name, erase it: any references to it via flat symbol reference will
+  // automatically resolve to the new alias.
+  if (entry) {
+    eraseGlobalSymbol(entry);
+    entry->erase();
+  }
+
+  // Aliases are always definitions, so the MLIR visibility should match the
+  // linkage rather than defaulting to private.
+  mlir::SymbolTable::Visibility visibility =
+      getMLIRVisibilityFromCIRLinkage(linkage);
+
+  if (isFunction) {
+    cir::FuncType fnType = mlir::cast<cir::FuncType>(declTy);
+    cir::FuncOp alias =
+        createCIRFunction(loc, mangledName, fnType, cast<FunctionDecl>(d));
+    alias.setAliasee(aa->getAliasee());
+    alias.setLinkage(linkage);
+    mlir::SymbolTable::setSymbolVisibility(alias, visibility);
+    setCommonAttributes(gd, alias);
+  } else {
+    cir::GlobalOp alias = createGlobalOp(*this, loc, mangledName, declTy);
+    alias.setAliasee(aa->getAliasee());
+    alias.setLinkage(linkage);
+    mlir::SymbolTable::setSymbolVisibility(alias, visibility);
+    assert(!cir::MissingFeatures::opGlobalThreadLocal());
+    setCommonAttributes(gd, alias);
+  }
+  assert(!cir::MissingFeatures::generateDebugInfo());
+}
+
 void CIRGenModule::emitAliasForGlobal(StringRef mangledName,
                                       mlir::Operation *op, GlobalDecl aliasGD,
                                       cir::FuncOp aliasee,
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h 
b/clang/lib/CIR/CodeGen/CIRGenModule.h
index 2869411015bc5..1146e4561db0b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.h
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.h
@@ -596,6 +596,9 @@ class CIRGenModule : public CIRGenTypeCache {
                           GlobalDecl aliasGD, cir::FuncOp aliasee,
                           cir::GlobalLinkageKind linkage);
 
+  /// Emit a definition for an `__attribute__((alias))` declaration.
+  void emitAliasDefinition(GlobalDecl gd);
+
   mlir::Type convertType(clang::QualType type);
 
   /// Set the visibility for the given global.
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp 
b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 47ccb291ea745..d9ed9e40e2547 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -1899,6 +1899,13 @@ mlir::LogicalResult cir::GlobalOp::verify() {
         "with a constructor or destructor, they require in-function "
         "initialization via LocalInitOp");
 
+  if (getAliasee().has_value()) {
+    if (getInitialValue().has_value() || !getCtorRegion().empty() ||
+        !getDtorRegion().empty())
+      return emitOpError("global alias shall not have an initializer or "
+                         "constructor/destructor regions");
+  }
+
   // TODO(CIR): Many other checks for properties that haven't been upstreamed
   // yet.
 
@@ -1980,29 +1987,32 @@ static void 
printGlobalOpTypeAndInitialValue(OpAsmPrinter &p, cir::GlobalOp op,
                                              mlir::Region &ctorRegion,
                                              mlir::Region &dtorRegion) {
   auto printType = [&]() { p << ": " << type; };
-  if (!op.isDeclaration()) {
-    p << "= ";
-    if (!ctorRegion.empty()) {
-      p << "ctor ";
-      printType();
-      p << " ";
-      p.printRegion(ctorRegion,
-                    /*printEntryBlockArgs=*/false,
-                    /*printBlockTerminators=*/false);
-    } else {
-      // This also prints the type...
-      if (initAttr)
-        printConstant(p, initAttr);
-    }
+  // Aliases are definitions but they have no initial value or ctor/dtor; the
+  // assembly prints them like declarations (`: type`).
+  if (op.isDeclaration() || op.getAliasee()) {
+    printType();
+    return;
+  }
 
-    if (!dtorRegion.empty()) {
-      p << " dtor ";
-      p.printRegion(dtorRegion,
-                    /*printEntryBlockArgs=*/false,
-                    /*printBlockTerminators=*/false);
-    }
-  } else {
+  p << "= ";
+  if (!ctorRegion.empty()) {
+    p << "ctor ";
     printType();
+    p << " ";
+    p.printRegion(ctorRegion,
+                  /*printEntryBlockArgs=*/false,
+                  /*printBlockTerminators=*/false);
+  } else {
+    // This also prints the type...
+    if (initAttr)
+      printConstant(p, initAttr);
+  }
+
+  if (!dtorRegion.empty()) {
+    p << " dtor ";
+    p.printRegion(dtorRegion,
+                  /*printEntryBlockArgs=*/false,
+                  /*printBlockTerminators=*/false);
   }
 }
 
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index e17c7a209db6b..2430f07b1462d 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -2473,6 +2473,23 @@ mlir::LogicalResult 
CIRToLLVMGlobalOpLowering::matchAndRewrite(
   SmallVector<mlir::NamedAttribute> attributes =
       lowerGlobalAttributes(op, rewriter);
 
+  // If this is a variable alias, lower it to llvm.mlir.alias.
+  if (std::optional<llvm::StringRef> aliasee = op.getAliasee()) {
+    mlir::Location loc = op.getLoc();
+    auto aliasOp = rewriter.replaceOpWithNewOp<mlir::LLVM::AliasOp>(
+        op, llvmType, linkage, symbol, isDsoLocal, isThreadLocal, attributes);
+
+    mlir::OpBuilder builder(op.getContext());
+    mlir::Block *block = builder.createBlock(&aliasOp.getInitializerRegion());
+    builder.setInsertionPointToStart(block);
+    mlir::Type ptrTy =
+        mlir::LLVM::LLVMPointerType::get(getContext(), addrSpace);
+    auto addrOp =
+        mlir::LLVM::AddressOfOp::create(builder, loc, ptrTy, *aliasee);
+    mlir::LLVM::ReturnOp::create(builder, loc, addrOp);
+    return mlir::success();
+  }
+
   if (init.has_value()) {
     if (mlir::isa<cir::FPAttr, cir::IntAttr, cir::BoolAttr>(init.value())) {
       GlobalInitAttrRewriter initRewriter(llvmType, rewriter);
diff --git a/clang/test/CIR/CodeGen/attr-alias.c 
b/clang/test/CIR/CodeGen/attr-alias.c
new file mode 100644
index 0000000000000..84091cc693753
--- /dev/null
+++ b/clang/test/CIR/CodeGen/attr-alias.c
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o 
%t.cir
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o 
%t-cir.ll
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
+// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s
+
+// Variable alias to a defined target.
+int alias_target = 42;
+extern int alias_var __attribute__((alias("alias_target")));
+
+// Function alias to a defined target.
+void alias_func_target(void) {}
+extern void alias_func(void) __attribute__((alias("alias_func_target")));
+
+// Variable alias preceded by an extern declaration. The previous declaration
+// must be replaced by the alias, otherwise we'd see two symbols with the same
+// name.
+int prior_decl_var_target = 7;
+extern int prior_decl_var;
+extern int prior_decl_var __attribute__((alias("prior_decl_var_target")));
+
+// Function alias preceded by an extern declaration. Same as above but for the
+// FuncOp entry-erasure path.
+extern void prior_decl_func(void);
+void prior_decl_func_target(void) {}
+extern void prior_decl_func(void) 
__attribute__((alias("prior_decl_func_target")));
+
+// Weak variable alias - exercises the WeakAttr linkage override branch.
+int weak_var_target = 9;
+extern int weak_var_alias __attribute__((weak, alias("weak_var_target")));
+
+// Weak function alias - exercises the WeakAttr linkage override branch for
+// functions.
+void weak_func_target(void) {}
+extern void weak_func_alias(void) __attribute__((weak, 
alias("weak_func_target")));
+
+// CIR-DAG: cir.global external @alias_target = #cir.int<42> : !s32i
+// CIR-DAG: cir.global external @alias_var alias(@alias_target) : !s32i
+// CIR-DAG: cir.global external @prior_decl_var_target = #cir.int<7>
+// CIR-DAG: cir.global external @prior_decl_var alias(@prior_decl_var_target) 
: !s32i
+// CIR-DAG: cir.global external @weak_var_target = #cir.int<9>
+// CIR-DAG: cir.global weak @weak_var_alias alias(@weak_var_target) : !s32i
+// CIR-DAG: cir.func{{.*}} @alias_func_target()
+// CIR-DAG: cir.func dso_local @alias_func() alias(@alias_func_target)
+// CIR-DAG: cir.func{{.*}} @prior_decl_func_target()
+// CIR-DAG: cir.func dso_local @prior_decl_func() 
alias(@prior_decl_func_target)
+// CIR-DAG: cir.func{{.*}} @weak_func_target()
+// CIR-DAG: cir.func weak @weak_func_alias() alias(@weak_func_target)
+
+// LLVM-DAG: @alias_target = global i32 42
+// LLVM-DAG: @prior_decl_var_target = global i32 7
+// LLVM-DAG: @weak_var_target = global i32 9
+// LLVM-DAG: @alias_var = alias i32, ptr @alias_target
+// LLVM-DAG: @prior_decl_var = alias i32, ptr @prior_decl_var_target
+// LLVM-DAG: @weak_var_alias = weak alias i32, ptr @weak_var_target
+// LLVM-DAG: @alias_func = alias void (), ptr @alias_func_target
+// LLVM-DAG: @prior_decl_func = alias void (), ptr @prior_decl_func_target
+// LLVM-DAG: @weak_func_alias = weak alias void (), ptr @weak_func_target
+// LLVM: define {{.*}}void @alias_func_target()
+
+// OGCG-DAG: @alias_target = {{.*}}global i32 42
+// OGCG-DAG: @prior_decl_var_target = {{.*}}global i32 7
+// OGCG-DAG: @weak_var_target = {{.*}}global i32 9
+// OGCG-DAG: @alias_var = {{.*}}alias i32, ptr @alias_target
+// OGCG-DAG: @prior_decl_var = {{.*}}alias i32, ptr @prior_decl_var_target
+// OGCG-DAG: @weak_var_alias = {{.*}}weak alias i32, ptr @weak_var_target
+// OGCG-DAG: @alias_func = {{.*}}alias void (), ptr @alias_func_target
+// OGCG-DAG: @prior_decl_func = {{.*}}alias void (), ptr 
@prior_decl_func_target
+// OGCG-DAG: @weak_func_alias = {{.*}}weak alias void (), ptr @weak_func_target
+// OGCG: define {{.*}}void @alias_func_target()
diff --git a/clang/test/CIR/CodeGen/attr-weakref.c 
b/clang/test/CIR/CodeGen/attr-weakref.c
new file mode 100644
index 0000000000000..621a277d79e79
--- /dev/null
+++ b/clang/test/CIR/CodeGen/attr-weakref.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o 
%t.cir
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o 
%t-cir.ll
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
+// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s
+
+// A weakref declaration that is never referenced should produce no output for
+// either the alias or its target. Only the unrelated definition below should
+// be emitted.
+void weakref_target(void);
+static void weakref_alias(void) __attribute__((weakref("weakref_target")));
+
+void unrelated(void) {}
+
+// The weakref alias produces no output by itself.
+// CIR-NOT: @weakref_alias
+// CIR-NOT: @weakref_target
+// LLVM-NOT: @weakref_alias
+// LLVM-NOT: @weakref_target
+// OGCG-NOT: @weakref_alias
+// OGCG-NOT: @weakref_target
+
+// CIR: cir.func{{.*}}@unrelated
+// LLVM: define{{.*}}@unrelated
+// OGCG: define{{.*}}@unrelated
diff --git a/clang/test/CIR/IR/invalid-global.cir 
b/clang/test/CIR/IR/invalid-global.cir
new file mode 100644
index 0000000000000..d0a2f0d116c7f
--- /dev/null
+++ b/clang/test/CIR/IR/invalid-global.cir
@@ -0,0 +1,42 @@
+// RUN: cir-opt %s -verify-diagnostics -split-input-file
+
+!s32i = !cir.int<s, 32>
+
+module {
+
+cir.global external @target = #cir.int<42> : !s32i
+
+// expected-error @below {{global alias shall not have an initializer or 
constructor/destructor regions}}
+cir.global external @bad_alias_with_init alias(@target) = #cir.int<7> : !s32i
+
+}
+
+// -----
+
+!s32i = !cir.int<s, 32>
+
+module {
+
+cir.global external @target = #cir.int<42> : !s32i
+
+// expected-error @below {{global alias shall not have an initializer or 
constructor/destructor regions}}
+cir.global external @bad_alias_with_ctor alias(@target) = ctor : !s32i {
+  cir.yield
+}
+
+}
+
+// -----
+
+!s32i = !cir.int<s, 32>
+
+module {
+
+cir.global external @target = #cir.int<42> : !s32i
+
+// expected-error @below {{global alias shall not have an initializer or 
constructor/destructor regions}}
+cir.global external @bad_alias_with_dtor alias(@target) = #cir.int<7> : !s32i 
dtor {
+  cir.yield
+}
+
+}

>From cbe9f5595e0ae3a3cd84006b8b81e0b19ccc26d6 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <[email protected]>
Date: Wed, 6 May 2026 11:51:33 -0700
Subject: [PATCH 2/2] Address review feedback

---
 .../clang/CIR/Interfaces/CIROpInterfaces.td   | 26 ++++++++++++++
 clang/lib/CIR/CodeGen/CIRGenModule.cpp        | 35 +++++++++----------
 2 files changed, 43 insertions(+), 18 deletions(-)

diff --git a/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td 
b/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
index 898e28964eef0..1e0c1298baa3a 100644
--- a/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
+++ b/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
@@ -171,6 +171,32 @@ let cppNamespace = "::cir" in {
         return mlir::dyn_cast_if_present<mlir::StringAttr>(
             $_op->getAttr("section"));
       }]
+      >,
+      // Added for readability.
+      InterfaceMethod<"",
+      "bool", "isDefinition", (ins), [{}],
+      /*defaultImplementation=*/[{
+        return !$_op.isDeclaration();
+      }]
+      >,
+      // TODO(cir): Make GlobalAlias a separate op.
+      InterfaceMethod<"",
+      "void", "setAliasee", (ins "::std::optional<::llvm::StringRef>":$val), 
[{}],
+      /*defaultImplementation=*/[{
+        if (val) {
+          auto aliaseeRef =
+              ::mlir::FlatSymbolRefAttr::get($_op->getContext(), *val);
+          $_op->setAttr("aliasee", aliaseeRef);
+        } else {
+          $_op->removeAttr("aliasee");
+        }
+      }]
+      >,
+      InterfaceMethod<"",
+      "void", "setLinkage", (ins "::cir::GlobalLinkageKind":$val), [{}],
+      /*defaultImplementation=*/[{
+        $_op.setLinkage(val);
+      }]
       >
     ];
     let extraClassDeclaration = [{
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp 
b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index bf6b5a22e6c4e..923253ac5f722 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -3404,7 +3404,7 @@ void CIRGenModule::emitAliasDefinition(GlobalDecl gd) {
   mlir::Operation *entry = getGlobalValue(mangledName);
   if (entry) {
     auto entryGV = mlir::dyn_cast<cir::CIRGlobalValueInterface>(entry);
-    if (entryGV && !entryGV.isDeclaration())
+    if (entryGV && entryGV.isDefinition())
       return;
   }
 
@@ -3413,7 +3413,7 @@ void CIRGenModule::emitAliasDefinition(GlobalDecl gd) {
   assert(!cir::MissingFeatures::checkAliases());
 
   mlir::Location loc = getLoc(d->getSourceRange());
-  const bool isFunction = isa<FunctionDecl>(d);
+  bool isFunction = isa<FunctionDecl>(d);
 
   // Get the linkage and the type of the alias.
   cir::GlobalLinkageKind linkage;
@@ -3447,22 +3447,21 @@ void CIRGenModule::emitAliasDefinition(GlobalDecl gd) {
   mlir::SymbolTable::Visibility visibility =
       getMLIRVisibilityFromCIRLinkage(linkage);
 
-  if (isFunction) {
-    cir::FuncType fnType = mlir::cast<cir::FuncType>(declTy);
-    cir::FuncOp alias =
-        createCIRFunction(loc, mangledName, fnType, cast<FunctionDecl>(d));
-    alias.setAliasee(aa->getAliasee());
-    alias.setLinkage(linkage);
-    mlir::SymbolTable::setSymbolVisibility(alias, visibility);
-    setCommonAttributes(gd, alias);
-  } else {
-    cir::GlobalOp alias = createGlobalOp(*this, loc, mangledName, declTy);
-    alias.setAliasee(aa->getAliasee());
-    alias.setLinkage(linkage);
-    mlir::SymbolTable::setSymbolVisibility(alias, visibility);
-    assert(!cir::MissingFeatures::opGlobalThreadLocal());
-    setCommonAttributes(gd, alias);
-  }
+  // TODO(cir): Make GlobalAlias a separate op.
+  cir::CIRGlobalValueInterface alias =
+      isFunction
+          ? mlir::cast<cir::CIRGlobalValueInterface>(
+                createCIRFunction(loc, mangledName,
+                                  mlir::cast<cir::FuncType>(declTy),
+                                  cast<FunctionDecl>(d))
+                    .getOperation())
+          : mlir::cast<cir::CIRGlobalValueInterface>(
+                createGlobalOp(*this, loc, mangledName, 
declTy).getOperation());
+  alias.setAliasee(aa->getAliasee());
+  alias.setLinkage(linkage);
+  mlir::SymbolTable::setSymbolVisibility(alias, visibility);
+  assert(!cir::MissingFeatures::opGlobalThreadLocal());
+  setCommonAttributes(gd, alias);
   assert(!cir::MissingFeatures::generateDebugInfo());
 }
 

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

Reply via email to