https://github.com/xlauko updated 
https://github.com/llvm/llvm-project/pull/195478

>From 111464c44186d6017247e2a0499ba9cc0d5c545d Mon Sep 17 00:00:00 2001
From: xlauko <[email protected]>
Date: Sat, 2 May 2026 21:29:53 +0200
Subject: [PATCH] [CIR] Extract CIR_ClassCastOp base class for BaseClassAddrOp
 and DerivedClassAddrOp

Both ops have identical structure (arguments, results, assembly format)
and differ only in mnemonic and description. Extract a shared TableGen
base class to eliminate the duplication. Also improve the assembly format
to print nonnull before the operand and place the type after the offset.
---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 55 ++++++++-----------
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 36 ++++++------
 clang/test/CIR/CodeGen/base-init-eh.cpp       |  4 +-
 clang/test/CIR/CodeGen/base-to-derived.cpp    |  6 +-
 clang/test/CIR/CodeGen/class.cpp              |  4 +-
 clang/test/CIR/CodeGen/ctor-null-init.cpp     |  6 +-
 clang/test/CIR/CodeGen/ctor-try-body.cpp      |  2 +-
 clang/test/CIR/CodeGen/ctor.cpp               |  6 +-
 clang/test/CIR/CodeGen/delegating-ctor.cpp    |  2 +-
 clang/test/CIR/CodeGen/derived-to-base.cpp    | 10 ++--
 clang/test/CIR/CodeGen/dtors.cpp              |  4 +-
 clang/test/CIR/CodeGen/inherited-ctors.cpp    |  8 +--
 clang/test/CIR/CodeGen/multi-vtable.cpp       |  6 +-
 .../test/CIR/CodeGen/paren-list-agg-init.cpp  |  4 +-
 clang/test/CIR/CodeGen/vbase.cpp              |  4 +-
 .../CIR/CodeGen/virtual-destructor-calls.cpp  |  2 +-
 clang/test/CIR/CodeGen/vtt.cpp                | 16 +++---
 clang/test/CIR/IR/vtt-addrpoint.cir           |  6 +-
 clang/test/CIR/Lowering/vtt-addrpoint.cir     |  6 +-
 .../CIR/Transforms/pure-ptr-arithmetic.cir    |  4 +-
 20 files changed, 90 insertions(+), 101 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 67ddaa73d9184..ff4bc590bd56a 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -5374,10 +5374,27 @@ def CIR_VecSplatOp : CIR_Op<"vec.splat", [
 }
 
 
//===----------------------------------------------------------------------===//
-// BaseClassAddrOp
+// BaseClassAddrOp & DerivedClassAddrOp
 
//===----------------------------------------------------------------------===//
 
