Author: Andy Kaylor
Date: 2026-08-10T13:11:45-07:00
New Revision: f3d0df914d37098eb8b6c12e8c81ac7842119052

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

LOG: [CIR] Add alias analysis skeleton (#214357)

This change adds the skeleton of MLIR alias analysis for CIR and
implements a very basic AA handler. More thorough AA implementations for
things like TBAA and restrict keyword handling will be added in the
future. This change is intended only to put the basic framework in
place.

Assisted-by: Claude / Sonnet-4.6

Added: 
    clang/include/clang/CIR/Dialect/Analysis/CIRAliasAnalysis.h
    clang/include/clang/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.h
    clang/lib/CIR/Dialect/Analysis/CIRAliasAnalysis.cpp
    clang/lib/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.cpp
    clang/lib/CIR/Dialect/Analysis/CMakeLists.txt
    clang/test/CIR/Analysis/alias-analysis-modref.cir
    clang/test/CIR/Analysis/alias-analysis.cir
    clang/test/CIR/lib/Analysis/CMakeLists.txt
    clang/test/CIR/lib/Analysis/TestCIRAliasAnalysis.cpp
    clang/test/CIR/lib/CMakeLists.txt
    clang/test/CIR/lib/lit.local.cfg

Modified: 
    clang/lib/CIR/Dialect/CMakeLists.txt
    clang/test/CMakeLists.txt
    clang/tools/cir-opt/CMakeLists.txt
    clang/tools/cir-opt/cir-opt.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/CIR/Dialect/Analysis/CIRAliasAnalysis.h 
b/clang/include/clang/CIR/Dialect/Analysis/CIRAliasAnalysis.h
new file mode 100644
index 0000000000000..df074f9393b0c
--- /dev/null
+++ b/clang/include/clang/CIR/Dialect/Analysis/CIRAliasAnalysis.h
@@ -0,0 +1,34 @@
+//===- CIRAliasAnalysis.h - CIR Alias Analysis Suite ------------*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the registration function for the full suite of CIR alias
+// analysis implementations. Callers that want all CIR analyses should use
+// registerCIRAliasAnalyses() rather than adding individual implementations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CIR_DIALECT_ANALYSIS_CIRALIASANALYSIS_H
+#define CLANG_CIR_DIALECT_ANALYSIS_CIRALIASANALYSIS_H
+
+#include "mlir/Analysis/AliasAnalysis.h"
+
+namespace cir {
+
+/// Register all CIR alias analysis implementations with `aa`.
+///
+/// Passes that want full CIR alias information should call this rather than
+/// adding individual implementations:
+///
+///   mlir::AliasAnalysis aa(funcOp);
+///   cir::registerCIRAliasAnalyses(aa);
+///
+void registerCIRAliasAnalyses(mlir::AliasAnalysis &aa);
+
+} // namespace cir
+
+#endif // CLANG_CIR_DIALECT_ANALYSIS_CIRALIASANALYSIS_H

diff  --git a/clang/include/clang/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.h 
b/clang/include/clang/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.h
new file mode 100644
index 0000000000000..f653534060080
--- /dev/null
+++ b/clang/include/clang/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.h
@@ -0,0 +1,60 @@
+//===- CIRBasicAliasAnalysis.h - Basic CIR Alias Analysis -------*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines CIRBasicAliasAnalysis, a CIR-specific alias analysis
+// implementation based on pointer provenance and distinct allocation sites.
+// Register with an mlir::AliasAnalysis aggregate via
+// addAnalysisImplementation(), or use registerCIRAliasAnalyses() to add the
+// full suite of CIR analyses at once.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CIR_DIALECT_ANALYSIS_CIRBASICALIASANALYSIS_H
+#define CLANG_CIR_DIALECT_ANALYSIS_CIRBASICALIASANALYSIS_H
+
+#include "mlir/Analysis/AliasAnalysis.h"
+#include "mlir/IR/Operation.h"
+#include "mlir/IR/Value.h"
+
+namespace cir {
+
+/// Basic CIR alias analysis based on pointer provenance and distinct 
allocation
+/// sites. Conservative defaults (MayAlias / ModRef) are returned for cases
+/// that are not yet handled.
+class CIRBasicAliasAnalysis {
+public:
+  CIRBasicAliasAnalysis() = default;
+  CIRBasicAliasAnalysis(CIRBasicAliasAnalysis &&) = default;
+
+  /// Return the aliasing behavior between two values.
+  ///
+  /// Returns MayAlias conservatively unless a more precise result can be
+  /// determined from CIR-specific information (e.g. distinct alloca ops,
+  /// pointer provenance, restrict attributes).
+  mlir::AliasResult alias(mlir::Value lhs, mlir::Value rhs);
+
+  /// Return the modify-reference behavior of `op` on `location`.
+  ///
+  /// Returns ModRef conservatively. CIR ops that carry explicit memory-effect
+  /// attributes or that are known to be pure/read-only can be handled here.
+  mlir::ModRefResult getModRef(mlir::Operation *op, mlir::Value location);
+
+private:
+  /// Attempt to find the underlying allocation source for `val` by walking
+  /// through pointer arithmetic, casts, and other CIR ops. Returns `val` if
+  /// no more specific source is found.
+  mlir::Value getUnderlyingObject(mlir::Value val);
+
+  /// Return true if `lhs` and `rhs` are provably 
diff erent allocations and
+  /// therefore cannot alias.
+  bool areDistinctObjects(mlir::Value lhs, mlir::Value rhs);
+};
+
+} // namespace cir
+
+#endif // CLANG_CIR_DIALECT_ANALYSIS_CIRBASICALIASANALYSIS_H

diff  --git a/clang/lib/CIR/Dialect/Analysis/CIRAliasAnalysis.cpp 
b/clang/lib/CIR/Dialect/Analysis/CIRAliasAnalysis.cpp
new file mode 100644
index 0000000000000..03daf3ae4c37c
--- /dev/null
+++ b/clang/lib/CIR/Dialect/Analysis/CIRAliasAnalysis.cpp
@@ -0,0 +1,14 @@
+//===- CIRAliasAnalysis.cpp - CIR Alias Analysis Suite 
--------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/CIR/Dialect/Analysis/CIRAliasAnalysis.h"
+#include "clang/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.h"
+
+void cir::registerCIRAliasAnalyses(mlir::AliasAnalysis &aa) {
+  aa.addAnalysisImplementation(CIRBasicAliasAnalysis());
+}

diff  --git a/clang/lib/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.cpp 
b/clang/lib/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.cpp
new file mode 100644
index 0000000000000..d56454ddb4586
--- /dev/null
+++ b/clang/lib/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.cpp
@@ -0,0 +1,157 @@
+//===- CIRBasicAliasAnalysis.cpp - Basic CIR Alias Analysis 
---------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.h"
+#include "mlir/Interfaces/SideEffectInterfaces.h"
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
+#include "llvm/Support/DebugLog.h"
+
+#define DEBUG_TYPE "cir-basic-alias-analysis"
+
+using namespace llvm;
+using namespace cir;
+
+//===----------------------------------------------------------------------===//
+// Helpers
+//===----------------------------------------------------------------------===//
+
+mlir::Value CIRBasicAliasAnalysis::getUnderlyingObject(mlir::Value val) {
+  LDBG() << "Getting underlying object for: " << val;
+
+  // TODO: Walk through cir.ptr_stride, cir.cast, cir.get_member, etc.
+  // to find the root allocation (cir.alloca, cir.global_addr, function args).
+  LDBG() << "Not yet implemented";
+  return val;
+}
+
+bool CIRBasicAliasAnalysis::areDistinctObjects(mlir::Value lhs,
+                                               mlir::Value rhs) {
+  LDBG() << "Checking if " << lhs << " and " << rhs << " are distinct objects";
+
+  // Two values are distinct allocations if they originate from 
diff erent
+  // cir.alloca operations (or other allocation ops) in the same function.
+  // TODO: Extend to cover global addresses, function arguments with noalias,
+  // and heap allocations.
+  mlir::Value lhsObj = getUnderlyingObject(lhs);
+  mlir::Value rhsObj = getUnderlyingObject(rhs);
+
+  if (lhsObj == rhsObj) {
+    LDBG() << "Identical values, not distinct";
+    return false;
+  }
+
+  // Different cir.alloca ops in the same function cannot alias.
+  if (mlir::isa_and_nonnull<cir::AllocaOp>(lhsObj.getDefiningOp()) &&
+      mlir::isa_and_nonnull<cir::AllocaOp>(rhsObj.getDefiningOp())) {
+    LDBG() << "Different cir.alloca ops in the same function, distinct";
+    return true;
+  }
+
+  LDBG() << "Conservative fallback, not distinct";
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// CIRBasicAliasAnalysis
+//===----------------------------------------------------------------------===//
+
+mlir::AliasResult CIRBasicAliasAnalysis::alias(mlir::Value lhs,
+                                               mlir::Value rhs) {
+  LDBG() << "Checking alias between: " << lhs << " and " << rhs;
+
+  if (lhs == rhs) {
+    LDBG() << "Trivial alias between identical values";
+    return mlir::AliasResult::MustAlias;
+  }
+
+  if (areDistinctObjects(lhs, rhs)) {
+    LDBG() << "No alias between distinct objects";
+    return mlir::AliasResult::NoAlias;
+  }
+
+  // Conservative fallback — the aggregate will try other implementations.
+  LDBG() << "Conservative fallback, may alias";
+  return mlir::AliasResult::MayAlias;
+}
+
+mlir::ModRefResult CIRBasicAliasAnalysis::getModRef(mlir::Operation *op,
+                                                    mlir::Value location) {
+  LDBG() << "getModRef: "
+         << mlir::OpWithFlags(op, mlir::OpPrintingFlags().skipRegions())
+         << " on location " << location;
+
+  auto effects = mlir::dyn_cast<mlir::MemoryEffectOpInterface>(op);
+  if (!effects) {
+    LDBG() << "No memory effect interface, returning ModAndRef";
+    return mlir::ModRefResult::getModAndRef();
+  }
+
+  SmallVector<mlir::MemoryEffects::EffectInstance> effectList;
+  effects.getEffects(effectList);
+
+  auto classifyEffect = [location, this](
+                            const mlir::MemoryEffects::EffectInstance &effect) 
{
+    if (mlir::isa<mlir::MemoryEffects::Allocate>(effect.getEffect())) {
+      LDBG() << "Skipping allocate effect";
+      return mlir::ModRefResult::getNoModRef();
+    }
+
+    mlir::AliasResult aliasResult = mlir::AliasResult::MayAlias;
+    if (mlir::Value affectedLocation = effect.getValue()) {
+      LDBG() << "    Checking alias between affected location "
+             << affectedLocation << " and query location " << location;
+      aliasResult = alias(affectedLocation, location);
+      LDBG() << "    Alias result: "
+             << (aliasResult.isMust() ? "MustAlias"
+                 : aliasResult.isNo() ? "NoAlias"
+                                      : "MayAlias");
+    } else {
+      // An effect on a non-addressable resource cannot affect a
+      // pointer-based location.
+      if (!effect.getResource()->isAddressable()) {
+        LDBG() << "    Effect on non-addressable resource '"
+               << effect.getResource()->getName() << "', skipping (NoAlias)";
+        aliasResult = mlir::AliasResult::NoAlias;
+      } else {
+        LDBG() << "    No effect value, assuming MayAlias";
+      }
+    }
+
+    // If the affected location doesn't alias with the query location,
+    // ignore this effect.
+    if (aliasResult.isNo()) {
+      LDBG() << "No alias with affected location";
+      return mlir::ModRefResult::getNoModRef();
+    }
+
+    // TODO: Consider whether Free should be NoModRef.
+    if (mlir::isa<mlir::MemoryEffects::Free>(effect.getEffect())) {
+      LDBG() << "Skipping free effect";
+      return mlir::ModRefResult::getModAndRef();
+    }
+
+    if (mlir::isa<mlir::MemoryEffects::Write>(effect.getEffect())) {
+      LDBG() << "Write effect, adding Mod";
+      return mlir::ModRefResult::getMod();
+    }
+
+    if (mlir::isa<mlir::MemoryEffects::Read>(effect.getEffect())) {
+      LDBG() << "Read effect, adding Ref";
+      return mlir::ModRefResult::getRef();
+    }
+
+    LDBG() << "Unexpected memory effect: " << effect.getEffect();
+    return mlir::ModRefResult::getNoModRef();
+  };
+
+  return llvm::accumulate(llvm::map_range(effectList, classifyEffect),
+                          mlir::ModRefResult::getNoModRef(),
+                          [](mlir::ModRefResult lhs, mlir::ModRefResult rhs) {
+                            return lhs.merge(rhs);
+                          });
+}

diff  --git a/clang/lib/CIR/Dialect/Analysis/CMakeLists.txt 
b/clang/lib/CIR/Dialect/Analysis/CMakeLists.txt
new file mode 100644
index 0000000000000..778119c4f7731
--- /dev/null
+++ b/clang/lib/CIR/Dialect/Analysis/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_clang_library(MLIRCIRAnalysis
+  CIRAliasAnalysis.cpp
+  CIRBasicAliasAnalysis.cpp
+
+  LINK_LIBS PUBLIC
+  MLIRCIR
+  MLIRIR
+  MLIRAnalysis
+  MLIRSideEffectInterfaces
+)

diff  --git a/clang/lib/CIR/Dialect/CMakeLists.txt 
b/clang/lib/CIR/Dialect/CMakeLists.txt
index e05c9becebbad..6aacd029d845d 100644
--- a/clang/lib/CIR/Dialect/CMakeLists.txt
+++ b/clang/lib/CIR/Dialect/CMakeLists.txt
@@ -1,3 +1,4 @@
+add_subdirectory(Analysis)
 add_subdirectory(IR)
 add_subdirectory(OpenACC)
 add_subdirectory(OpenMP)

diff  --git a/clang/test/CIR/Analysis/alias-analysis-modref.cir 
b/clang/test/CIR/Analysis/alias-analysis-modref.cir
new file mode 100644
index 0000000000000..d02a6f06bfc3e
--- /dev/null
+++ b/clang/test/CIR/Analysis/alias-analysis-modref.cir
@@ -0,0 +1,56 @@
+// Use --mlir-disable-threading so that the AA queries are serialized
+// as well as their diagnostic output.
+// RUN: cir-opt %s 
-pass-pipeline='builtin.module(cir.func(test-cir-alias-analysis-modref))' \
+// RUN:   -split-input-file --mlir-disable-threading 2>&1 | FileCheck %s
+
+// -----
+
+// A cir.store Mod-s the location it writes to. The alloca itself only has
+// an Alloc effect on its result and therefore NoModRef.
+
+// CHECK-LABEL: Testing : "modref_store"
+// CHECK-DAG: store_op -> x#0: Mod
+// CHECK-DAG: x -> x#0: NoModRef
+
+!s32i = !cir.int<s, 32>
+cir.func @modref_store() {
+  %x = cir.alloca "x" align(4) : !cir.ptr<!s32i> {test.ptr = "x"}
+  %val = cir.const #cir.int<1> : !s32i
+  cir.store %val, %x {test.ptr = "store_op"} : !s32i, !cir.ptr<!s32i>
+  cir.return
+}
+
+// -----
+
+// A cir.load Ref-s the location it reads from.
+
+// CHECK-LABEL: Testing : "modref_load"
+// CHECK-DAG: load_op -> x#0: Ref
+// CHECK-DAG: x -> x#0: NoModRef
+
+!s32i = !cir.int<s, 32>
+cir.func @modref_load() {
+  %x = cir.alloca "x" align(4) init : !cir.ptr<!s32i> {test.ptr = "x"}
+  %val = cir.const #cir.int<42> : !s32i
+  cir.store %val, %x : !s32i, !cir.ptr<!s32i>
+  %0 = cir.load %x : !cir.ptr<!s32i>, !s32i {test.ptr = "load_op"}
+  cir.return
+}
+
+// -----
+
+// A cir.fadd with an `fenv` attribute has Read/Write effects on the
+// non-addressable FloatingPointEnvironment resource and no associated
+// Value. Such effects can never alias a pointer-based location, so the
+// result is NoModRef regardless of the queried location.
+
+// CHECK-LABEL: Testing : "modref_fenv"
+// CHECK-DAG: fadd_op -> x#0: NoModRef
+// CHECK-DAG: x -> x#0: NoModRef
+
+!s32i = !cir.int<s, 32>
+cir.func @modref_fenv(%a: !cir.float, %b: !cir.float) {
+  %x = cir.alloca "x" align(4) : !cir.ptr<!s32i> {test.ptr = "x"}
+  %0 = cir.fadd %a, %b : !cir.float {fenv = #cir.fenv<>, test.ptr = "fadd_op"}
+  cir.return
+}

diff  --git a/clang/test/CIR/Analysis/alias-analysis.cir 
b/clang/test/CIR/Analysis/alias-analysis.cir
new file mode 100644
index 0000000000000..c4705ce2a9c3e
--- /dev/null
+++ b/clang/test/CIR/Analysis/alias-analysis.cir
@@ -0,0 +1,65 @@
+// Use --mlir-disable-threading so that the AA queries are serialized
+// as well as their diagnostic output.
+// RUN: cir-opt %s 
-pass-pipeline='builtin.module(cir.func(test-cir-alias-analysis))' \
+// RUN:   -split-input-file --mlir-disable-threading 2>&1 | FileCheck %s
+
+// -----
+
+// Two distinct cir.alloca ops in the same function cannot alias.
+
+// CHECK-LABEL: Testing : "distinct_allocas"
+// CHECK-DAG: x#0 <-> y#0: NoAlias
+
+!s32i = !cir.int<s, 32>
+cir.func @distinct_allocas() {
+  %x = cir.alloca "x" align(4) : !cir.ptr<!s32i> {test.ptr = "x"}
+  %y = cir.alloca "y" align(4) : !cir.ptr<!s32i> {test.ptr = "y"}
+  cir.return
+}
+
+// -----
+
+// Three distinct allocas are mutually non-aliasing.
+
+// CHECK-LABEL: Testing : "three_distinct_allocas"
+// CHECK-DAG: a#0 <-> b#0: NoAlias
+// CHECK-DAG: a#0 <-> c#0: NoAlias
+// CHECK-DAG: b#0 <-> c#0: NoAlias
+
+!s32i = !cir.int<s, 32>
+cir.func @three_distinct_allocas() {
+  %a = cir.alloca "a" align(4) : !cir.ptr<!s32i> {test.ptr = "a"}
+  %b = cir.alloca "b" align(4) : !cir.ptr<!s32i> {test.ptr = "b"}
+  %c = cir.alloca "c" align(4) : !cir.ptr<!s32i> {test.ptr = "c"}
+  cir.return
+}
+
+// -----
+
+// Function arguments have unknown provenance — they may alias each other.
+// test.ptr goes on the cir.func op; args are addressed as func.region0#N.
+
+// CHECK-LABEL: Testing : "ptr_args_may_alias"
+// CHECK-DAG: func.region0#0 <-> func.region0#1: MayAlias
+
+!s32i = !cir.int<s, 32>
+cir.func @ptr_args_may_alias(%p: !cir.ptr<!s32i>, %q: !cir.ptr<!s32i>)
+    attributes {test.ptr = "func"} {
+  cir.return
+}
+
+// -----
+
+// A local alloca cannot alias a pointer argument: the alloca is a fresh
+// allocation that did not exist before the call, so no pre-existing pointer
+// can refer to it.
+
+// CHECK-LABEL: Testing : "arg_and_alloca_no_alias"
+// CHECK-DAG: local#0 <-> func.region0#0: NoAlias
+
+!s32i = !cir.int<s, 32>
+cir.func @arg_and_alloca_no_alias(%p: !cir.ptr<!s32i>)
+    attributes {test.ptr = "func"} {
+  %local = cir.alloca "local" align(4) : !cir.ptr<!s32i> {test.ptr = "local"}
+  cir.return
+}

diff  --git a/clang/test/CIR/lib/Analysis/CMakeLists.txt 
b/clang/test/CIR/lib/Analysis/CMakeLists.txt
new file mode 100644
index 0000000000000..6a20fb43ce8b0
--- /dev/null
+++ b/clang/test/CIR/lib/Analysis/CMakeLists.txt
@@ -0,0 +1,16 @@
+add_clang_library(CIRTestAnalysis
+  TestCIRAliasAnalysis.cpp
+
+  LINK_LIBS PUBLIC
+  MLIRCIRAnalysis
+  MLIRCIR
+  MLIRIR
+  MLIRAnalysis
+  MLIRPass
+  MLIRTestAnalysis
+)
+
+target_include_directories(CIRTestAnalysis
+  PRIVATE
+  ${LLVM_MAIN_SRC_DIR}/..
+)

diff  --git a/clang/test/CIR/lib/Analysis/TestCIRAliasAnalysis.cpp 
b/clang/test/CIR/lib/Analysis/TestCIRAliasAnalysis.cpp
new file mode 100644
index 0000000000000..2bee3f522ab91
--- /dev/null
+++ b/clang/test/CIR/lib/Analysis/TestCIRAliasAnalysis.cpp
@@ -0,0 +1,72 @@
+//===- TestCIRAliasAnalysis.cpp - Test CIR alias analysis results 
----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Pass/Pass.h"
+#include "mlir/test/lib/Analysis/TestAliasAnalysis.h"
+#include "clang/CIR/Dialect/Analysis/CIRAliasAnalysis.h"
+
+using namespace mlir;
+
+namespace {
+
+//===----------------------------------------------------------------------===//
+// Testing AliasResult
+//===----------------------------------------------------------------------===//
+
+struct TestCIRAliasAnalysisPass
+    : public test::TestAliasAnalysisBase,
+      PassWrapper<TestCIRAliasAnalysisPass, OperationPass<>> {
+  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestCIRAliasAnalysisPass)
+
+  StringRef getArgument() const final { return "test-cir-alias-analysis"; }
+  StringRef getDescription() const final {
+    return "Test CIR alias analysis results.";
+  }
+  void runOnOperation() override {
+    mlir::AliasAnalysis aliasAnalysis(getOperation());
+    cir::registerCIRAliasAnalyses(aliasAnalysis);
+    runAliasAnalysisOnOperation(getOperation(), aliasAnalysis);
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Testing ModRefResult
+//===----------------------------------------------------------------------===//
+
+struct TestCIRAliasAnalysisModRefPass
+    : public test::TestAliasAnalysisModRefBase,
+      PassWrapper<TestCIRAliasAnalysisModRefPass, OperationPass<>> {
+  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestCIRAliasAnalysisModRefPass)
+
+  StringRef getArgument() const final {
+    return "test-cir-alias-analysis-modref";
+  }
+  StringRef getDescription() const final {
+    return "Test CIR alias analysis ModRef results.";
+  }
+  void runOnOperation() override {
+    mlir::AliasAnalysis aliasAnalysis(getOperation());
+    cir::registerCIRAliasAnalyses(aliasAnalysis);
+    runAliasAnalysisOnOperation(getOperation(), aliasAnalysis);
+  }
+};
+
+} // namespace
+
+//===----------------------------------------------------------------------===//
+// Pass Registration
+//===----------------------------------------------------------------------===//
+
+namespace cir {
+namespace test {
+void registerTestCIRAliasAnalysisPass() {
+  PassRegistration<TestCIRAliasAnalysisPass>();
+  PassRegistration<TestCIRAliasAnalysisModRefPass>();
+}
+} // namespace test
+} // namespace cir

diff  --git a/clang/test/CIR/lib/CMakeLists.txt 
b/clang/test/CIR/lib/CMakeLists.txt
new file mode 100644
index 0000000000000..a084defdbdddb
--- /dev/null
+++ b/clang/test/CIR/lib/CMakeLists.txt
@@ -0,0 +1,4 @@
+include_directories(${LLVM_MAIN_SRC_DIR}/../mlir/include)
+include_directories(${CMAKE_BINARY_DIR}/tools/mlir/include)
+
+add_subdirectory(Analysis)

diff  --git a/clang/test/CIR/lib/lit.local.cfg 
b/clang/test/CIR/lib/lit.local.cfg
new file mode 100644
index 0000000000000..7d6f0d30cb3b0
--- /dev/null
+++ b/clang/test/CIR/lib/lit.local.cfg
@@ -0,0 +1,3 @@
+# Exclude .cpp files from test discovery — this directory contains library
+# source files used by the test infrastructure, not tests themselves.
+config.suffixes = []

diff  --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt
index 92883005dd88d..97d5992d803c5 100644
--- a/clang/test/CMakeLists.txt
+++ b/clang/test/CMakeLists.txt
@@ -118,6 +118,7 @@ if(CLANG_ENABLE_CIR)
     cir-translate
     mlir-translate
     )
+  add_subdirectory(CIR/lib)
 endif()
 
 if(CLANG_ENABLE_STATIC_ANALYZER)

diff  --git a/clang/tools/cir-opt/CMakeLists.txt 
b/clang/tools/cir-opt/CMakeLists.txt
index 287eba226cfe3..72cfff1800d41 100644
--- a/clang/tools/cir-opt/CMakeLists.txt
+++ b/clang/tools/cir-opt/CMakeLists.txt
@@ -15,10 +15,18 @@ if (LLVM_COMPILER_IS_GCC_COMPATIBLE AND (NOT 
"${CMAKE_CXX_COMPILER_ID}" MATCHES
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-overloaded-virtual")
 endif()
 
+if(CLANG_INCLUDE_TESTS)
+  set(cir_opt_test_libs CIRTestAnalysis)
+endif()
+
 add_clang_tool(cir-opt
   cir-opt.cpp
 )
 
+if(CLANG_INCLUDE_TESTS)
+  target_compile_definitions(cir-opt PRIVATE CLANG_INCLUDE_TESTS)
+endif()
+
 clang_target_link_libraries(cir-opt
   PRIVATE
   clangCIR
@@ -26,6 +34,7 @@ clang_target_link_libraries(cir-opt
   CIRRegisterAllDialects
   MLIRCIR
   MLIRCIRTransforms
+  ${cir_opt_test_libs}
 )
 
 target_link_libraries(cir-opt

diff  --git a/clang/tools/cir-opt/cir-opt.cpp b/clang/tools/cir-opt/cir-opt.cpp
index 9d29b56a5ad63..fdaf405441003 100644
--- a/clang/tools/cir-opt/cir-opt.cpp
+++ b/clang/tools/cir-opt/cir-opt.cpp
@@ -25,6 +25,12 @@
 #include "clang/CIR/InitAllDialects.h"
 #include "clang/CIR/Passes.h"
 
+#ifdef CLANG_INCLUDE_TESTS
+namespace cir::test {
+void registerTestCIRAliasAnalysisPass();
+} // namespace cir::test
+#endif
+
 struct CIRToLLVMPipelineOptions
     : public mlir::PassPipelineOptions<CIRToLLVMPipelineOptions> {
   Option<bool> enableOpenMP{
@@ -37,6 +43,10 @@ int main(int argc, char **argv) {
   // TODO: register needed MLIR passes for CIR?
   mlir::DialectRegistry registry;
   cir::registerAllDialects(registry);
+
+#ifdef CLANG_INCLUDE_TESTS
+  cir::test::registerTestCIRAliasAnalysisPass();
+#endif
   registry.insert<mlir::memref::MemRefDialect, mlir::LLVM::LLVMDialect>();
 
   ::mlir::registerPass([]() -> std::unique_ptr<::mlir::Pass> {


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

Reply via email to