[clang] 26fdd8f - [CIR] Upstream support for data member comparison (#171897)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 9 17:03:23 PST 2026
Author: Andy Kaylor
Date: 2026-01-10T01:03:18Z
New Revision: 26fdd8faff33b0af12c4deb1abd5d5e4ebec1a00
URL: https://github.com/llvm/llvm-project/commit/26fdd8faff33b0af12c4deb1abd5d5e4ebec1a00
DIFF: https://github.com/llvm/llvm-project/commit/26fdd8faff33b0af12c4deb1abd5d5e4ebec1a00.diff
LOG: [CIR] Upstream support for data member comparison (#171897)
This adds support for handling data member pointer comparisons in CIR.
Added:
clang/test/CIR/CodeGen/pointer-to-data-member-cmp.cpp
Modified:
clang/include/clang/CIR/Dialect/IR/CIROps.td
clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp
clang/lib/CIR/Dialect/Transforms/TargetLowering/CIRCXXABI.h
clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp
clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 35f09cc31197b..cf7e398e53cd4 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -1828,6 +1828,7 @@ def CIR_CmpOp : CIR_Op<"cmp", [Pure, SameTypeOperands]> {
}];
let isLLVMLoweringRecursive = true;
+ let hasCXXABILowering = true;
}
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp
index d2417de0d0ea3..99addf8d0adb4 100644
--- a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp
@@ -58,7 +58,7 @@ class CIRGenericCXXABILoweringPattern : public mlir::ConversionPattern {
mlir::ConversionPatternRewriter &rewriter) const override {
// Do not match on operations that have dedicated ABI lowering rewrite rules
if (llvm::isa<cir::AllocaOp, cir::BaseDataMemberOp, cir::ConstantOp,
- cir::DerivedDataMemberOp, cir::FuncOp,
+ cir::CmpOp, cir::DerivedDataMemberOp, cir::FuncOp,
cir::GetRuntimeMemberOp, cir::GlobalOp>(op))
return mlir::failure();
@@ -146,6 +146,21 @@ mlir::LogicalResult CIRConstantOpABILowering::matchAndRewrite(
llvm_unreachable("constant operand is not an CXXABI-dependent type");
}
+mlir::LogicalResult CIRCmpOpABILowering::matchAndRewrite(
+ cir::CmpOp op, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ mlir::Type type = op.getLhs().getType();
+ assert((mlir::isa<cir::DataMemberType>(type)) &&
+ "input to cmp in ABI lowering must be a data member");
+
+ assert(!cir::MissingFeatures::methodType());
+ mlir::Value loweredResult = lowerModule->getCXXABI().lowerDataMemberCmp(
+ op, adaptor.getLhs(), adaptor.getRhs(), rewriter);
+
+ rewriter.replaceOp(op, loweredResult);
+ return mlir::success();
+}
+
mlir::LogicalResult CIRFuncOpABILowering::matchAndRewrite(
cir::FuncOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/CIRCXXABI.h b/clang/lib/CIR/Dialect/Transforms/TargetLowering/CIRCXXABI.h
index 6c166b3aed5d6..d554a64e4bf63 100644
--- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/CIRCXXABI.h
+++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/CIRCXXABI.h
@@ -71,6 +71,10 @@ class CIRCXXABI {
virtual mlir::Value
lowerDerivedDataMember(cir::DerivedDataMemberOp op, mlir::Value loweredSrc,
mlir::OpBuilder &builder) const = 0;
+
+ virtual mlir::Value lowerDataMemberCmp(cir::CmpOp op, mlir::Value loweredLhs,
+ mlir::Value loweredRhs,
+ mlir::OpBuilder &builder) const = 0;
};
/// Creates an Itanium-family ABI.
diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp
index c58e6c4f224f8..5abe58489e96f 100644
--- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp
@@ -59,6 +59,10 @@ class LowerItaniumCXXABI : public CIRCXXABI {
mlir::Value lowerDerivedDataMember(cir::DerivedDataMemberOp op,
mlir::Value loweredSrc,
mlir::OpBuilder &builder) const override;
+
+ mlir::Value lowerDataMemberCmp(cir::CmpOp op, mlir::Value loweredLhs,
+ mlir::Value loweredRhs,
+ mlir::OpBuilder &builder) const override;
};
} // namespace
@@ -185,4 +189,12 @@ LowerItaniumCXXABI::lowerDerivedDataMember(cir::DerivedDataMemberOp op,
/*isDerivedToBase=*/false, builder);
}
+mlir::Value
+LowerItaniumCXXABI::lowerDataMemberCmp(cir::CmpOp op, mlir::Value loweredLhs,
+ mlir::Value loweredRhs,
+ mlir::OpBuilder &builder) const {
+ return cir::CmpOp::create(builder, op.getLoc(), op.getKind(), loweredLhs,
+ loweredRhs);
+}
+
} // namespace cir
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index bb6b44f07e8dd..60143a734d37a 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -2626,9 +2626,6 @@ mlir::LogicalResult CIRToLLVMCmpOpLowering::matchAndRewrite(
mlir::ConversionPatternRewriter &rewriter) const {
mlir::Type type = cmpOp.getLhs().getType();
- assert(!cir::MissingFeatures::dataMemberType());
- assert(!cir::MissingFeatures::methodType());
-
if (mlir::isa<cir::IntType, mlir::IntegerType>(type)) {
bool isSigned = mlir::isa<cir::IntType>(type)
? mlir::cast<cir::IntType>(type).isSigned()
diff --git a/clang/test/CIR/CodeGen/pointer-to-data-member-cmp.cpp b/clang/test/CIR/CodeGen/pointer-to-data-member-cmp.cpp
new file mode 100644
index 0000000000000..482a1aa3938d4
--- /dev/null
+++ b/clang/test/CIR/CodeGen/pointer-to-data-member-cmp.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++17 -fclangir -emit-cir -mmlir -mlir-print-ir-before=cir-cxxabi-lowering %s -o %t.cir 2> %t-before.cir
+// RUN: FileCheck --check-prefix=CIR-BEFORE --input-file=%t-before.cir %s
+// RUN: FileCheck --check-prefix=CIR-AFTER --input-file=%t.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 Foo {
+ int a;
+};
+
+struct Bar {
+ int a;
+};
+
+bool eq(int Foo::*x, int Foo::*y) {
+ return x == y;
+}
+
+// CIR-BEFORE-LABEL: @_Z2eqM3FooiS0_
+// CIR-BEFORE: %[[#x:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.data_member<!s32i in !rec_Foo>>, !cir.data_member<!s32i in !rec_Foo>
+// CIR-BEFORE-NEXT: %[[#y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.data_member<!s32i in !rec_Foo>>, !cir.data_member<!s32i in !rec_Foo>
+// CIR-BEFORE-NEXT: %{{.+}} = cir.cmp(eq, %[[#x]], %[[#y]]) : !cir.data_member<!s32i in !rec_Foo>, !cir.bool
+// CIR-BEFORE: }
+
+// CIR-AFTER-LABEL: @_Z2eqM3FooiS0_
+// CIR-AFTER: %[[#x:]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!s64i>, !s64i
+// CIR-AFTER: %[[#y:]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!s64i>, !s64i
+// CIR-AFTER: %{{.*}} = cir.cmp(eq, %[[#x]], %[[#y]]) : !s64i, !cir.bool
+
+// LLVM-LABEL: @_Z2eqM3FooiS0_
+// LLVM: %[[#x:]] = load i64, ptr %{{.+}}, align 8
+// LLVM-NEXT: %[[#y:]] = load i64, ptr %{{.+}}, align 8
+// LLVM-NEXT: %{{.+}} = icmp eq i64 %[[#x]], %[[#y]]
+// LLVM: }
+
+// OGCG-LABEL: @_Z2eqM3FooiS0_
+// OGCG: %[[#x:]] = load i64, ptr %{{.+}}, align 8
+// OGCG-NEXT: %[[#y:]] = load i64, ptr %{{.+}}, align 8
+// OGCG-NEXT: %{{.+}} = icmp eq i64 %[[#x]], %[[#y]]
+// OGCG: }
+
+bool ne(int Foo::*x, int Foo::*y) {
+ return x != y;
+}
+
+// CIR-BEFORE-LABEL: @_Z2neM3FooiS0_
+// CIR-BEFORE: %[[#x:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.data_member<!s32i in !rec_Foo>>, !cir.data_member<!s32i in !rec_Foo>
+// CIR-BEFORE-NEXT: %[[#y:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.data_member<!s32i in !rec_Foo>>, !cir.data_member<!s32i in !rec_Foo>
+// CIR-BEFORE-NEXT: %{{.+}} = cir.cmp(ne, %[[#x]], %[[#y]]) : !cir.data_member<!s32i in !rec_Foo>, !cir.bool
+// CIR-BEFORE: }
+
+// CIR-AFTER-LABEL: @_Z2neM3FooiS0_
+// CIR-AFTER: %[[#x:]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!s64i>, !s64i
+// CIR-AFTER: %[[#y:]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!s64i>, !s64i
+// CIR-AFTER: %{{.*}} = cir.cmp(ne, %[[#x]], %[[#y]]) : !s64i, !cir.bool
+
+// LLVM-LABEL: @_Z2neM3FooiS0_
+// LLVM: %[[#x:]] = load i64, ptr %{{.+}}, align 8
+// LLVM-NEXT: %[[#y:]] = load i64, ptr %{{.+}}, align 8
+// LLVM-NEXT: %{{.+}} = icmp ne i64 %[[#x]], %[[#y]]
+// LLVM: }
+
+// OGCG-LABEL: @_Z2neM3FooiS0_
+// OGCG: %[[#x:]] = load i64, ptr %{{.+}}, align 8
+// OGCG-NEXT: %[[#y:]] = load i64, ptr %{{.+}}, align 8
+// OGCG-NEXT: %{{.+}} = icmp ne i64 %[[#x]], %[[#y]]
+// OGCG: }
More information about the cfe-commits
mailing list