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

>From e789f029ec7ceafe396e651c6714191ddf139fd8 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <[email protected]>
Date: Tue, 9 Dec 2025 15:46:54 -0800
Subject: [PATCH 1/2] [CIR] Upstream handling for data member pointer casts

This adds the CIR basic handling for casts of data member pointers. Cast to
bool and null, as well as member function pointer casts will be handled
in followup PRs.
---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  |  52 +++++++++
 clang/include/clang/CIR/MissingFeatures.h     |   2 +
 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp    |  34 ++++++
 clang/lib/CIR/Dialect/IR/CIRDialect.cpp       |  32 +++++
 .../Transforms/TargetLowering/CIRCXXABI.h     |  12 ++
 .../Transforms/TargetLowering/CMakeLists.txt  |   1 +
 .../TargetLowering/LowerItaniumCXXABI.cpp     |  51 ++++++++
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  18 +++
 .../CodeGen/pointer-to-data-member-cast.cpp   | 110 ++++++++++++++++++
 9 files changed, 312 insertions(+)
 create mode 100644 clang/test/CIR/CodeGen/pointer-to-data-member-cast.cpp

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 4922f83df0efb..e94280f9c1ce9 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -3994,6 +3994,58 @@ def CIR_DerivedClassAddrOp : 
CIR_Op<"derived_class_addr"> {
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// BaseDataMemberOp & DerivedDataMemberOp
+//===----------------------------------------------------------------------===//
+
+def CIR_BaseDataMemberOp : CIR_Op<"base_data_member", [Pure]> {
+  let summary =
+    "Cast a derived class data member pointer to a base class data member "
+    "pointer";
+  let description = [{
+    The `cir.base_data_member` operation casts a data member pointer of type
+    `T Derived::*` to a data member pointer of type `T Base::*`, where `Base`
+    is an accessible non-ambiguous non-virtual base class of `Derived`.
+
+    The `offset` parameter gives the offset in bytes of the `Base` base class
+    subobject within a `Derived` object.
+  }];
+
+  let arguments = (ins CIR_DataMemberType:$src, IndexAttr:$offset);
+  let results = (outs CIR_DataMemberType:$result);
+
+  let assemblyFormat = [{
+    $src `:` qualified(type($src))
+    ` ` `[` $offset `]` `->` qualified(type($result)) attr-dict
+  }];
+
+  let hasVerifier = 1;
+}
+
+def CIR_DerivedDataMemberOp : CIR_Op<"derived_data_member", [Pure]> {
+  let summary =
+    "Cast a base class data member pointer to a derived class data member "
+    "pointer";
+  let description = [{
+    The `cir.derived_data_member` operation casts a data member pointer of type
+    `T Base::*` to a data member pointer of type `T Derived::*`, where `Base`
+    is an accessible non-ambiguous non-virtual base class of `Derived`.
+
+    The `offset` parameter gives the offset in bytes of the `Base` base class
+    subobject within a `Derived` object.
+  }];
+
+  let arguments = (ins CIR_DataMemberType:$src, IndexAttr:$offset);
+  let results = (outs CIR_DataMemberType:$result);
+
+  let assemblyFormat = [{
+    $src `:` qualified(type($src))
+    ` ` `[` $offset `]` `->` qualified(type($result)) attr-dict
+  }];
+
+  let hasVerifier = 1;
+}
+
 
//===----------------------------------------------------------------------===//
 // ComplexCreateOp
 
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index 9975ee0142d77..8daf1a05f3905 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -300,6 +300,8 @@ struct MissingFeatures {
   static bool makeTripleAlwaysPresent() { return false; }
   static bool maybeHandleStaticInExternC() { return false; }
   static bool mergeAllConstants() { return false; }
+  static bool memberFuncPtrAuthInfo() { return false; }
+  static bool memberFuncPtrCast() { return false; }
   static bool metaDataNode() { return false; }
   static bool moduleNameHash() { return false; }
   static bool msabi() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 3b5ed225a58d6..3d5fd656c2606 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -2207,6 +2207,40 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr 
*ce) {
     return builder.getNullPtr(ty, cgf.getLoc(subExpr->getExprLoc()));
   }
 
+  case CK_BaseToDerivedMemberPointer:
+  case CK_DerivedToBaseMemberPointer: {
+    mlir::Value src = Visit(subExpr);
+
+    assert(!cir::MissingFeatures::memberFuncPtrAuthInfo());
+
+    QualType derivedTy =
+        kind == CK_DerivedToBaseMemberPointer ? subExpr->getType() : destTy;
+    const auto *mpType = derivedTy->castAs<MemberPointerType>();
+    NestedNameSpecifier qualifier = mpType->getQualifier();
+    assert(qualifier && "member pointer without class qualifier");
+    const Type *qualifierType = qualifier.getAsType();
+    assert(qualifierType && "member pointer qualifier is not a type");
+    const CXXRecordDecl *derivedClass = qualifierType->getAsCXXRecordDecl();
+    CharUnits offset = cgf.cgm.computeNonVirtualBaseClassOffset(
+        derivedClass, ce->path());
+
+    mlir::Location loc = cgf.getLoc(subExpr->getExprLoc());
+    mlir::Type resultTy = cgf.convertType(destTy);
+    mlir::IntegerAttr offsetAttr = builder.getIndexAttr(offset.getQuantity());
+
+    if (subExpr->getType()->isMemberFunctionPointerType()) {
+      cgf.cgm.errorNYI(subExpr->getSourceRange(),
+                       "VisitCastExpr: member function pointer");
+      return {};
+    }
+
+    if (kind == CK_BaseToDerivedMemberPointer)
+      return cir::DerivedDataMemberOp::create(builder, loc, resultTy, src,
+                                              offsetAttr);
+    return cir::BaseDataMemberOp::create(builder, loc, resultTy, src,
+                                         offsetAttr);
+  }
+
   case CK_LValueToRValue:
     assert(cgf.getContext().hasSameUnqualifiedType(subExpr->getType(), 
destTy));
     assert(subExpr->isGLValue() && "lvalue-to-rvalue applied to r-value!");
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp 
b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index ffe93c5b4124b..7501d48364d30 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -2414,6 +2414,38 @@ OpFoldResult cir::UnaryOp::fold(FoldAdaptor adaptor) {
 
   return {};
 }
+
+//===----------------------------------------------------------------------===//
+// BaseDataMemberOp & DerivedDataMemberOp
+//===----------------------------------------------------------------------===//
+
+static LogicalResult verifyMemberPtrCast(Operation *op, mlir::Value src,
+                                         mlir::Type resultTy) {
+  // Let the operand type be T1 C1::*, let the result type be T2 C2::*.
+  // Verify that T1 and T2 are the same type.
+  mlir::Type inputMemberTy;
+  mlir::Type resultMemberTy;
+  if (mlir::isa<cir::DataMemberType>(src.getType())) {
+    inputMemberTy =
+        mlir::cast<cir::DataMemberType>(src.getType()).getMemberTy();
+    resultMemberTy = mlir::cast<cir::DataMemberType>(resultTy).getMemberTy();
+  }
+  assert(!cir::MissingFeatures::memberFuncPtrCast());
+  if (inputMemberTy != resultMemberTy)
+    return op->emitOpError()
+           << "member types of the operand and the result do not match";
+
+  return mlir::success();
+}
+
+LogicalResult cir::BaseDataMemberOp::verify() {
+  return verifyMemberPtrCast(getOperation(), getSrc(), getType());
+}
+
+LogicalResult cir::DerivedDataMemberOp::verify() {
+  return verifyMemberPtrCast(getOperation(), getSrc(), getType());
+}
+
 
//===----------------------------------------------------------------------===//
 // AwaitOp
 
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/CIRCXXABI.h 
b/clang/lib/CIR/Dialect/Transforms/TargetLowering/CIRCXXABI.h
index 90f0ac3478f9d..94472af27ea3f 100644
--- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/CIRCXXABI.h
+++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/CIRCXXABI.h
@@ -53,6 +53,18 @@ class CIRCXXABI {
   lowerGetRuntimeMember(cir::GetRuntimeMemberOp op, mlir::Type loweredResultTy,
                         mlir::Value loweredAddr, mlir::Value loweredMember,
                         mlir::OpBuilder &builder) const = 0;
+
+  /// Lower the given cir.base_data_member op to a sequence of more "primitive"
+  /// CIR operations that act on the ABI types.
+  virtual mlir::Value lowerBaseDataMember(cir::BaseDataMemberOp op,
+                                          mlir::Value loweredSrc,
+                                          mlir::OpBuilder &builder) const = 0;
+
+  /// Lower the given cir.derived_data_member op to a sequence of more
+  /// "primitive" CIR operations that act on the ABI types.
+  virtual mlir::Value
+  lowerDerivedDataMember(cir::DerivedDataMemberOp op, mlir::Value loweredSrc,
+                         mlir::OpBuilder &builder) const = 0;
 };
 
 /// Creates an Itanium-family ABI.
diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt 
b/clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt
index 158c42e729536..3a1ab34cea4d9 100644
--- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt
+++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt
@@ -17,4 +17,5 @@ add_clang_library(MLIRCIRTargetLowering
   MLIRDLTIDialect
   MLIRCIR
   MLIRCIRInterfaces
+  MLIRLLVMDialect
 )
diff --git 
a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp 
b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp
index ce4b0c7e92d09..1d28107ba248b 100644
--- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp
@@ -47,6 +47,14 @@ class LowerItaniumCXXABI : public CIRCXXABI {
   lowerGetRuntimeMember(cir::GetRuntimeMemberOp op, mlir::Type loweredResultTy,
                         mlir::Value loweredAddr, mlir::Value loweredMember,
                         mlir::OpBuilder &builder) const override;
+
+  mlir::Value lowerBaseDataMember(cir::BaseDataMemberOp op,
+                                  mlir::Value loweredSrc,
+                                  mlir::OpBuilder &builder) const override;
+
+  mlir::Value lowerDerivedDataMember(cir::DerivedDataMemberOp op,
+                                     mlir::Value loweredSrc,
+                                     mlir::OpBuilder &builder) const override;
 };
 
 } // namespace
