llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Andrzej Warzyński (banach-space) <details> <summary>Changes</summary> This reverts commit 23ca09c96d24b5cd06f54a3c764e9acede166b44. The included test does not pass (alias-analysis-underlying-object.cir). Since the change is quite subtle, I propose to revert. --- Patch is 20.84 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/216278.diff 3 Files Affected: - (modified) clang/include/clang/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.h (+3-14) - (modified) clang/lib/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.cpp (+13-120) - (removed) clang/test/CIR/Analysis/alias-analysis-underlying-object.cir (-305) ``````````diff diff --git a/clang/include/clang/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.h b/clang/include/clang/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.h index 014688092c597..f653534060080 100644 --- a/clang/include/clang/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.h +++ b/clang/include/clang/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.h @@ -27,15 +27,6 @@ namespace cir { /// sites. Conservative defaults (MayAlias / ModRef) are returned for cases /// that are not yet handled. class CIRBasicAliasAnalysis { - enum class ObjectRelation { - /// Provably different underlying allocations. - Distinct, - /// Same underlying allocation, no offset. - Identical, - /// Cannot determine the relationship. - Unknown, - }; - public: CIRBasicAliasAnalysis() = default; CIRBasicAliasAnalysis(CIRBasicAliasAnalysis &&) = default; @@ -59,11 +50,9 @@ class CIRBasicAliasAnalysis { /// no more specific source is found. mlir::Value getUnderlyingObject(mlir::Value val); - /// Classify the relationship between \p lhs and \p rhs. Returns one of: - /// Distinct – provably different allocations - /// Identical – same allocation, no offset - /// Unknown – cannot determine - ObjectRelation classifyObjects(mlir::Value lhs, mlir::Value rhs); + /// Return true if `lhs` and `rhs` are provably different allocations and + /// therefore cannot alias. + bool areDistinctObjects(mlir::Value lhs, mlir::Value rhs); }; } // namespace cir diff --git a/clang/lib/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.cpp b/clang/lib/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.cpp index ceaca4916fdae..d56454ddb4586 100644 --- a/clang/lib/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.cpp +++ b/clang/lib/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.cpp @@ -8,7 +8,6 @@ #include "clang/CIR/Dialect/Analysis/CIRBasicAliasAnalysis.h" #include "mlir/Interfaces/SideEffectInterfaces.h" -#include "clang/CIR/Dialect/IR/CIRAttrs.h" #include "clang/CIR/Dialect/IR/CIRDialect.h" #include "llvm/Support/DebugLog.h" @@ -21,117 +20,17 @@ using namespace cir; // Helpers //===----------------------------------------------------------------------===// -static constexpr unsigned MaxLookupDepth = 6; - mlir::Value CIRBasicAliasAnalysis::getUnderlyingObject(mlir::Value val) { LDBG() << "Getting underlying object for: " << val; - for (unsigned depth = 0; depth < MaxLookupDepth; ++depth) { - mlir::Operation *defOp = val.getDefiningOp(); - if (!defOp) { - LDBG() << "No defining operation, stopping"; - break; // Block argument (e.g. function parameter) — stop here. - } - - // Bitcast and address-space casts don't change the underlying object. - // array_to_ptrdecay produces an element pointer to the same storage as - // the array pointer, so strip through it too. - if (auto castOp = mlir::dyn_cast<cir::CastOp>(defOp)) { - if (castOp.isAllocaPreservingCast() || - castOp.getKind() == cir::CastKind::array_to_ptrdecay) { - LDBG() << "Walking past cast operation"; - val = castOp.getSrc(); - continue; - } - LDBG() << "Opaque cast operation, stopping"; - break; - } - - // Pointer stride: only strip through when we can prove the access stays - // within the bounds of the underlying allocation. - if (auto strideOp = mlir::dyn_cast<cir::PtrStrideOp>(defOp)) { - auto constOp = strideOp.getStride().getDefiningOp<cir::ConstantOp>(); - if (constOp) { - if (auto intAttr = mlir::dyn_cast<cir::IntAttr>(constOp.getValue())) { - APInt stride = intAttr.getValue(); - - // Zero stride is trivially in-bounds. - if (stride.isZero()) { - LDBG() << "Walking past zero-strided PtrStrideOp"; - val = strideOp.getBase(); - continue; - } - } - } - // Dynamic stride or unverifiable bounds — stop here conservatively. - LDBG() << "Non-zero or dynamic PtrStrideOp, stopping"; - break; - } - - // Handle special cases for zero-offset sub-object accesses. - if (auto op = mlir::dyn_cast<cir::GetMemberOp>(defOp)) { - if (op.getIndex() == 0) { - LDBG() << "GetMemberOp[0], following to underlying object"; - val = op.getAddr(); - continue; - } else { - LDBG() << "GetMemberOp, non-zero index, stopping"; - break; - } - } - if (auto op = mlir::dyn_cast<cir::GetElementOp>(defOp)) { - cir::IntAttr index; - if (auto constOp = op.getIndex().getDefiningOp<cir::ConstantOp>()) - index = mlir::dyn_cast<cir::IntAttr>(constOp.getValue()); - if (index && index.getValue().isZero()) { - LDBG() << "GetElementOp[0], following to underlying object"; - val = op.getBase(); - continue; - } - LDBG() << "GetElementOp, non-zero or dynamic index, stopping"; - break; - } - if (auto op = mlir::dyn_cast<cir::BaseClassAddrOp>(defOp)) { - // A zero byte offset means the base subobject starts at the same address - // as the derived object. - if (op.getOffset().isZero()) { - LDBG() << "BaseClassAddrOp[0], following to underlying object"; - val = op.getDerivedAddr(); - continue; - } - LDBG() << "BaseClassAddrOp, non-zero offset, stopping"; - break; - } - if (auto op = mlir::dyn_cast<cir::DerivedClassAddrOp>(defOp)) { - // The offset is stored unsigned but applied as a negative adjustment. A - // zero offset means the derived object starts at the same address as the - // base subobject. - if (op.getOffset().isZero()) { - LDBG() << "DerivedClassAddrOp[0], following to underlying object"; - val = op.getBaseAddr(); - continue; - } - LDBG() << "DerivedClassAddrOp, non-zero offset, stopping"; - break; - } - if (auto op = mlir::dyn_cast<cir::ComplexRealPtrOp>(defOp)) { - LDBG() << "Getting input pointer for ComplexRealPtrOp"; - val = op.getOperand(); - continue; - } - if (auto op = mlir::dyn_cast<cir::ComplexImagPtrOp>(defOp)) { - LDBG() << "ComplexImagPtrOp, stopping"; - break; - } - - LDBG() << "Unhandled operation, stopping"; - break; // Unknown op — stop here conservatively. - } + // 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; } -CIRBasicAliasAnalysis::ObjectRelation -CIRBasicAliasAnalysis::classifyObjects(mlir::Value lhs, mlir::Value rhs) { +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 different @@ -143,18 +42,18 @@ CIRBasicAliasAnalysis::classifyObjects(mlir::Value lhs, mlir::Value rhs) { if (lhsObj == rhsObj) { LDBG() << "Identical values, not distinct"; - return ObjectRelation::Identical; + 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 ObjectRelation::Distinct; + return true; } LDBG() << "Conservative fallback, not distinct"; - return ObjectRelation::Unknown; + return false; } //===----------------------------------------------------------------------===// @@ -170,20 +69,14 @@ mlir::AliasResult CIRBasicAliasAnalysis::alias(mlir::Value lhs, return mlir::AliasResult::MustAlias; } - ObjectRelation relation = classifyObjects(lhs, rhs); - switch (relation) { - case ObjectRelation::Distinct: + if (areDistinctObjects(lhs, rhs)) { LDBG() << "No alias between distinct objects"; return mlir::AliasResult::NoAlias; - case ObjectRelation::Identical: - LDBG() << "Must alias between identical objects"; - return mlir::AliasResult::MustAlias; - case ObjectRelation::Unknown: - // Conservative fallback — the aggregate will try other implementations. - LDBG() << "Conservative fallback, may alias"; - return mlir::AliasResult::MayAlias; } - llvm_unreachable("Unhandled ObjectRelation"); + + // Conservative fallback — the aggregate will try other implementations. + LDBG() << "Conservative fallback, may alias"; + return mlir::AliasResult::MayAlias; } mlir::ModRefResult CIRBasicAliasAnalysis::getModRef(mlir::Operation *op, diff --git a/clang/test/CIR/Analysis/alias-analysis-underlying-object.cir b/clang/test/CIR/Analysis/alias-analysis-underlying-object.cir deleted file mode 100644 index 73768fcd44241..0000000000000 --- a/clang/test/CIR/Analysis/alias-analysis-underlying-object.cir +++ /dev/null @@ -1,305 +0,0 @@ -// 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 - -// ----- - -// CHECK-LABEL: Testing : "bitcast_strips_to_alloca" -// CHECK-DAG: x#0 <-> y#0: NoAlias -// CHECK-DAG: x#0 <-> bc#0: MustAlias -// CHECK-DAG: y#0 <-> bc#0: NoAlias - -!s32i = !cir.int<s, 32> -!u8i = !cir.int<u, 8> -cir.func @bitcast_strips_to_alloca() { - %x = cir.alloca "x" align(4) : !cir.ptr<!s32i> {test.ptr = "x"} - %y = cir.alloca "y" align(4) : !cir.ptr<!s32i> {test.ptr = "y"} - %bc = cir.cast bitcast %x : !cir.ptr<!s32i> -> !cir.ptr<!u8i> {test.ptr = "bc"} - cir.return -} - -// ----- - -// CHECK-LABEL: Testing : "array_to_ptrdecay_strips_to_alloca" -// CHECK-DAG: arr#0 <-> other#0: NoAlias -// CHECK-DAG: arr#0 <-> ptr#0: MustAlias -// CHECK-DAG: other#0 <-> ptr#0: NoAlias - -!s32i = !cir.int<s, 32> -cir.func @array_to_ptrdecay_strips_to_alloca() { - %arr = cir.alloca "arr" align(4) : !cir.ptr<!cir.array<!s32i x 4>> {test.ptr = "arr"} - %other = cir.alloca "other" align(4) : !cir.ptr<!s32i> {test.ptr = "other"} - %ptr = cir.cast array_to_ptrdecay %arr - : !cir.ptr<!cir.array<!s32i x 4>> -> !cir.ptr<!s32i> {test.ptr = "ptr"} - cir.return -} - -// ----- - -// CHECK-LABEL: Testing : "ptr_stride_zero_strips_to_alloca" -// CHECK-DAG: arr#0 <-> other#0: NoAlias -// CHECK-DAG: arr#0 <-> ptr#0: MustAlias -// CHECK-DAG: other#0 <-> ptr#0: NoAlias -// CHECK-DAG: arr#0 <-> elem#0: MustAlias -// CHECK-DAG: other#0 <-> elem#0: NoAlias -// CHECK-DAG: ptr#0 <-> elem#0: MustAlias - -!s32i = !cir.int<s, 32> -cir.func @ptr_stride_zero_strips_to_alloca() { - %arr = cir.alloca "arr" align(4) : !cir.ptr<!cir.array<!s32i x 4>> {test.ptr = "arr"} - %other = cir.alloca "other" align(4) : !cir.ptr<!s32i> {test.ptr = "other"} - %ptr = cir.cast array_to_ptrdecay %arr - : !cir.ptr<!cir.array<!s32i x 4>> -> !cir.ptr<!s32i> {test.ptr = "ptr"} - %zero = cir.const #cir.int<0> : !s32i - %elem = cir.ptr_stride %ptr, %zero : (!cir.ptr<!s32i>, !s32i) -> !cir.ptr<!s32i> - {test.ptr = "elem"} - cir.return -} - -// ----- - -// CHECK-LABEL: Testing : "ptr_stride_inbounds_strips_to_alloca" -// CHECK-DAG: arr#0 <-> other#0: NoAlias -// CHECK-DAG: arr#0 <-> ptr#0: MustAlias -// CHECK-DAG: other#0 <-> ptr#0: NoAlias -// CHECK-DAG: arr#0 <-> elem#0: MayAlias -// CHECK-DAG: other#0 <-> elem#0: MayAlias -// CHECK-DAG: ptr#0 <-> elem#0: MayAlias - -!s32i = !cir.int<s, 32> -cir.func @ptr_stride_inbounds_strips_to_alloca() { - %arr = cir.alloca "arr" align(4) : !cir.ptr<!cir.array<!s32i x 4>> {test.ptr = "arr"} - %other = cir.alloca "other" align(4) : !cir.ptr<!s32i> {test.ptr = "other"} - %ptr = cir.cast array_to_ptrdecay %arr - : !cir.ptr<!cir.array<!s32i x 4>> -> !cir.ptr<!s32i> {test.ptr = "ptr"} - %two = cir.const #cir.int<2> : !s32i - %elem = cir.ptr_stride %ptr, %two : (!cir.ptr<!s32i>, !s32i) -> !cir.ptr<!s32i> - {test.ptr = "elem"} - cir.return -} - -// ----- - -// CHECK-LABEL: Testing : "ptr_stride_dynamic_not_stripped" -// CHECK-DAG: arr#0 <-> other#0: NoAlias -// CHECK-DAG: arr#0 <-> ptr#0: MustAlias -// CHECK-DAG: other#0 <-> ptr#0: NoAlias -// CHECK-DAG: arr#0 <-> dyn#0: MayAlias -// CHECK-DAG: other#0 <-> dyn#0: MayAlias -// CHECK-DAG: ptr#0 <-> dyn#0: MayAlias - -!s32i = !cir.int<s, 32> -cir.func @ptr_stride_dynamic_not_stripped(%n: !s32i) { - %arr = cir.alloca "arr" align(4) : !cir.ptr<!cir.array<!s32i x 4>> {test.ptr = "arr"} - %other = cir.alloca "other" align(4) : !cir.ptr<!s32i> {test.ptr = "other"} - %ptr = cir.cast array_to_ptrdecay %arr - : !cir.ptr<!cir.array<!s32i x 4>> -> !cir.ptr<!s32i> {test.ptr = "ptr"} - %dyn = cir.ptr_stride %ptr, %n : (!cir.ptr<!s32i>, !s32i) -> !cir.ptr<!s32i> - {test.ptr = "dyn"} - cir.return -} - -// ----- - -// CHECK-LABEL: Testing : "get_member_distinct_allocas" -// CHECK-DAG: s1#0 <-> s2#0: NoAlias -// CHECK-DAG: s1#0 <-> m1_0#0: MustAlias -// CHECK-DAG: s2#0 <-> m1_0#0: NoAlias -// CHECK-DAG: s1#0 <-> m1_1#0: MayAlias -// CHECK-DAG: s2#0 <-> m1_1#0: MayAlias -// CHECK-DAG: m1_0#0 <-> m1_1#0: MayAlias -// CHECK-DAG: s1#0 <-> m2_0#0: NoAlias -// CHECK-DAG: s2#0 <-> m2_0#0: MustAlias -// CHECK-DAG: m1_0#0 <-> m2_0#0: NoAlias -// CHECK-DAG: m1_1#0 <-> m2_0#0: MayAlias -// CHECK-DAG: s1#0 <-> m2_1#0: MayAlias -// CHECK-DAG: s2#0 <-> m2_1#0: MayAlias -// CHECK-DAG: m1_0#0 <-> m2_1#0: MayAlias -// CHECK-DAG: m1_1#0 <-> m2_1#0: MayAlias -// CHECK-DAG: m2_0#0 <-> m2_1#0: MayAlias - -!s32i = !cir.int<s, 32> -!rec_S = !cir.struct<"S" {!s32i, !s32i}> -cir.func @get_member_distinct_allocas() { - %s1 = cir.alloca "s1" align(4) : !cir.ptr<!rec_S> {test.ptr = "s1"} - %s2 = cir.alloca "s2" align(4) : !cir.ptr<!rec_S> {test.ptr = "s2"} - %m1_0 = cir.get_member %s1[0] {name = "x", test.ptr = "m1_0"} - : !cir.ptr<!rec_S> -> !cir.ptr<!s32i> - %m1_1 = cir.get_member %s1[1] {name = "y", test.ptr = "m1_1"} - : !cir.ptr<!rec_S> -> !cir.ptr<!s32i> - %m2_0 = cir.get_member %s2[0] {name = "x", test.ptr = "m2_0"} - : !cir.ptr<!rec_S> -> !cir.ptr<!s32i> - %m2_1 = cir.get_member %s2[1] {name = "y", test.ptr = "m2_1"} - : !cir.ptr<!rec_S> -> !cir.ptr<!s32i> - cir.return -} - -// ----- - -// CHECK-LABEL: Testing : "get_element_distinct_allocas" -// CHECK-DAG: a1#0 <-> a2#0: NoAlias -// CHECK-DAG: a1#0 <-> e1_0#0: MustAlias -// CHECK-DAG: a2#0 <-> e1_0#0: NoAlias -// CHECK-DAG: a1#0 <-> e2_0#0: NoAlias -// CHECK-DAG: a2#0 <-> e2_0#0: MustAlias -// CHECK-DAG: e1_0#0 <-> e2_0#0: NoAlias -// CHECK-DAG: a1#0 <-> e1_1#0: MayAlias -// CHECK-DAG: a2#0 <-> e1_1#0: MayAlias -// CHECK-DAG: e1_0#0 <-> e1_1#0: MayAlias -// CHECK-DAG: e2_0#0 <-> e1_1#0: MayAlias -// CHECK-DAG: a1#0 <-> e2_1#0: MayAlias -// CHECK-DAG: a2#0 <-> e2_1#0: MayAlias -// CHECK-DAG: e1_0#0 <-> e2_1#0: MayAlias -// CHECK-DAG: e2_0#0 <-> e2_1#0: MayAlias -// CHECK-DAG: e1_1#0 <-> e2_1#0: MayAlias - -!s32i = !cir.int<s, 32> -cir.func @get_element_distinct_allocas() { - %a1 = cir.alloca "a1" align(4) : !cir.ptr<!cir.array<!s32i x 4>> {test.ptr = "a1"} - %a2 = cir.alloca "a2" align(4) : !cir.ptr<!cir.array<!s32i x 4>> {test.ptr = "a2"} - %idx = cir.const #cir.int<0> : !s32i - %e1_0 = cir.get_element %a1[%idx : !s32i] {test.ptr = "e1_0"} - : !cir.ptr<!cir.array<!s32i x 4>> -> !cir.ptr<!s32i> - %e2_0 = cir.get_element %a2[%idx : !s32i] {test.ptr = "e2_0"} - : !cir.ptr<!cir.array<!s32i x 4>> -> !cir.ptr<!s32i> - %idx2 = cir.const #cir.int<1> : !s32i - %e1_1 = cir.get_element %a1[%idx2 : !s32i] {test.ptr = "e1_1"} - : !cir.ptr<!cir.array<!s32i x 4>> -> !cir.ptr<!s32i> - %e2_1 = cir.get_element %a2[%idx2 : !s32i] {test.ptr = "e2_1"} - : !cir.ptr<!cir.array<!s32i x 4>> -> !cir.ptr<!s32i> - cir.return -} - -// ----- - -// CHECK-LABEL: Testing : "base_class_addr_distinct_allocas" -// CHECK-DAG: d1#0 <-> d2#0: NoAlias -// CHECK-DAG: d1#0 <-> base1#0: MustAlias -// CHECK-DAG: d2#0 <-> base1#0: NoAlias -// CHECK-DAG: d1#0 <-> base2#0: NoAlias -// CHECK-DAG: d2#0 <-> base2#0: MustAlias -// CHECK-DAG: base1#0 <-> base2#0: NoAlias - -!u8i = !cir.int<u, 8> -!s32i = !cir.int<s, 32> -!rec_Base = !cir.struct<"Base" {!u8i}> -!rec_Derived = !cir.struct<"Derived" {!rec_Base, !s32i}> -cir.func @base_class_addr_distinct_allocas() { - %d1 = cir.alloca "d1" align(4) : !cir.ptr<!rec_Derived> {test.ptr = "d1"} - %d2 = cir.alloca "d2" align(4) : !cir.ptr<!rec_Derived> {test.ptr = "d2"} - %base1 = cir.base_class_addr %d1 : !cir.ptr<!rec_Derived> nonnull [0] - -> !cir.ptr<!rec_Base> {test.ptr = "base1"} - %base2 = cir.base_class_addr %d2 : !cir.ptr<!rec_Derived> nonnull [0] - -> !cir.ptr<!rec_Base> {test.ptr = "base2"} - cir.return -} - -// ----- - -// CHECK-LABEL: Testing : "base_class_addr_nonzero_offset" -// CHECK-DAG: d1#0 <-> d2#0: NoAlias -// CHECK-DAG: d1#0 <-> base1#0: MayAlias -// CHECK-DAG: d2#0 <-> base1#0: MayAlias -// CHECK-DAG: d1#0 <-> base2#0: MayAlias -// CHECK-DAG: d2#0 <-> base2#0: MayAlias -// CHECK-DAG: base1#0 <-> base2#0: MayAlias - -!u8i = !cir.int<u, 8> -!s32i = !cir.int<s, 32> -!rec_Base = !cir.struct<"Base" {!u8i}> -!rec_Derived = !cir.struct<"Derived" {!s32i, !rec_Base}> -cir.func @base_class_addr_nonzero_offset() { - %d1 = cir.alloca "d1" align(4) : !cir.ptr<!rec_Derived> {test.ptr = "d1"} - %d2 = cir.alloca "d2" align(4) : !cir.ptr<!rec_Derived> {test.ptr = "d2"} - %base1 = cir.base_class_addr %d1 : !cir.ptr<!rec_Derived> nonnull [4] - -> !cir.ptr<!rec_Base> {test.ptr = "base1"} - %base2 = cir.base_class_addr %d2 : !cir.ptr<!rec_Derived> nonnull [4] - -> !cir.ptr<!rec_Base> {test.ptr = "base2"} - cir.return -} - -// ----- - -// CHECK-LABEL: Testing : "derived_class_addr_zero_offset" -// CHECK-DAG: b1#0 <-> b2#0: NoAlias -// CHECK-DAG: b1#0 <-> d1#0: MustAlias -// CHECK-DAG: b2#0 <-> d1#0: NoAlias -// CHECK-DAG: b1#0 <-> d2#0: NoAlias -// CHECK-DAG: b2#0 <-> d2#0: MustAlias -// CHECK-DAG: d1#0 <-> d2#0: NoAlias - -!u8i = !cir.int<u, 8> -!s32i = !cir.int<s, 32> -!rec_Base = !cir.struct<"Base" {!u8i}> -!rec_Derived = !cir.struct<"Derived" {!rec_Base, !s32i}> -cir.func @derived_class_addr_zero_offset() { - %b1 = cir.alloca "d1" align(4) : !cir.ptr<!rec_Base> {test.ptr = "b1"} - %b2 = cir.alloca "d2" align(4) : !cir.ptr<!rec_Base> {test.ptr = "b2"} - %d1 = cir.derived_class_addr %b1 : !cir.ptr<!rec_Base> nonnull [0] - -> !cir.ptr<!rec_Derived> {test.ptr = "d1"} - %d2 = cir.derived_class_addr %b2 : !cir.ptr<!rec_Base> nonnull [0] - -> !cir.ptr<!rec_Derived> {test.ptr = "d2"} - cir.return -} - -// ----- - -// CHECK-LABEL: Testing : "derived_class_addr_nonzero_offset" -// CHECK-DAG: b1#0 <-> b2#0: NoAlias -// CHECK-DAG: b1#0 <-> d1#0: MayAlias -// CHECK-DAG: b2#0 <-> d1#0: MayAlias -// CHECK-DAG: b1#0 <-> d2#0: MayAlias -// CHECK-DAG: b2#0 <-> d2#0: MayAlias -// CHECK-DAG: d1#0 <-> d2#0: MayAlias - -!u8i = !cir.int<u, 8> -!s32i = !cir.int<s, 32> -!rec_Base = !cir.struct<"Base" {!u8i}> -!rec_Derived = !cir.struct<"Derived" {!s32i, !rec_Base}> -cir.func @derived_class_addr_nonzero_offset() { - %b1 = cir.alloca "d1" align(4) : !cir.ptr<!rec_Base> {test.ptr = "b1"} - %b2 = cir.alloca "d2" align(4) : !cir.ptr<!rec_Base> {test.ptr = "b2"} - %d1 = cir.derived_class_addr %b1 : !cir.ptr<!rec_Base> nonnull [4] - -> !cir.ptr<!rec_Derived> {test.ptr = "d1"} - %d2 = cir.derived_class_addr %b2 : !cir.ptr<!rec_Base> nonnull [4] - -> !cir.ptr<!rec_Derived> {test.ptr = "d2"} - cir.return -} - -// ----- - -// CHECK-LABEL: Testing : "complex_parts_distinct_allocas" -// CHECK-DAG: c1#0 <-> c2#0: NoAlias -// CHECK-DAG: c1#0 <-> real1#0: MustAlias -// CHECK-DAG: c2#0 <-> real1#0: NoAlias -// CHECK-DAG: c1#0 <-> imag1#0: MayAlias -// CHECK-DAG: c2#0 <-> imag1#0: MayAlias -// CHECK-DAG: real1#0 <-> imag1#0: MayAlias -// CHECK-DAG: c1#0 <-> real2#0: NoAlias -// CHECK-DAG: c2#0 <-> real2#0: MustAlias -// CHECK-DAG: real1#0 <-> real2#0: NoAlias -// CHECK-DAG: imag1#0 <-> real2#0: MayAlias -// CHECK-DAG: c1#0 <-> imag2#0: MayAlias -// CHECK-DAG: c2#0 <-> imag2#0: MayAlias -// CHECK-DAG: real1#0 <-> imag2#0: MayAlias -// CHECK-DAG: imag1#0 <-> imag2#0: MayAlias -// CHECK-DAG: real2#0 <-> imag... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/216278 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