-def CIR_BaseClassAddrOp : CIR_Op<"base_class_addr", [Pure]> {
+class CIR_ClassCastOp<string mnemonic> : CIR_Op<mnemonic, [Pure]> {
+  let arguments = (ins
+    CIR_PointerType:$src_addr,
+    IndexAttr:$offset, 
+    UnitAttr:$assume_not_null
+  );
+
+  let results = (outs Res<CIR_PointerType, "">:$result);
+
+  let assemblyFormat = [{
+      (`nonnull` $assume_not_null^)?
+      $src_addr ` ` `[` $offset `]` 
+      `:` qualified(type($src_addr)) `->` qualified(type($result)) 
+      attr-dict
+  }];
+}
+
+def CIR_BaseClassAddrOp : CIR_ClassCastOp<"base_class_addr"> {
   let summary = "Get the base class address for a class/struct";
   let description = [{
     The `cir.base_class_addr` operaration gets the address of a particular
@@ -5401,28 +5418,12 @@ def CIR_BaseClassAddrOp : CIR_Op<"base_class_addr", 
[Pure]> {
     ```
     will generate
     ```
-    %3 = cir.base_class_addr %1 : !cir.ptr<!rec_Derived> nonnull [0] -> 
!cir.ptr<!rec_Base>
+    %3 = cir.base_class_addr nonnull %1 [0] : !cir.ptr<!rec_Derived> -> 
!cir.ptr<!rec_Base>
     ```
   }];
-
-  let arguments = (ins
-    CIR_PointerType:$derived_addr,
-    IndexAttr:$offset, UnitAttr:$assume_not_null);
-
-  let results = (outs Res<CIR_PointerType, "">:$base_addr);
-
-  let assemblyFormat = [{
-      $derived_addr `:` qualified(type($derived_addr))
-      (`nonnull` $assume_not_null^)?
-      ` ` `[` $offset `]` `->` qualified(type($base_addr)) attr-dict
-  }];
 }
 
-//===----------------------------------------------------------------------===//
-// DerivedClassAddrOp
-//===----------------------------------------------------------------------===//
-
-def CIR_DerivedClassAddrOp : CIR_Op<"derived_class_addr", [Pure]> {
+def CIR_DerivedClassAddrOp : CIR_ClassCastOp<"derived_class_addr"> {
   let summary = "Get the derived class address for a class/struct";
   let description = [{
     The `cir.derived_class_addr` operaration gets the address of a particular
@@ -5451,21 +5452,9 @@ def CIR_DerivedClassAddrOp : 
CIR_Op<"derived_class_addr", [Pure]> {
     leads to
     ```
       %2 = cir.load %0 : !cir.ptr<!cir.ptr<!rec_A>>, !cir.ptr<!rec_A>
-      %3 = cir.base_class_addr %2 : !cir.ptr<!rec_B> [0] -> !cir.ptr<!rec_A>
+      %3 = cir.derived_class_addr %2 [0] : !cir.ptr<!rec_A> -> !cir.ptr<!rec_B>
     ```
   }];
-
-  let arguments = (ins
-    CIR_PointerType:$base_addr,
-    IndexAttr:$offset, UnitAttr:$assume_not_null);
-
-  let results = (outs Res<CIR_PointerType, "">:$derived_addr);
-
-  let assemblyFormat = [{
-      $base_addr `:` qualified(type($base_addr))
-      (`nonnull` $assume_not_null^)?
-      ` ` `[` $offset `]` `->` qualified(type($derived_addr)) attr-dict
-  }];
 }
 
 
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index c4e98e299dfc1..6b4b83501f58b 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1547,29 +1547,29 @@ mlir::LogicalResult 
CIRToLLVMBaseClassAddrOpLowering::matchAndRewrite(
     mlir::ConversionPatternRewriter &rewriter) const {
   const mlir::Type resultType =
       getTypeConverter()->convertType(baseClassOp.getType());
-  mlir::Value derivedAddr = adaptor.getDerivedAddr();
+  mlir::Value srcAddr = adaptor.getSrcAddr();
   llvm::SmallVector<mlir::LLVM::GEPArg, 1> offset = {
       adaptor.getOffset().getZExtValue()};
   mlir::Type byteType = mlir::IntegerType::get(resultType.getContext(), 8,
                                                mlir::IntegerType::Signless);
   if (adaptor.getOffset().getZExtValue() == 0) {
-    rewriter.replaceOpWithNewOp<mlir::LLVM::BitcastOp>(
-        baseClassOp, resultType, adaptor.getDerivedAddr());
+    rewriter.replaceOpWithNewOp<mlir::LLVM::BitcastOp>(baseClassOp, resultType,
+                                                       adaptor.getSrcAddr());
     return mlir::success();
   }
 
   if (baseClassOp.getAssumeNotNull()) {
-    rewriter.replaceOpWithNewOp<mlir::LLVM::GEPOp>(
-        baseClassOp, resultType, byteType, derivedAddr, offset);
+    rewriter.replaceOpWithNewOp<mlir::LLVM::GEPOp>(baseClassOp, resultType,
+                                                   byteType, srcAddr, offset);
   } else {
     auto loc = baseClassOp.getLoc();
     mlir::Value isNull = mlir::LLVM::ICmpOp::create(
-        rewriter, loc, mlir::LLVM::ICmpPredicate::eq, derivedAddr,
-        mlir::LLVM::ZeroOp::create(rewriter, loc, derivedAddr.getType()));
-    mlir::Value adjusted = mlir::LLVM::GEPOp::create(
-        rewriter, loc, resultType, byteType, derivedAddr, offset);
+        rewriter, loc, mlir::LLVM::ICmpPredicate::eq, srcAddr,
+        mlir::LLVM::ZeroOp::create(rewriter, loc, srcAddr.getType()));
+    mlir::Value adjusted = mlir::LLVM::GEPOp::create(rewriter, loc, resultType,
+                                                     byteType, srcAddr, 
offset);
     rewriter.replaceOpWithNewOp<mlir::LLVM::SelectOp>(baseClassOp, isNull,
-                                                      derivedAddr, adjusted);
+                                                      srcAddr, adjusted);
   }
   return mlir::success();
 }
@@ -1579,13 +1579,13 @@ mlir::LogicalResult 
CIRToLLVMDerivedClassAddrOpLowering::matchAndRewrite(
     mlir::ConversionPatternRewriter &rewriter) const {
   const mlir::Type resultType =
       getTypeConverter()->convertType(derivedClassOp.getType());
-  mlir::Value baseAddr = adaptor.getBaseAddr();
+  mlir::Value srcAddr = adaptor.getSrcAddr();
   // The offset is set in the operation as an unsigned value, but it must be
   // applied as a negative offset.
   int64_t offsetVal = -(adaptor.getOffset().getZExtValue());
   if (offsetVal == 0) {
-    // If the offset is zero, we can just return the base address,
-    rewriter.replaceOp(derivedClassOp, baseAddr);
+    // If the offset is zero, we can just return the source address.
+    rewriter.replaceOp(derivedClassOp, srcAddr);
     return mlir::success();
   }
   llvm::SmallVector<mlir::LLVM::GEPArg, 1> offset = {offsetVal};
@@ -1593,18 +1593,18 @@ mlir::LogicalResult 
CIRToLLVMDerivedClassAddrOpLowering::matchAndRewrite(
                                                mlir::IntegerType::Signless);
   if (derivedClassOp.getAssumeNotNull()) {
     rewriter.replaceOpWithNewOp<mlir::LLVM::GEPOp>(
-        derivedClassOp, resultType, byteType, baseAddr, offset,
+        derivedClassOp, resultType, byteType, srcAddr, offset,
         mlir::LLVM::GEPNoWrapFlags::inbounds);
   } else {
     mlir::Location loc = derivedClassOp.getLoc();
     mlir::Value isNull = mlir::LLVM::ICmpOp::create(
-        rewriter, loc, mlir::LLVM::ICmpPredicate::eq, baseAddr,
-        mlir::LLVM::ZeroOp::create(rewriter, loc, baseAddr.getType()));
+        rewriter, loc, mlir::LLVM::ICmpPredicate::eq, srcAddr,
+        mlir::LLVM::ZeroOp::create(rewriter, loc, srcAddr.getType()));
     mlir::Value adjusted =
-        mlir::LLVM::GEPOp::create(rewriter, loc, resultType, byteType, 
baseAddr,
+        mlir::LLVM::GEPOp::create(rewriter, loc, resultType, byteType, srcAddr,
                                   offset, 
mlir::LLVM::GEPNoWrapFlags::inbounds);
     rewriter.replaceOpWithNewOp<mlir::LLVM::SelectOp>(derivedClassOp, isNull,
-                                                      baseAddr, adjusted);
+                                                      srcAddr, adjusted);
   }
   return mlir::success();
 }
diff --git a/clang/test/CIR/CodeGen/base-init-eh.cpp 
b/clang/test/CIR/CodeGen/base-init-eh.cpp
index 063a4d1dca977..7c5609492c35d 100644
--- a/clang/test/CIR/CodeGen/base-init-eh.cpp
+++ b/clang/test/CIR/CodeGen/base-init-eh.cpp
@@ -24,7 +24,7 @@ void test_base_initializer() {
 
 // CIR: cir.func {{.*}} @_ZN7DerivedC2Ev
 // CIR:   %[[THIS:.*]] = cir.load %{{.*}}
-// CIR:   %[[BASE_ADDR:.*]] = cir.base_class_addr %[[THIS]] : 
!cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR:   %[[BASE_ADDR:.*]] = cir.base_class_addr nonnull %[[THIS]] [0] : 
!cir.ptr<!rec_Derived> -> !cir.ptr<!rec_Base>
 // CIR:   %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i
 // CIR:   cir.call @_ZN4BaseC2Ei(%[[BASE_ADDR]], %[[ZERO]])
 // CIR:   cir.cleanup.scope {
@@ -65,7 +65,7 @@ void test_virt_base_initializer() {
         
 // CIR: cir.func {{.*}} @_ZN11VirtDerivedC1Ev
 // CIR:   %[[THIS:.*]] = cir.load %{{.*}}
-// CIR:   %[[BASE_ADDR:.*]] = cir.base_class_addr %[[THIS]] : 
!cir.ptr<!rec_VirtDerived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR:   %[[BASE_ADDR:.*]] = cir.base_class_addr nonnull %[[THIS]] [0] : 
!cir.ptr<!rec_VirtDerived> -> !cir.ptr<!rec_Base>
 // CIR:   %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i
 // CIR:   cir.call @_ZN4BaseC2Ei(%[[BASE_ADDR]], %[[ZERO]])
 // CIR:   cir.cleanup.scope {
diff --git a/clang/test/CIR/CodeGen/base-to-derived.cpp 
b/clang/test/CIR/CodeGen/base-to-derived.cpp
index 147b0b897e674..92e51a8d36bba 100644
--- a/clang/test/CIR/CodeGen/base-to-derived.cpp
+++ b/clang/test/CIR/CodeGen/base-to-derived.cpp
@@ -27,7 +27,7 @@ X *castAtoX(A *a) {
 // CIR:   %[[A_ADDR:.*]] = cir.alloca !cir.ptr<!rec_A>, 
!cir.ptr<!cir.ptr<!rec_A>>, ["a", init]
 // CIR:   cir.store %[[ARG0]], %[[A_ADDR]] : !cir.ptr<!rec_A>, 
!cir.ptr<!cir.ptr<!rec_A>>
 // CIR:   %[[A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.ptr<!rec_A>>, 
!cir.ptr<!rec_A>
-// CIR:   %[[X:.*]] = cir.derived_class_addr %[[A]] : !cir.ptr<!rec_A> [0] -> 
!cir.ptr<!rec_X>
+// CIR:   %[[X:.*]] = cir.derived_class_addr %[[A]] [0] : !cir.ptr<!rec_A> -> 
!cir.ptr<!rec_X>
 
 // Note: Because the offset is 0, a null check is not needed.
 
@@ -49,7 +49,7 @@ X *castBtoX(B *b) {
 // CIR:   %[[B_ADDR:.*]] = cir.alloca !cir.ptr<!rec_B>, 
!cir.ptr<!cir.ptr<!rec_B>>, ["b", init]
 // CIR:   cir.store %[[ARG0]], %[[B_ADDR]] : !cir.ptr<!rec_B>, 
!cir.ptr<!cir.ptr<!rec_B>>
 // CIR:   %[[B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!cir.ptr<!rec_B>>, 
!cir.ptr<!rec_B>
-// CIR:   %[[X:.*]] = cir.derived_class_addr %[[B]] : !cir.ptr<!rec_B> [4] -> 
!cir.ptr<!rec_X>
+// CIR:   %[[X:.*]] = cir.derived_class_addr %[[B]] [4] : !cir.ptr<!rec_B> -> 
!cir.ptr<!rec_X>
 
 // LLVM: define {{.*}} ptr @_Z8castBtoXP1B(ptr {{.*}} %[[ARG0:.*]])
 // LLVM:   %[[B_ADDR:.*]] = alloca ptr, i64 1, align 8
@@ -82,7 +82,7 @@ X &castBReftoXRef(B &b) {
 // CIR:   %[[B_ADDR:.*]] = cir.alloca !cir.ptr<!rec_B>, 
!cir.ptr<!cir.ptr<!rec_B>>, ["b", init, const]
 // CIR:   cir.store %[[ARG0]], %[[B_ADDR]] : !cir.ptr<!rec_B>, 
!cir.ptr<!cir.ptr<!rec_B>>
 // CIR:   %[[B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!cir.ptr<!rec_B>>, 
!cir.ptr<!rec_B>
-// CIR:   %[[X:.*]] = cir.derived_class_addr %[[B]] : !cir.ptr<!rec_B> nonnull 
[4] -> !cir.ptr<!rec_X>
+// CIR:   %[[X:.*]] = cir.derived_class_addr nonnull %[[B]] [4] : 
!cir.ptr<!rec_B> -> !cir.ptr<!rec_X>
 
 // LLVM: define {{.*}} ptr @_Z14castBReftoXRefR1B(ptr {{.*}} %[[ARG0:.*]])
 // LLVM:   %[[B_ADDR:.*]] = alloca ptr
diff --git a/clang/test/CIR/CodeGen/class.cpp b/clang/test/CIR/CodeGen/class.cpp
index 243eb746ade52..ef51cd36b7176 100644
--- a/clang/test/CIR/CodeGen/class.cpp
+++ b/clang/test/CIR/CodeGen/class.cpp
@@ -71,7 +71,7 @@ int use_base() {
 
 // CIR: cir.func{{.*}} @_Z8use_basev
 // CIR:   %[[D_ADDR:.*]] = cir.alloca !rec_Derived, !cir.ptr<!rec_Derived>, 
["d"]
-// CIR:   %[[BASE_ADDR:.*]] cir.base_class_addr %[[D_ADDR]] : 
!cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR:   %[[BASE_ADDR:.*]] cir.base_class_addr nonnull %[[D_ADDR]] [0] : 
!cir.ptr<!rec_Derived> -> !cir.ptr<!rec_Base>
 // CIR:   %[[D_A_ADDR:.*]] = cir.get_member %2[0] {name = "a"} : 
!cir.ptr<!rec_Base> -> !cir.ptr<!s32i>
 // CIR:   %[[D_A:.*]] = cir.load align(4) %3 : !cir.ptr<!s32i>, !s32i
 
@@ -91,7 +91,7 @@ int use_base_via_pointer(Derived *d) {
 // CIR:   %[[D_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Derived>, 
!cir.ptr<!cir.ptr<!rec_Derived>>, ["d", init]
 // CIR:   cir.store %[[ARG0]], %[[D_ADDR]]
 // CIR:   %[[D:.*]] = cir.load align(8) %[[D_ADDR]]
-// CIR:   %[[BASE_ADDR:.*]] = cir.base_class_addr %[[D]] : 
!cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR:   %[[BASE_ADDR:.*]] = cir.base_class_addr nonnull %[[D]] [0] : 
!cir.ptr<!rec_Derived> -> !cir.ptr<!rec_Base>
 // CIR:   %[[D_A_ADDR:.*]] = cir.get_member %[[BASE_ADDR]][0] {name = "a"}
 // CIR:   %[[D_A:.*]] = cir.load align(4) %[[D_A_ADDR]]
 
diff --git a/clang/test/CIR/CodeGen/ctor-null-init.cpp 
b/clang/test/CIR/CodeGen/ctor-null-init.cpp
index 6f31a46305ae8..0aacc99b9364e 100644
--- a/clang/test/CIR/CodeGen/ctor-null-init.cpp
+++ b/clang/test/CIR/CodeGen/ctor-null-init.cpp
@@ -19,7 +19,7 @@ void test_empty_base_null_init() {
 
 // CIR: cir.func {{.*}} @_Z25test_empty_base_null_initv()
 // CIR-NEXT:   %[[B_ADDR:.*]] = cir.alloca !rec_B, !cir.ptr<!rec_B>, 
["agg.tmp.ensured"]
-// CIR-NEXT:   %[[A_ADDR:.*]] = cir.base_class_addr %[[B_ADDR]] : 
!cir.ptr<!rec_B> nonnull [0] -> !cir.ptr<!rec_A>
+// CIR-NEXT:   %[[A_ADDR:.*]] = cir.base_class_addr nonnull %[[B_ADDR]] [0] : 
!cir.ptr<!rec_B> -> !cir.ptr<!rec_A>
 
 // LLVM: define{{.*}} @_Z25test_empty_base_null_initv()
 // LLVM-NEXT:   %[[B:.*]] = alloca %struct.B
@@ -46,7 +46,7 @@ void test_non_empty_base_null_init() {
 
 // CIR: cir.func {{.*}} @_Z29test_non_empty_base_null_initv()
 // CIR:   %[[TMP:.*]] = cir.alloca !rec_D, !cir.ptr<!rec_D>, 
["agg.tmp.ensured"]
-// CIR:   %[[BASE:.*]] = cir.base_class_addr %[[TMP]] : !cir.ptr<!rec_D> 
nonnull [0] -> !cir.ptr<!rec_C>
+// CIR:   %[[BASE:.*]] = cir.base_class_addr nonnull %[[TMP]] [0] : 
!cir.ptr<!rec_D> -> !cir.ptr<!rec_C>
 // CIR:   %[[ZERO:.*]] = cir.const #cir.const_record<{#cir.int<0> : !s32i}> : 
!rec_C
 // CIR:   cir.store{{.*}} %[[ZERO]], %[[BASE]]
 
@@ -77,7 +77,7 @@ void test_base_chain_null_init() {
 
 // CIR: cir.func {{.*}} @_Z25test_base_chain_null_initv()
 // CIR:   %[[TMP:.*]] = cir.alloca !rec_G, !cir.ptr<!rec_G>, 
["agg.tmp.ensured"]
-// CIR:   %[[BASE:.*]] = cir.base_class_addr %[[TMP]] : !cir.ptr<!rec_G> 
nonnull [0] -> !cir.ptr<!rec_F>
+// CIR:   %[[BASE:.*]] = cir.base_class_addr nonnull %[[TMP]] [0] : 
!cir.ptr<!rec_G> -> !cir.ptr<!rec_F>
 // CIR:   %[[ZERO:.*]] = cir.const #cir.const_record<{#cir.zero : !rec_E}> : 
!rec_F
 // CIR:   cir.store{{.*}} %[[ZERO]], %[[BASE]]
 
diff --git a/clang/test/CIR/CodeGen/ctor-try-body.cpp 
b/clang/test/CIR/CodeGen/ctor-try-body.cpp
index 567fe9d7c77ac..d843ad551db6d 100644
--- a/clang/test/CIR/CodeGen/ctor-try-body.cpp
+++ b/clang/test/CIR/CodeGen/ctor-try-body.cpp
@@ -38,7 +38,7 @@ struct HasThings : Base {
 // CIR-NEXT:  %[[THIS_LOAD:.*]] = cir.load %[[THIS_ALLOC]] : 
!cir.ptr<!cir.ptr<!rec_HasThings>>, !cir.ptr<!rec_HasThings>
 // CIR-NEXT:  cir.scope {
 // CIR-NEXT:    cir.try {
-// CIR-NEXT:      %[[BASE_ADDR:.*]] = cir.base_class_addr %[[THIS_LOAD]] : 
!cir.ptr<!rec_HasThings> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR-NEXT:      %[[BASE_ADDR:.*]] = cir.base_class_addr nonnull 
%[[THIS_LOAD]] [0] : !cir.ptr<!rec_HasThings> -> !cir.ptr<!rec_Base>
 // CIR-NEXT:      cir.call @_ZN4BaseC2Ev(%[[BASE_ADDR]]) : 
(!cir.ptr<!rec_Base>{{.*}}) -> ()
 // CIR-NEXT:      %[[FROMCTOR_ADDR:.*]] = cir.cast bitcast %[[THIS_LOAD]] : 
!cir.ptr<!rec_HasThings> -> !cir.ptr<!rec_FromCtor>
 // CIR-NEXT:      %[[C_LOAD:.*]] = cir.load %[[C_ALLOC]] : 
!cir.ptr<!cir.ptr<!rec_Ctor>>, !cir.ptr<!rec_Ctor>
diff --git a/clang/test/CIR/CodeGen/ctor.cpp b/clang/test/CIR/CodeGen/ctor.cpp
index 3df31b71b34c0..19fff5f5eaecc 100644
--- a/clang/test/CIR/CodeGen/ctor.cpp
+++ b/clang/test/CIR/CodeGen/ctor.cpp
@@ -250,7 +250,7 @@ void test_derived() {
 // CHECK-NEXT:   cir.store %arg0, %[[THIS_ADDR]]
 // CHECK-NEXT:   cir.store %arg1, %[[VAL_ADDR]]
 // CHECK-NEXT:   %[[THIS:.*]] = cir.load{{.*}} %[[THIS_ADDR]]
-// CHECK-NEXT:   %[[BASE:.*]] = cir.base_class_addr %[[THIS]] : 
!cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CHECK-NEXT:   %[[BASE:.*]] = cir.base_class_addr nonnull %[[THIS]] [0] : 
!cir.ptr<!rec_Derived> -> !cir.ptr<!rec_Base>
 // CHECK-NEXT:   %[[VAL:.*]] = cir.load{{.*}} %[[VAL_ADDR]]
 // CHECK-NEXT:   cir.call @_ZN4BaseC2Ei(%[[BASE]], %[[VAL]])
 // CHECK-NEXT:   cir.return
@@ -309,10 +309,10 @@ void test_derived2() {
 // CHECK-NEXT:   cir.store %arg2, %[[VAL2_ADDR]]
 // CHECK-NEXT:   cir.store %arg3, %[[VAL3_ADDR]]
 // CHECK-NEXT:   %[[THIS:.*]] = cir.load{{.*}} %[[THIS_ADDR]]
-// CHECK-NEXT:   %[[BASE:.*]] = cir.base_class_addr %[[THIS]] : 
!cir.ptr<!rec_Derived2> nonnull [0] -> !cir.ptr<!rec_Base>
+// CHECK-NEXT:   %[[BASE:.*]] = cir.base_class_addr nonnull %[[THIS]] [0] : 
!cir.ptr<!rec_Derived2> -> !cir.ptr<!rec_Base>
 // CHECK-NEXT:   %[[VAL1:.*]] = cir.load{{.*}} %[[VAL1_ADDR]]
 // CHECK-NEXT:   cir.call @_ZN4BaseC2Ei(%[[BASE]], %[[VAL1]])
-// CHECK-NEXT:   %[[BASE2:.*]] = cir.base_class_addr %[[THIS]] : 
!cir.ptr<!rec_Derived2> nonnull [4] -> !cir.ptr<!rec_Base2>
+// CHECK-NEXT:   %[[BASE2:.*]] = cir.base_class_addr nonnull %[[THIS]] [4] : 
!cir.ptr<!rec_Derived2> -> !cir.ptr<!rec_Base2>
 // CHECK-NEXT:   %[[VAL2:.*]] = cir.load{{.*}} %[[VAL2_ADDR]]
 // CHECK-NEXT:   cir.call @_ZN5Base2C2Ei(%[[BASE2]], %[[VAL2]])
 // CHECK-NEXT:   %[[C_ADDR:.*]] = cir.get_member %[[THIS]][2] {name = "c"}
diff --git a/clang/test/CIR/CodeGen/delegating-ctor.cpp 
b/clang/test/CIR/CodeGen/delegating-ctor.cpp
index 7c2f5be118c35..ab3d02dde2a68 100644
--- a/clang/test/CIR/CodeGen/delegating-ctor.cpp
+++ b/clang/test/CIR/CodeGen/delegating-ctor.cpp
@@ -257,7 +257,7 @@ Derived::Derived(const void *inVoid) { squawk(); }
 // CIR:   cir.store %[[THIS_ARG]], %[[THIS_ADDR]]
 // CIR:   cir.store %[[INVOID_ARG]], %[[INVOID_ADDR]]
 // CIR:   %[[THIS:.*]] = cir.load %[[THIS_ADDR]]
-// CIR:   %[[BASE:.*]] = cir.base_class_addr %[[THIS]] : 
!cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR:   %[[BASE:.*]] = cir.base_class_addr nonnull %[[THIS]] [0] : 
!cir.ptr<!rec_Derived> -> !cir.ptr<!rec_Base>
 // CIR:   cir.call @_ZN4BaseC2Ev(%[[BASE]])
 // CIR:   %[[VPTR_GLOBAL:.*]] = cir.vtable.address_point(@_ZTV7Derived, 
address_point = <index = 0, offset = 4>) : !cir.vptr
 // CIR:   %[[VPTR_ADDR:.*]] = cir.vtable.get_vptr %[[THIS]] : 
!cir.ptr<!rec_Derived> -> !cir.ptr<!cir.vptr>
diff --git a/clang/test/CIR/CodeGen/derived-to-base.cpp 
b/clang/test/CIR/CodeGen/derived-to-base.cpp
index a5b9cb7313e00..7deb00ab761e7 100644
--- a/clang/test/CIR/CodeGen/derived-to-base.cpp
+++ b/clang/test/CIR/CodeGen/derived-to-base.cpp
@@ -28,7 +28,7 @@ void f() {
 // CIR: cir.func {{.*}} @_Z1fv()
 // CIR:   %[[D:.*]] = cir.alloca !rec_Derived, !cir.ptr<!rec_Derived>, ["d", 
init]
 // CIR:   cir.call @_ZN7DerivedC1Ev(%[[D]]) : (!cir.ptr<!rec_Derived> {{.*}}) 
-> ()
-// CIR:   %[[D_BASE:.*]] = cir.base_class_addr %[[D]] : !cir.ptr<!rec_Derived> 
nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR:   %[[D_BASE:.*]] = cir.base_class_addr nonnull %[[D]] [0] : 
!cir.ptr<!rec_Derived> -> !cir.ptr<!rec_Base>
 // CIR:   cir.call @_ZN4Base1fEv(%[[D_BASE]]) : (!cir.ptr<!rec_Base> {{.*}}) 
-> ()
 
 // LLVM: define {{.*}}void @_Z1fv()
@@ -51,7 +51,7 @@ void callBaseUsingDerived(Derived *derived) {
 // CIR:   %[[DERIVED_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Derived>, 
!cir.ptr<!cir.ptr<!rec_Derived>>, ["derived", init]
 // CIR:   cir.store %[[DERIVED_ARG]], %[[DERIVED_ADDR]]
 // CIR:   %[[DERIVED:.*]] = cir.load{{.*}} %[[DERIVED_ADDR]]
-// CIR:   %[[DERIVED_BASE:.*]] = cir.base_class_addr %[[DERIVED]] : 
!cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR:   %[[DERIVED_BASE:.*]] = cir.base_class_addr nonnull %[[DERIVED]] [0] 
: !cir.ptr<!rec_Derived> -> !cir.ptr<!rec_Base>
 // CIR:   cir.call @_Z7useBaseP4Base(%[[DERIVED_BASE]]) : (!cir.ptr<!rec_Base> 
{{.*}}) -> ()
 
 // LLVM: define {{.*}} void @_Z20callBaseUsingDerivedP7Derived(ptr {{.*}} 
%[[DERIVED_ARG:.*]])
@@ -75,7 +75,7 @@ Base *returnBaseFromDerived(Derived* derived) {
 // CIR:   %[[BASE_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Base>, 
!cir.ptr<!cir.ptr<!rec_Base>>, ["__retval"]
 // CIR:   cir.store %[[DERIVED_ARG]], %[[DERIVED_ADDR]]
 // CIR:   %[[DERIVED:.*]] = cir.load{{.*}} %[[DERIVED_ADDR]]
-// CIR:   %[[DERIVED_BASE:.*]] = cir.base_class_addr %[[DERIVED]] : 
!cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR:   %[[DERIVED_BASE:.*]] = cir.base_class_addr nonnull %[[DERIVED]] [0] 
: !cir.ptr<!rec_Derived> -> !cir.ptr<!rec_Base>
 // CIR:   cir.store %[[DERIVED_BASE]], %[[BASE_ADDR]]
 // CIR:   %[[BASE:.*]] = cir.load{{.*}} %[[BASE_ADDR]]
 // CIR:   cir.return %[[BASE]] : !cir.ptr<!rec_Base>
@@ -99,7 +99,7 @@ void test_volatile_store() {
 // CIR: cir.func {{.*}} @_Z19test_volatile_storev()
 // CIR:   %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i
 // CIR:   %[[DERIVED_OBJ:.*]] = cir.get_global @derivedObj : 
!cir.ptr<!rec_Derived>
-// CIR:   %[[DERIVED_OBJ_BASE:.*]] = cir.base_class_addr %[[DERIVED_OBJ]] : 
!cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR:   %[[DERIVED_OBJ_BASE:.*]] = cir.base_class_addr nonnull 
%[[DERIVED_OBJ]] [0] : !cir.ptr<!rec_Derived> -> !cir.ptr<!rec_Base>
 // CIR:   %[[DERIVED_OBJ_A:.*]] = cir.get_member %[[DERIVED_OBJ_BASE]][0] 
{name = "a"} : !cir.ptr<!rec_Base> -> !cir.ptr<!s32i>
 // CIR:   cir.store volatile {{.*}} %[[ZERO]], %[[DERIVED_OBJ_A]] : !s32i, 
!cir.ptr<!s32i>
 
@@ -115,7 +115,7 @@ void test_volatile_load() {
 
 // CIR: cir.func {{.*}} @_Z18test_volatile_loadv()
 // CIR:   %[[DERIVED_OBJ:.*]] = cir.get_global @derivedObj : 
!cir.ptr<!rec_Derived>
-// CIR:   %[[DERIVED_OBJ_BASE:.*]] = cir.base_class_addr %[[DERIVED_OBJ]] : 
!cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR:   %[[DERIVED_OBJ_BASE:.*]] = cir.base_class_addr nonnull 
%[[DERIVED_OBJ]] [0] : !cir.ptr<!rec_Derived> -> !cir.ptr<!rec_Base>
 // CIR:   %[[DERIVED_OBJ_A:.*]] = cir.get_member %[[DERIVED_OBJ_BASE]][0] 
{name = "a"} : !cir.ptr<!rec_Base> -> !cir.ptr<!s32i>
 // CIR:   %[[VAL:.*]] = cir.load volatile {{.*}} %[[DERIVED_OBJ_A]] : 
!cir.ptr<!s32i>, !s32i
 
diff --git a/clang/test/CIR/CodeGen/dtors.cpp b/clang/test/CIR/CodeGen/dtors.cpp
index 4c1a98e1ce9da..88b553f6374f0 100644
--- a/clang/test/CIR/CodeGen/dtors.cpp
+++ b/clang/test/CIR/CodeGen/dtors.cpp
@@ -293,7 +293,7 @@ struct F : public E {
 };
 
 // CIR: cir.func {{.*}} @_ZN1FD2Ev
-// CIR:   %[[BASE_E:.*]] = cir.base_class_addr %{{.*}} : !cir.ptr<!rec_F> 
nonnull [0] -> !cir.ptr<!rec_E>
+// CIR:   %[[BASE_E:.*]] = cir.base_class_addr nonnull %{{.*}} [0] : 
!cir.ptr<!rec_F> -> !cir.ptr<!rec_E>
 // CIR:   cir.call @_ZN1ED2Ev(%[[BASE_E]]) nothrow : (!cir.ptr<!rec_E> {{.*}}) 
-> ()
 
 // Because E is at offset 0 in F, there is no getelementptr needed.
@@ -472,7 +472,7 @@ void test_base_dtor_call_virtual_base() {
 // CIR:   %[[THIS:.*]] = cir.load %{{.*}}
 // CIR:   %[[VTT:.*]] = cir.vtt.address_point @_ZTT7Derived, offset = 0 -> 
!cir.ptr<!cir.ptr<!void>>
 // CIR:   cir.call @_ZN7DerivedD2Ev(%[[THIS]], %[[VTT]])
-// CIR:   %[[VIRTUAL_BASE:.*]] = cir.base_class_addr %[[THIS]] : 
!cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_VirtualBase>
+// CIR:   %[[VIRTUAL_BASE:.*]] = cir.base_class_addr nonnull %[[THIS]] [0] : 
!cir.ptr<!rec_Derived> -> !cir.ptr<!rec_VirtualBase>
 // CIR:   cir.call @_ZN11VirtualBaseD2Ev(%[[VIRTUAL_BASE]])
 
 // LLVM: define {{.*}} void @_ZN7DerivedD1Ev
diff --git a/clang/test/CIR/CodeGen/inherited-ctors.cpp 
b/clang/test/CIR/CodeGen/inherited-ctors.cpp
index 8684b2142b68f..0fb96873147e2 100644
--- a/clang/test/CIR/CodeGen/inherited-ctors.cpp
+++ b/clang/test/CIR/CodeGen/inherited-ctors.cpp
@@ -46,7 +46,7 @@ void fallsthrough() {
 // CIR: %[[THIS_ALLOCA:.*]] = cir.alloca !cir.ptr<!rec_Derived>, 
!cir.ptr<!cir.ptr<!rec_Derived>>, ["this", init]
 // CIR: %[[INT_ALLOCA:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["", init]
 // CIR: %[[THIS_LOAD:.*]] = cir.load %[[THIS_ALLOCA]] : 
!cir.ptr<!cir.ptr<!rec_Derived>>, !cir.ptr<!rec_Derived>
-// CIR: %[[BASE_ADDR:.*]] = cir.base_class_addr %[[THIS_LOAD]] : 
!cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR: %[[BASE_ADDR:.*]] = cir.base_class_addr nonnull %[[THIS_LOAD]] [0] : 
!cir.ptr<!rec_Derived> -> !cir.ptr<!rec_Base>
 // CIR: %[[INT:.*]] = cir.load align(4) %[[INT_ALLOCA]] : !cir.ptr<!s32i>, 
!s32i
 // CIR: cir.call @_ZN4BaseC2Ei(%[[BASE_ADDR]], %[[INT]]) : 
(!cir.ptr<!rec_Base>{{.*}}, !s32i{{.*}}) -> () 
 //
@@ -72,7 +72,7 @@ void fallsthrough() {
 // CIR: %[[TWO:.*]] = cir.const #cir.int<2> : !s32i
 // CIR: %[[THREE:.*]] = cir.const #cir.fp<3.0{{.*}}> : !cir.double
 // CIR: %[[LOAD_DERIVED:.*]] = cir.load %[[TMP_ALLOCA]] : 
!cir.ptr<!cir.ptr<!rec_Derived>>, !cir.ptr<!rec_Derived>
-// CIR: %[[BASE_ADDR:.*]] = cir.base_class_addr %[[LOAD_DERIVED]] : 
!cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR: %[[BASE_ADDR:.*]] = cir.base_class_addr nonnull %[[LOAD_DERIVED]] [0] 
: !cir.ptr<!rec_Derived> -> !cir.ptr<!rec_Base>
 // CIR: cir.call @_ZN4BaseC2Efz(%[[BASE_ADDR]], %[[FP_1_1]], %[[TWO]], 
%[[THREE]]) : (!cir.ptr<!rec_Base>{{.*}}, !cir.float{{.*}}, !s32i{{.*}}, 
!cir.double{{.*}}) -> ()
 //
 // LLVM-LABEL: define dso_local void @_Z26cannotEmitDelegateCallArgsv()
@@ -104,7 +104,7 @@ void fallsthrough() {
 // CIR: %[[THIS_ALLOCA:.*]] = cir.alloca !cir.ptr<!rec_VirtualDelegatingCtor>, 
!cir.ptr<!cir.ptr<!rec_VirtualDelegatingCtor>>, ["this", init] {alignment = 8 : 
i64}
 // CIR: %[[X_ALLOCA:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init] 
{alignment = 4 : i64}
 // CIR: %[[THIS_LOAD:.*]] = cir.load %[[THIS_ALLOCA]] : 
!cir.ptr<!cir.ptr<!rec_VirtualDelegatingCtor>>, 
!cir.ptr<!rec_VirtualDelegatingCtor>
-// CIR: %[[BASE_ADDR:.*]] = cir.base_class_addr %[[THIS_LOAD]] : 
!cir.ptr<!rec_VirtualDelegatingCtor> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR: %[[BASE_ADDR:.*]] = cir.base_class_addr nonnull %[[THIS_LOAD]] [0] : 
!cir.ptr<!rec_VirtualDelegatingCtor> -> !cir.ptr<!rec_Base>
 // CIR: %[[X_LOAD:.*]] = cir.load align(4) %[[X_ALLOCA]] : !cir.ptr<!s32i>, 
!s32i
 // CIR: cir.call @_ZN4BaseC2Ei(%[[BASE_ADDR]], %[[X_LOAD]]) : 
(!cir.ptr<!rec_Base> {{.*}}, !s32i {{{.*}}) -> ()
 //
@@ -120,7 +120,7 @@ void fallsthrough() {
 // in the body, and not being included in the declaration/definition of this
 // function. CIR cannot reproduce this, as we have a verifier that checks that
 // the arg counts match.
-// CIR: %[[BASE_ADDR:.*]] = cir.base_class_addr %[[THIS_LOAD]] : 
!cir.ptr<!rec_VirtualDelegatingCtor> nonnull [0] -> !cir.ptr<!rec_VirtDerived>
+// CIR: %[[BASE_ADDR:.*]] = cir.base_class_addr nonnull %[[THIS_LOAD]] [0] : 
!cir.ptr<!rec_VirtualDelegatingCtor> -> !cir.ptr<!rec_VirtDerived>
 // CIR: %[[ADDR_PT:.*]] = cir.vtt.address_point @_ZTT21VirtualDelegatingCtor, 
offset = 1 -> !cir.ptr<!cir.ptr<!void>>
 // CIR: cir.call @_ZN11VirtDerivedCI24BaseEi(%[[BASE_ADDR]], %[[ADDR_PT]]) : 
(!cir.ptr<!rec_VirtDerived>{{.*}}, !cir.ptr<!cir.ptr<!void>>{{.*}}) -> ()
 // CIR: %[[ADDR_PT:.*]] = 
cir.vtable.address_point(@_ZTV21VirtualDelegatingCtor, address_point = <index = 
0, offset = 3>) : !cir.vptr
diff --git a/clang/test/CIR/CodeGen/multi-vtable.cpp 
b/clang/test/CIR/CodeGen/multi-vtable.cpp
index 8f5b8b38eb3a6..108c0f5019f80 100644
--- a/clang/test/CIR/CodeGen/multi-vtable.cpp
+++ b/clang/test/CIR/CodeGen/multi-vtable.cpp
@@ -143,15 +143,15 @@ Child::Child() {}
 // CIR:   %[[THIS_ADDR:.*]] = cir.alloca {{.*}} ["this", init]
 // CIR:   cir.store %[[THIS_ARG]], %[[THIS_ADDR]]
 // CIR:   %[[THIS:.*]] = cir.load %[[THIS_ADDR]]
-// CIR:   %[[MOTHER_BASE:.*]] = cir.base_class_addr %[[THIS]] : 
!cir.ptr<!rec_Child> nonnull [0] -> !cir.ptr<!rec_Mother>
+// CIR:   %[[MOTHER_BASE:.*]] = cir.base_class_addr nonnull %[[THIS]] [0] : 
!cir.ptr<!rec_Child> -> !cir.ptr<!rec_Mother>
 // CIR:   cir.call @_ZN6MotherC2Ev(%[[MOTHER_BASE]]) nothrow : 
(!cir.ptr<!rec_Mother> {{.*}}) -> ()
-// CIR:   %[[FATHER_BASE:.*]] = cir.base_class_addr %[[THIS]] : 
!cir.ptr<!rec_Child> nonnull [8] -> !cir.ptr<!rec_Father>
+// CIR:   %[[FATHER_BASE:.*]] = cir.base_class_addr nonnull %[[THIS]] [8] : 
!cir.ptr<!rec_Child> -> !cir.ptr<!rec_Father>
 // CIR:   cir.call @_ZN6FatherC2Ev(%[[FATHER_BASE]]) nothrow : 
(!cir.ptr<!rec_Father> {{.*}}) -> ()
 // CIR:   %[[CHILD_VPTR:.*]] = cir.vtable.address_point(@_ZTV5Child, 
address_point = <index = 0, offset = 2>) : !cir.vptr
 // CIR:   %[[CHILD_VPTR_ADDR:.*]] = cir.vtable.get_vptr %[[THIS]] : 
!cir.ptr<!rec_Child> -> !cir.ptr<!cir.vptr>
 // CIR:   cir.store{{.*}} %[[CHILD_VPTR]], %[[CHILD_VPTR_ADDR]] : !cir.vptr, 
!cir.ptr<!cir.vptr>
 // CIR:   %[[FATHER_IN_CHILD_VPTR:.*]] = cir.vtable.address_point(@_ZTV5Child, 
address_point = <index = 1, offset = 2>) : !cir.vptr
-// CIR:   %[[FATHER_BASE:.*]] = cir.base_class_addr %[[THIS]] : 
!cir.ptr<!rec_Child> nonnull [8] -> !cir.ptr<!rec_Father>
+// CIR:   %[[FATHER_BASE:.*]] = cir.base_class_addr nonnull %[[THIS]] [8] : 
!cir.ptr<!rec_Child> -> !cir.ptr<!rec_Father>
 // CIR:   %[[FATHER_IN_CHILD_VPTR_ADDR:.*]] = cir.vtable.get_vptr 
%[[FATHER_BASE]] : !cir.ptr<!rec_Father> -> !cir.ptr<!cir.vptr>
 // CIR:   cir.store{{.*}} %[[FATHER_IN_CHILD_VPTR]], 
%[[FATHER_IN_CHILD_VPTR_ADDR]] : !cir.vptr, !cir.ptr<!cir.vptr>
 // CIR:   cir.return
diff --git a/clang/test/CIR/CodeGen/paren-list-agg-init.cpp 
b/clang/test/CIR/CodeGen/paren-list-agg-init.cpp
index a5e84669d914d..f7850527491f2 100644
--- a/clang/test/CIR/CodeGen/paren-list-agg-init.cpp
+++ b/clang/test/CIR/CodeGen/paren-list-agg-init.cpp
@@ -211,7 +211,7 @@ C foo3() {
 // CIR: %[[C2_ALLOCA:.*]] = cir.alloca ![[STRUCT_C]], !cir.ptr<![[STRUCT_C]]>, 
["c2", init]
 // CIR: %[[B_TMP:.*]] = cir.alloca ![[STRUCT_B]], !cir.ptr<![[STRUCT_B]]>, 
["ref.tmp0"]
 // CIR: %[[A_TMP:.*]] = cir.alloca ![[STRUCT_A]], !cir.ptr<![[STRUCT_A]]>, 
["ref.tmp1"]
-// CIR: %[[C_BASE:.*]] = cir.base_class_addr %[[C2_ALLOCA]] : 
!cir.ptr<![[STRUCT_C]]> nonnull [0] -> !cir.ptr<![[STRUCT_B]]>
+// CIR: %[[C_BASE:.*]] = cir.base_class_addr nonnull %[[C2_ALLOCA]] [0] : 
!cir.ptr<![[STRUCT_C]]> -> !cir.ptr<![[STRUCT_B]]>
 // CIR: %[[GET_A:.*]] = cir.get_member %[[B_TMP]][0] {name = "a"} : 
!cir.ptr<![[STRUCT_B]]> -> !cir.ptr<![[STRUCT_A]]>
 // CIR: %[[GET_I:.*]] = cir.get_member %[[GET_A]][0] {name = "i"} : 
!cir.ptr<![[STRUCT_A]]> -> !cir.ptr<!s8i>
 // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s8i
@@ -224,7 +224,7 @@ C foo3() {
 // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i
 // CIR: cir.store{{.*}} %[[ONE]], %[[GET_B]] : !s32i, !cir.ptr<!s32i>
 // CIR: cir.copy %[[B_TMP]] to %[[C_BASE]] : !cir.ptr<![[STRUCT_B]]>
-// CIR: %[[C_BASE_A:.*]] = cir.base_class_addr %[[C2_ALLOCA]] : 
!cir.ptr<![[STRUCT_C]]> nonnull [24] -> !cir.ptr<![[STRUCT_A]]>
+// CIR: %[[C_BASE_A:.*]] = cir.base_class_addr nonnull %[[C2_ALLOCA]] [24] : 
!cir.ptr<![[STRUCT_C]]> -> !cir.ptr<![[STRUCT_A]]>
 // CIR: %[[GET_I:.*]] = cir.get_member %[[A_TMP]][0] {name = "i"} : 
!cir.ptr<![[STRUCT_A]]> -> !cir.ptr<!s8i>
 // CIR: %[[NINETYSEVEN:.*]] = cir.const #cir.int<97> : !s8i
 // CIR: cir.store{{.*}} %[[NINETYSEVEN]], %[[GET_I]] : !s8i, !cir.ptr<!s8i>
diff --git a/clang/test/CIR/CodeGen/vbase.cpp b/clang/test/CIR/CodeGen/vbase.cpp
index 6a6e1eeb2fdb0..33ecdafc6acb1 100644
--- a/clang/test/CIR/CodeGen/vbase.cpp
+++ b/clang/test/CIR/CodeGen/vbase.cpp
@@ -76,7 +76,7 @@ void ppp() { B b; }
 // CIR: cir.func {{.*}}@_Z1gv()
 // CIR:   %[[DF:.+]] = cir.alloca !rec_DerivedFinal, 
!cir.ptr<!rec_DerivedFinal>, ["df", init]
 // CIR:   cir.call @_ZN12DerivedFinalC1Ev(%[[DF]]) nothrow : 
(!cir.ptr<!rec_DerivedFinal> {{.*}}) -> ()
-// CIR:   %[[BASE_THIS_2:.+]] = cir.base_class_addr %[[DF]] : 
!cir.ptr<!rec_DerivedFinal> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR:   %[[BASE_THIS_2:.+]] = cir.base_class_addr nonnull %[[DF]] [0] : 
!cir.ptr<!rec_DerivedFinal> -> !cir.ptr<!rec_Base>
 // CIR:   cir.call @_ZN4Base1fEv(%[[BASE_THIS_2]]) : (!cir.ptr<!rec_Base> 
{{.*}}) -> ()
 // CIR:   cir.return
 
@@ -117,7 +117,7 @@ void ppp() { B b; }
 // CIR:   %[[THIS_ADDR:.*]] = cir.alloca !cir.ptr<!rec_B>, 
!cir.ptr<!cir.ptr<!rec_B>>, ["this", init]
 // CIR:   cir.store %arg0, %[[THIS_ADDR]] : !cir.ptr<!rec_B>, 
!cir.ptr<!cir.ptr<!rec_B>>
 // CIR:   %[[THIS:.*]] = cir.load %[[THIS_ADDR]] : !cir.ptr<!cir.ptr<!rec_B>>, 
!cir.ptr<!rec_B>
-// CIR:   %[[BASE_A_ADDR:.*]] = cir.base_class_addr %[[THIS]] : 
!cir.ptr<!rec_B> nonnull [12] -> !cir.ptr<!rec_A>
+// CIR:   %[[BASE_A_ADDR:.*]] = cir.base_class_addr nonnull %[[THIS]] [12] : 
!cir.ptr<!rec_B> -> !cir.ptr<!rec_A>
 // CIR:   %[[VTABLE:.*]] = cir.vtable.address_point(@_ZTV1B, address_point = 
<index = 0, offset = 3>) : !cir.vptr
 // CIR:   %[[B_VPTR:.*]] = cir.vtable.get_vptr %[[THIS]] : !cir.ptr<!rec_B> -> 
!cir.ptr<!cir.vptr>
 // CIR:   cir.store align(8) %[[VTABLE]], %[[B_VPTR]] : !cir.vptr, 
!cir.ptr<!cir.vptr>
diff --git a/clang/test/CIR/CodeGen/virtual-destructor-calls.cpp 
b/clang/test/CIR/CodeGen/virtual-destructor-calls.cpp
index 7f31106661aef..33076208a5725 100644
--- a/clang/test/CIR/CodeGen/virtual-destructor-calls.cpp
+++ b/clang/test/CIR/CodeGen/virtual-destructor-calls.cpp
@@ -79,7 +79,7 @@ C::~C() { }
 // Base (D2) dtor for C: calls B's base dtor.
 
 // CIR: cir.func{{.*}} @_ZN1CD2Ev
-// CIR:   %[[B:.*]] = cir.base_class_addr %[[THIS:.*]] : !cir.ptr<!rec_C> 
nonnull [0] -> !cir.ptr<!rec_B>
+// CIR:   %[[B:.*]] = cir.base_class_addr nonnull %[[THIS:.*]] [0] : 
!cir.ptr<!rec_C> -> !cir.ptr<!rec_B>
 // CIR:   cir.call @_ZN1BD2Ev(%[[B]])
 
 // LLVM: define{{.*}} void @_ZN1CD2Ev
diff --git a/clang/test/CIR/CodeGen/vtt.cpp b/clang/test/CIR/CodeGen/vtt.cpp
index bd926c46d7a9b..4b4ef57b7db4f 100644
--- a/clang/test/CIR/CodeGen/vtt.cpp
+++ b/clang/test/CIR/CodeGen/vtt.cpp
@@ -412,10 +412,10 @@ D::D() {}
 // CIR-COMMON:        cir.store %[[VTT_ARG]], %[[VTT_ADDR]]
 // CIR-COMMON:        %[[THIS:.*]] = cir.load %[[THIS_ADDR]]
 // CIR-COMMON:        %[[VTT:.*]] = cir.load{{.*}} %[[VTT_ADDR]]
-// CIR-COMMON:        %[[B_ADDR:.*]] = cir.base_class_addr %[[THIS]] : 
!cir.ptr<!rec_D> nonnull [0] -> !cir.ptr<!rec_B>
+// CIR-COMMON:        %[[B_ADDR:.*]] = cir.base_class_addr nonnull %[[THIS]] 
[0] : !cir.ptr<!rec_D> -> !cir.ptr<!rec_B>
 // CIR-COMMON:        %[[B_VTT:.*]] = cir.vtt.address_point %[[VTT]] : 
!cir.ptr<!cir.ptr<!void>>, offset = 1 -> !cir.ptr<!cir.ptr<!void>>
 // CIR-COMMON:        cir.call @_ZN1BC2Ev(%[[B_ADDR]], %[[B_VTT]]) nothrow : 
(!cir.ptr<!rec_B> {{.*}}, !cir.ptr<!cir.ptr<!void>> {{.*}}) -> ()
-// CIR-COMMON:        %[[C_ADDR:.*]] = cir.base_class_addr %[[THIS]] : 
!cir.ptr<!rec_D> nonnull [16] -> !cir.ptr<!rec_C>
+// CIR-COMMON:        %[[C_ADDR:.*]] = cir.base_class_addr nonnull %[[THIS]] 
[16] : !cir.ptr<!rec_D> -> !cir.ptr<!rec_C>
 // CIR-COMMON:        %[[C_VTT:.*]] = cir.vtt.address_point %[[VTT]] : 
!cir.ptr<!cir.ptr<!void>>, offset = 3 -> !cir.ptr<!cir.ptr<!void>>
 // CIR-COMMON:        cir.call @_ZN1CC2Ev(%[[C_ADDR]], %[[C_VTT]]) nothrow : 
(!cir.ptr<!rec_C> {{.*}}, !cir.ptr<!cir.ptr<!void>> {{.*}}) -> ()
 // CIR-COMMON:        %[[D_VTT:.*]] = cir.vtt.address_point %[[VTT]] : 
!cir.ptr<!cir.ptr<!void>>, offset = 0 -> !cir.ptr<!cir.ptr<!void>>
@@ -441,7 +441,7 @@ D::D() {}
 // CIR-COMMON:        %[[C_VTT_ADDR_POINT:.*]] = cir.vtt.address_point 
%[[VTT]] : !cir.ptr<!cir.ptr<!void>>, offset = 6 -> !cir.ptr<!cir.ptr<!void>>
 // CIR-COMMON:        %[[C_VPTR_ADDR:.*]] = cir.cast bitcast 
%[[C_VTT_ADDR_POINT]] : !cir.ptr<!cir.ptr<!void>> -> !cir.ptr<!cir.vptr>
 // CIR-COMMON:        %[[C_VPTR:.*]] = cir.load{{.*}} %[[C_VPTR_ADDR]] : 
!cir.ptr<!cir.vptr>, !cir.vptr
-// CIR-COMMON:        %[[C_ADDR:.*]] = cir.base_class_addr %[[THIS]] : 
!cir.ptr<!rec_D> nonnull [16] -> !cir.ptr<!rec_C>
+// CIR-COMMON:        %[[C_ADDR:.*]] = cir.base_class_addr nonnull %[[THIS]] 
[16] : !cir.ptr<!rec_D> -> !cir.ptr<!rec_C>
 // CIR-COMMON:        %[[C_VPTR_ADDR:.*]] = cir.vtable.get_vptr %[[C_ADDR]] : 
!cir.ptr<!rec_C> -> !cir.ptr<!cir.vptr>
 // CIR-COMMON:        cir.store{{.*}} %[[C_VPTR]], %[[C_VPTR_ADDR]] : 
!cir.vptr, !cir.ptr<!cir.vptr>
 
@@ -499,23 +499,23 @@ D::D() {}
 // CIR-COMMON:        %[[THIS_ADDR:.*]] = cir.alloca {{.*}} ["this", init]
 // CIR-COMMON:        cir.store %[[THIS_ARG]], %[[THIS_ADDR]]
 // CIR-COMMON:        %[[THIS:.*]] = cir.load %[[THIS_ADDR]]
-// CIR-COMMON:        %[[A_ADDR:.*]] = cir.base_class_addr %[[THIS]] : 
!cir.ptr<!rec_D> nonnull [40] -> !cir.ptr<!rec_A>
+// CIR-COMMON:        %[[A_ADDR:.*]] = cir.base_class_addr nonnull %[[THIS]] 
[40] : !cir.ptr<!rec_D> -> !cir.ptr<!rec_A>
 // CIR-COMMON:        cir.call @_ZN1AC2Ev(%[[A_ADDR]]) nothrow : 
(!cir.ptr<!rec_A> {{.*}}) -> ()
-// CIR-COMMON:        %[[B_ADDR:.*]] = cir.base_class_addr %[[THIS]] : 
!cir.ptr<!rec_D> nonnull [0] -> !cir.ptr<!rec_B>
+// CIR-COMMON:        %[[B_ADDR:.*]] = cir.base_class_addr nonnull %[[THIS]] 
[0] : !cir.ptr<!rec_D> -> !cir.ptr<!rec_B>
 // CIR-COMMON:        %[[B_VTT:.*]] = cir.vtt.address_point @_ZTT1D, offset = 
1 -> !cir.ptr<!cir.ptr<!void>>
 // CIR-COMMON:        cir.call @_ZN1BC2Ev(%[[B_ADDR]], %[[B_VTT]]) nothrow : 
(!cir.ptr<!rec_B> {{.*}}, !cir.ptr<!cir.ptr<!void>> {{.*}}) -> ()
-// CIR-COMMON:        %[[C_ADDR:.*]] = cir.base_class_addr %[[THIS]] : 
!cir.ptr<!rec_D> nonnull [16] -> !cir.ptr<!rec_C>
+// CIR-COMMON:        %[[C_ADDR:.*]] = cir.base_class_addr nonnull %[[THIS]] 
[16] : !cir.ptr<!rec_D> -> !cir.ptr<!rec_C>
 // CIR-COMMON:        %[[C_VTT:.*]] = cir.vtt.address_point @_ZTT1D, offset = 
3 -> !cir.ptr<!cir.ptr<!void>>
 // CIR-COMMON:        cir.call @_ZN1CC2Ev(%[[C_ADDR]], %[[C_VTT]]) nothrow : 
(!cir.ptr<!rec_C> {{.*}}, !cir.ptr<!cir.ptr<!void>> {{.*}}) -> ()
 // CIR-COMMON:        %[[D_VPTR:.*]] = cir.vtable.address_point(@_ZTV1D, 
address_point = <index = 0, offset = 3>) : !cir.vptr
 // CIR-COMMON:        %[[VPTR_ADDR:.*]] = cir.vtable.get_vptr %[[THIS]] : 
!cir.ptr<!rec_D> -> !cir.ptr<!cir.vptr>
 // CIR-COMMON:        cir.store{{.*}} %[[D_VPTR]], %[[VPTR_ADDR]] : !cir.vptr, 
!cir.ptr<!cir.vptr>
 // CIR-COMMON:        %[[A_VPTR:.*]] = cir.vtable.address_point(@_ZTV1D, 
address_point = <index = 2, offset = 3>) : !cir.vptr
-// CIR-COMMON:        %[[A_ADDR:.*]] = cir.base_class_addr %[[THIS]] : 
!cir.ptr<!rec_D> nonnull [40] -> !cir.ptr<!rec_A>
+// CIR-COMMON:        %[[A_ADDR:.*]] = cir.base_class_addr nonnull %[[THIS]] 
[40] : !cir.ptr<!rec_D> -> !cir.ptr<!rec_A>
 // CIR-COMMON:        %[[A_VPTR_ADDR:.*]] = cir.vtable.get_vptr %[[A_ADDR]] : 
!cir.ptr<!rec_A> -> !cir.ptr<!cir.vptr>
 // CIR-COMMON:        cir.store{{.*}} %[[A_VPTR]], %[[A_VPTR_ADDR]] : 
!cir.vptr, !cir.ptr<!cir.vptr>
 // CIR-COMMON:        %[[C_VPTR:.*]] = cir.vtable.address_point(@_ZTV1D, 
address_point = <index = 1, offset = 3>) : !cir.vptr
-// CIR-COMMON:        %[[C_ADDR:.*]] = cir.base_class_addr %[[THIS]] : 
!cir.ptr<!rec_D> nonnull [16] -> !cir.ptr<!rec_C>
+// CIR-COMMON:        %[[C_ADDR:.*]] = cir.base_class_addr nonnull %[[THIS]] 
[16] : !cir.ptr<!rec_D> -> !cir.ptr<!rec_C>
 // CIR-COMMON:        %[[C_VPTR_ADDR:.*]] = cir.vtable.get_vptr %[[C_ADDR]] : 
!cir.ptr<!rec_C> -> !cir.ptr<!cir.vptr>
 // CIR-COMMON:        cir.store{{.*}} %[[C_VPTR]], %[[C_VPTR_ADDR]] : 
!cir.vptr, !cir.ptr<!cir.vptr>
 
diff --git a/clang/test/CIR/IR/vtt-addrpoint.cir 
b/clang/test/CIR/IR/vtt-addrpoint.cir
index 823ddd2e7dc1d..b924b26919814 100644
--- a/clang/test/CIR/IR/vtt-addrpoint.cir
+++ b/clang/test/CIR/IR/vtt-addrpoint.cir
@@ -19,7 +19,7 @@ module {
     cir.store %arg1, %1 : !cir.ptr<!cir.ptr<!void>>, 
!cir.ptr<!cir.ptr<!cir.ptr<!void>>>
     %2 = cir.load %0 : !cir.ptr<!cir.ptr<!rec_C>>, !cir.ptr<!rec_C>
     %3 = cir.load align(8) %1 : !cir.ptr<!cir.ptr<!cir.ptr<!void>>>, 
!cir.ptr<!cir.ptr<!void>>
-    %4 = cir.base_class_addr %2 : !cir.ptr<!rec_C> nonnull [0] -> 
!cir.ptr<!rec_B>
+    %4 = cir.base_class_addr nonnull %2 [0] : !cir.ptr<!rec_C> -> 
!cir.ptr<!rec_B>
 
     %5 = cir.vtt.address_point %3 : !cir.ptr<!cir.ptr<!void>>, offset = 1 -> 
!cir.ptr<!cir.ptr<!void>>
     // CHECK: cir.vtt.address_point %{{.*}} : !cir.ptr<!cir.ptr<!void>>, 
offset = 1 -> !cir.ptr<!cir.ptr<!void>>
@@ -38,9 +38,9 @@ module {
     %0 = cir.alloca !cir.ptr<!rec_C>, !cir.ptr<!cir.ptr<!rec_C>>, ["this", 
init] {alignment = 8 : i64}
     cir.store %arg0, %0 : !cir.ptr<!rec_C>, !cir.ptr<!cir.ptr<!rec_C>>
     %1 = cir.load %0 : !cir.ptr<!cir.ptr<!rec_C>>, !cir.ptr<!rec_C>
-    %2 = cir.base_class_addr %1 : !cir.ptr<!rec_C> nonnull [0] -> 
!cir.ptr<!rec_A>
+    %2 = cir.base_class_addr nonnull %1 [0] : !cir.ptr<!rec_C> -> 
!cir.ptr<!rec_A>
     cir.call @_ZN1AC2Ev(%2) : (!cir.ptr<!rec_A>) -> ()
-    %3 = cir.base_class_addr %1 : !cir.ptr<!rec_C> nonnull [0] -> 
!cir.ptr<!rec_B>
+    %3 = cir.base_class_addr nonnull %1 [0] : !cir.ptr<!rec_C> -> 
!cir.ptr<!rec_B>
 
     %4 = cir.vtt.address_point @_ZTT1C, offset = 1 -> !cir.ptr<!cir.ptr<!void>>
     // CHECK: cir.vtt.address_point @_ZTT1C, offset = 1 -> 
!cir.ptr<!cir.ptr<!void>>
diff --git a/clang/test/CIR/Lowering/vtt-addrpoint.cir 
b/clang/test/CIR/Lowering/vtt-addrpoint.cir
index e1bfd00245b1b..79ab7eb17df32 100644
--- a/clang/test/CIR/Lowering/vtt-addrpoint.cir
+++ b/clang/test/CIR/Lowering/vtt-addrpoint.cir
@@ -20,7 +20,7 @@ module {
     cir.store %arg1, %1 : !cir.ptr<!cir.ptr<!void>>, 
!cir.ptr<!cir.ptr<!cir.ptr<!void>>>
     %2 = cir.load %0 : !cir.ptr<!cir.ptr<!rec_C>>, !cir.ptr<!rec_C>
     %3 = cir.load align(8) %1 : !cir.ptr<!cir.ptr<!cir.ptr<!void>>>, 
!cir.ptr<!cir.ptr<!void>>
-    %4 = cir.base_class_addr %2 : !cir.ptr<!rec_C> nonnull [0] -> 
!cir.ptr<!rec_B>
+    %4 = cir.base_class_addr nonnull %2 [0] : !cir.ptr<!rec_C> -> 
!cir.ptr<!rec_B>
     %5 = cir.vtt.address_point %3 : !cir.ptr<!cir.ptr<!void>>, offset = 1 -> 
!cir.ptr<!cir.ptr<!void>>
     cir.call @_ZN1BC2Ev(%4, %5) : (!cir.ptr<!rec_B>, 
!cir.ptr<!cir.ptr<!void>>) -> ()
     %6 = cir.vtt.address_point %3 : !cir.ptr<!cir.ptr<!void>>, offset = 0 -> 
!cir.ptr<!cir.ptr<!void>>
@@ -41,9 +41,9 @@ module {
     %0 = cir.alloca !cir.ptr<!rec_C>, !cir.ptr<!cir.ptr<!rec_C>>, ["this", 
init] {alignment = 8 : i64}
     cir.store %arg0, %0 : !cir.ptr<!rec_C>, !cir.ptr<!cir.ptr<!rec_C>>
     %1 = cir.load %0 : !cir.ptr<!cir.ptr<!rec_C>>, !cir.ptr<!rec_C>
-    %2 = cir.base_class_addr %1 : !cir.ptr<!rec_C> nonnull [0] -> 
!cir.ptr<!rec_A>
+    %2 = cir.base_class_addr nonnull %1 [0] : !cir.ptr<!rec_C> -> 
!cir.ptr<!rec_A>
     cir.call @_ZN1AC2Ev(%2) : (!cir.ptr<!rec_A>) -> ()
-    %3 = cir.base_class_addr %1 : !cir.ptr<!rec_C> nonnull [0] -> 
!cir.ptr<!rec_B>
+    %3 = cir.base_class_addr nonnull %1 [0] : !cir.ptr<!rec_C> -> 
!cir.ptr<!rec_B>
     %4 = cir.vtt.address_point @_ZTT1C, offset = 1 -> !cir.ptr<!cir.ptr<!void>>
     cir.call @_ZN1BC2Ev(%3, %4) : (!cir.ptr<!rec_B>, 
!cir.ptr<!cir.ptr<!void>>) -> ()
     %5 = cir.vtable.address_point(@_ZTV1C, address_point = <index = 0, offset 
= 3>) : !cir.vptr
diff --git a/clang/test/CIR/Transforms/pure-ptr-arithmetic.cir 
b/clang/test/CIR/Transforms/pure-ptr-arithmetic.cir
index 4c7e79923d0db..23f96325b1fc5 100644
--- a/clang/test/CIR/Transforms/pure-ptr-arithmetic.cir
+++ b/clang/test/CIR/Transforms/pure-ptr-arithmetic.cir
@@ -23,14 +23,14 @@ cir.func @dead_get_member(%arg0: !cir.ptr<!rec_S>) {
 // CHECK-LABEL: @dead_base_class_addr
 // CHECK-NOT:     cir.base_class_addr
 cir.func @dead_base_class_addr(%arg0: !cir.ptr<!rec_Derived>) {
-  %0 = cir.base_class_addr %arg0 : !cir.ptr<!rec_Derived> nonnull [0] -> 
!cir.ptr<!rec_Base>
+  %0 = cir.base_class_addr nonnull %arg0 [0] : !cir.ptr<!rec_Derived> -> 
!cir.ptr<!rec_Base>
   cir.return
 }
 
 // CHECK-LABEL: @dead_derived_class_addr
 // CHECK-NOT:     cir.derived_class_addr
 cir.func @dead_derived_class_addr(%arg0: !cir.ptr<!rec_Base>) {
-  %0 = cir.derived_class_addr %arg0 : !cir.ptr<!rec_Base> nonnull [0] -> 
!cir.ptr<!rec_Derived>
+  %0 = cir.derived_class_addr nonnull %arg0 [0] : !cir.ptr<!rec_Base> -> 
!cir.ptr<!rec_Derived>
   cir.return
 }
 

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

Reply via email to