@@ -108,4 +116,47 @@ mlir::Operation *LowerItaniumCXXABI::lowerGetRuntimeMember(
                              cir::CastKind::bitcast, memberBytesPtr);
 }
 
+static mlir::Value lowerDataMemberCast(mlir::Operation *op,
+                                       mlir::Value loweredSrc,
+                                       std::int64_t offset,
+                                       bool isDerivedToBase,
+                                       mlir::OpBuilder &builder) {
+  if (offset == 0)
+    return loweredSrc;
+  mlir::Location loc = op->getLoc();
+  mlir::Type ty = loweredSrc.getType();
+
+  auto nullValue = mlir::LLVM::ConstantOp::create(
+      builder, loc, ty, mlir::IntegerAttr::get(ty, -1));
+
+  auto isNull = mlir::LLVM::ICmpOp::create(
+      builder, loc, mlir::LLVM::ICmpPredicate::eq, loweredSrc, nullValue);
+
+  auto offsetValue = mlir::LLVM::ConstantOp::create(
+      builder, loc, ty, mlir::IntegerAttr::get(ty, offset));
+  mlir::Value adjustedPtr;
+  if (isDerivedToBase)
+    adjustedPtr = mlir::LLVM::SubOp::create(builder, loc, loweredSrc, 
offsetValue, mlir::LLVM::IntegerOverflowFlags::nsw);
+  else
+    adjustedPtr = mlir::LLVM::AddOp::create(builder, loc, loweredSrc, 
offsetValue, mlir::LLVM::IntegerOverflowFlags::nsw);
+
+  return mlir::LLVM::SelectOp::create(builder, loc, isNull, loweredSrc, 
adjustedPtr);
+}
+
+mlir::Value
+LowerItaniumCXXABI::lowerBaseDataMember(cir::BaseDataMemberOp op,
+                                        mlir::Value loweredSrc,
+                                        mlir::OpBuilder &builder) const {
+  return lowerDataMemberCast(op, loweredSrc, op.getOffset().getSExtValue(),
+                             /*isDerivedToBase=*/true, builder);
+}
+
+mlir::Value
+LowerItaniumCXXABI::lowerDerivedDataMember(cir::DerivedDataMemberOp op,
+                                           mlir::Value loweredSrc,
+                                           mlir::OpBuilder &builder) const {
+  return lowerDataMemberCast(op, loweredSrc, op.getOffset().getSExtValue(),
+                             /*isDerivedToBase=*/false, builder);
+}
+
 } // namespace cir
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index c01b2c1487709..a95c6520e9e83 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1482,6 +1482,24 @@ mlir::LogicalResult 
CIRToLLVMDerivedClassAddrOpLowering::matchAndRewrite(
   return mlir::success();
 }
 
+mlir::LogicalResult CIRToLLVMBaseDataMemberOpLowering::matchAndRewrite(
+    cir::BaseDataMemberOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  mlir::Value loweredResult =
+      lowerMod->getCXXABI().lowerBaseDataMember(op, adaptor.getSrc(), 
rewriter);
+  rewriter.replaceOp(op, loweredResult);
+  return mlir::success();
+}
+
+mlir::LogicalResult CIRToLLVMDerivedDataMemberOpLowering::matchAndRewrite(
+    cir::DerivedDataMemberOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  mlir::Value loweredResult = lowerMod->getCXXABI().lowerDerivedDataMember(
+      op, adaptor.getSrc(), rewriter);
+  rewriter.replaceOp(op, loweredResult);
+  return mlir::success();
+}
+
 mlir::LogicalResult CIRToLLVMATanOpLowering::matchAndRewrite(
     cir::ATanOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
diff --git a/clang/test/CIR/CodeGen/pointer-to-data-member-cast.cpp 
b/clang/test/CIR/CodeGen/pointer-to-data-member-cast.cpp
new file mode 100644
index 0000000000000..e5c673d031a2e
--- /dev/null
+++ b/clang/test/CIR/CodeGen/pointer-to-data-member-cast.cpp
@@ -0,0 +1,110 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++17 -fclangir 
-emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir --check-prefix=CIR %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++17 -fclangir 
-emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll --check-prefix=LLVM %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++17 -emit-llvm %s 
-o %t.ll
+// RUN: FileCheck --input-file=%t.ll --check-prefix=OGCG %s
+
+struct Base1 {
+  int base1_data;
+};
+
+struct Base2 {
+  int base2_data;
+};
+
+struct Derived : Base1, Base2 {
+  int derived_data;
+};
+
+auto base_to_derived(int Base2::*ptr) -> int Derived::* {
+  return ptr;
+}
+
+// CIR: cir.func {{.*}} @_Z15base_to_derivedM5Base2i
+// CIR:   %[[PTR:.*]] = cir.load{{.*}} %{{.*}}
+// CIR:   %[[RET:.*]] = cir.derived_data_member %[[PTR]] : 
!cir.data_member<!s32i in !rec_Base2> [4] -> !cir.data_member<!s32i in 
!rec_Derived>
+
+// LLVM: define {{.*}} i64 @_Z15base_to_derivedM5Base2i
+// LLVM:   %[[PTR:.*]] = load i64, ptr %{{.*}}
+// LLVM:   %[[IS_NULL:.*]] = icmp eq i64 %[[PTR]], -1
+// LLVM:   %[[DERIVED:.*]] = add nsw i64 %[[PTR]], 4
+// LLVM:   %[[RET:.*]] = select i1 %[[IS_NULL]], i64 %[[PTR]], i64 %[[DERIVED]]
+
+// OGCG: define {{.*}} i64 @_Z15base_to_derivedM5Base2i
+// OGCG:   %[[PTR:.*]] = load i64, ptr %{{.*}}
+// OGCG:   %[[DERIVED:.*]] = add nsw i64 %[[PTR]], 4
+// OGCG:   %[[IS_NULL:.*]] = icmp eq i64 %[[PTR]], -1
+// OGCG:   %[[RET:.*]] = select i1 %[[IS_NULL]], i64 %[[PTR]], i64 %[[DERIVED]]
+
+auto derived_to_base(int Derived::*ptr) -> int Base2::* {
+  return static_cast<int Base2::*>(ptr);
+}
+
+// CIR: cir.func {{.*}} @_Z15derived_to_baseM7Derivedi
+// CIR:   %[[PTR:.*]] = cir.load{{.*}} %{{.*}}
+// CIR:   %[[RET:.*]] = cir.base_data_member %[[PTR]] : !cir.data_member<!s32i 
in !rec_Derived> [4] -> !cir.data_member<!s32i in !rec_Base2>
+
+// LLVM: define {{.*}} i64 @_Z15derived_to_baseM7Derivedi
+// LLVM:   %[[PTR:.*]] = load i64, ptr %{{.*}}
+// LLVM:   %[[IS_NULL:.*]] = icmp eq i64 %[[PTR]], -1
+// LLVM:   %[[BASE:.*]] = sub nsw i64 %[[PTR]], 4
+// LLVM:   %[[RET:.*]] = select i1 %[[IS_NULL]], i64 %[[PTR]], i64 %[[BASE]]
+
+// OGCG: define {{.*}} i64 @_Z15derived_to_baseM7Derivedi
+// OGCG:   %[[PTR:.*]] = load i64, ptr %{{.*}}
+// OGCG:   %[[BASE:.*]] = sub nsw i64 %[[PTR]], 4
+// OGCG:   %[[IS_NULL:.*]] = icmp eq i64 %[[PTR]], -1
+// OGCG:   %[[RET:.*]] = select i1 %[[IS_NULL]], i64 %[[PTR]], i64 %[[BASE]]
+
+auto base_to_derived_zero_offset(int Base1::*ptr) -> int Derived::* {
+  return ptr;
+}
+
+// CIR: cir.func {{.*}} @_Z27base_to_derived_zero_offsetM5Base1i
+// CIR:   %[[PTR:.*]] = cir.load{{.*}} %{{.*}}
+// CIR:   %[[RET:.*]] = cir.derived_data_member %[[PTR]] : 
!cir.data_member<!s32i in !rec_Base1> [0] -> !cir.data_member<!s32i in 
!rec_Derived>
+
+// No LLVM instructions emitted for performing a zero-offset cast.
+
+// LLVM:      define {{.*}} i64 @_Z27base_to_derived_zero_offsetM5Base1i
+// LLVM-NEXT:   %[[PTR_ADDR:.*]] = alloca i64
+// LLVM-NEXT:   %[[RETVAL:.*]] = alloca i64
+// LLVM-NEXT:   store i64 %{{.*}}, ptr %[[PTR_ADDR]]
+// LLVM-NEXT:   %[[TEMP:.*]] = load i64, ptr %[[PTR_ADDR]]
+// LLVM-NEXT:   store i64 %[[TEMP]], ptr %[[RETVAL]]
+// LLVM-NEXT:   %[[RET:.*]] = load i64, ptr %[[RETVAL]]
+// LLVM-NEXT:   ret i64 %[[RET]]
+
+// OGCG:      define {{.*}} i64 @_Z27base_to_derived_zero_offsetM5Base1i
+// OGCG-NEXT: entry:
+// OGCG-NEXT:   %[[PTR_ADDR:.*]] = alloca i64
+// OGCG-NEXT:   store i64 %{{.*}}, ptr %[[PTR_ADDR]]
+// OGCG-NEXT:   %[[RET:.*]] = load i64, ptr %[[PTR_ADDR]]
+// OGCG-NEXT:   ret i64 %[[RET]]
+
+auto derived_to_base_zero_offset(int Derived::*ptr) -> int Base1::* {
+  return static_cast<int Base1::*>(ptr);
+}
+
+// CIR: cir.func {{.*}} @_Z27derived_to_base_zero_offsetM7Derivedi
+// CIR:   %[[PTR:.*]] = cir.load{{.*}} %{{.*}}
+// CIR:   %[[RET:.*]] = cir.base_data_member %[[PTR]] : !cir.data_member<!s32i 
in !rec_Derived> [0] -> !cir.data_member<!s32i in !rec_Base1>
+
+// No LLVM instructions emitted for performing a zero-offset cast.
+
+// LLVM:      define {{.*}} i64 @_Z27derived_to_base_zero_offsetM7Derivedi
+// LLVM-NEXT:   %[[PTR_ADDR:.*]] = alloca i64
+// LLVM-NEXT:   %[[RETVAL:.*]] = alloca i64
+// LLVM-NEXT:   store i64 %{{.*}}, ptr %[[PTR_ADDR]]
+// LLVM-NEXT:   %[[TEMP:.*]] = load i64, ptr %[[PTR_ADDR]]
+// LLVM-NEXT:   store i64 %[[TEMP]], ptr %[[RETVAL]]
+// LLVM-NEXT:   %[[RET:.*]] = load i64, ptr %[[RETVAL]]
+// LLVM-NEXT:   ret i64 %[[RET]]
+
+// OGCG:      define {{.*}} i64 @_Z27derived_to_base_zero_offsetM7Derivedi
+// OGCG-NEXT: entry:
+// OGCG-NEXT:   %[[PTR_ADDR:.*]] = alloca i64
+// OGCG-NEXT:   store i64 %{{.*}}, ptr %[[PTR_ADDR]]
+// OGCG-NEXT:   %[[RET:.*]] = load i64, ptr %[[PTR_ADDR]]
+// OGCG-NEXT:   ret i64 %[[RET]]

>From 1623875e4b8b28c95a98713ebaf177266c945fc3 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <[email protected]>
Date: Fri, 12 Dec 2025 09:20:22 -0800
Subject: [PATCH 2/2] Fix formatting

---
 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp            |  4 ++--
 .../Transforms/TargetLowering/LowerItaniumCXXABI.cpp  | 11 ++++++++---
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 3d5fd656c2606..b4b7ab120904b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -2221,8 +2221,8 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr 
*ce) {
     const Type *qualifierType = qualifier.getAsType();
     assert(qualifierType && "member pointer qualifier is not a type");
     const CXXRecordDecl *derivedClass = qualifierType->getAsCXXRecordDecl();
-    CharUnits offset = cgf.cgm.computeNonVirtualBaseClassOffset(
-        derivedClass, ce->path());
+    CharUnits offset =
+        cgf.cgm.computeNonVirtualBaseClassOffset(derivedClass, ce->path());
 
     mlir::Location loc = cgf.getLoc(subExpr->getExprLoc());
     mlir::Type resultTy = cgf.convertType(destTy);
diff --git 
a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp 
b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp
index 1d28107ba248b..8028beea76e8e 100644
--- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp
@@ -136,11 +136,16 @@ static mlir::Value lowerDataMemberCast(mlir::Operation 
*op,
       builder, loc, ty, mlir::IntegerAttr::get(ty, offset));
   mlir::Value adjustedPtr;
   if (isDerivedToBase)
-    adjustedPtr = mlir::LLVM::SubOp::create(builder, loc, loweredSrc, 
offsetValue, mlir::LLVM::IntegerOverflowFlags::nsw);
+    adjustedPtr =
+        mlir::LLVM::SubOp::create(builder, loc, loweredSrc, offsetValue,
+                                  mlir::LLVM::IntegerOverflowFlags::nsw);
   else
-    adjustedPtr = mlir::LLVM::AddOp::create(builder, loc, loweredSrc, 
offsetValue, mlir::LLVM::IntegerOverflowFlags::nsw);
+    adjustedPtr =
+        mlir::LLVM::AddOp::create(builder, loc, loweredSrc, offsetValue,
+                                  mlir::LLVM::IntegerOverflowFlags::nsw);
 
-  return mlir::LLVM::SelectOp::create(builder, loc, isNull, loweredSrc, 
adjustedPtr);
+  return mlir::LLVM::SelectOp::create(builder, loc, isNull, loweredSrc,
+                                      adjustedPtr);
 }
 
 mlir::Value

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

Reply via email to