@@ -103,6 +103,10 @@ class ItaniumCXXABI : public CIRCXXABI {
103103 mlir::Value loweredRhs,
104104 mlir::OpBuilder &builder) const override ;
105105
106+ mlir::Value lowerMethodCmp (cir::CmpOp op, mlir::Value loweredLhs,
107+ mlir::Value loweredRhs,
108+ mlir::OpBuilder &builder) const override ;
109+
106110 mlir::Value lowerDataMemberBitcast (cir::CastOp op, mlir::Type loweredDstTy,
107111 mlir::Value loweredSrc,
108112 mlir::OpBuilder &builder) const override ;
@@ -478,6 +482,61 @@ mlir::Value ItaniumCXXABI::lowerDataMemberCmp(cir::CmpOp op,
478482 loweredRhs);
479483}
480484
485+ mlir::Value ItaniumCXXABI::lowerMethodCmp (cir::CmpOp op, mlir::Value loweredLhs,
486+ mlir::Value loweredRhs,
487+ mlir::OpBuilder &builder) const {
488+ assert (op.getKind () == cir::CmpOpKind::eq ||
489+ op.getKind () == cir::CmpOpKind::ne);
490+
491+ cir::IntType ptrdiffCIRTy = getPtrDiffCIRTy (LM);
492+ mlir::Value ptrdiffZero = builder.create <cir::ConstantOp>(
493+ op.getLoc (), ptrdiffCIRTy, cir::IntAttr::get (ptrdiffCIRTy, 0 ));
494+
495+ mlir::Value lhsPtrField = builder.create <cir::ExtractMemberOp>(
496+ op.getLoc (), ptrdiffCIRTy, loweredLhs, 0 );
497+ mlir::Value rhsPtrField = builder.create <cir::ExtractMemberOp>(
498+ op.getLoc (), ptrdiffCIRTy, loweredRhs, 0 );
499+ mlir::Value ptrCmp = builder.create <cir::CmpOp>(op.getLoc (), op.getKind (),
500+ lhsPtrField, rhsPtrField);
501+ mlir::Value ptrCmpToNull = builder.create <cir::CmpOp>(
502+ op.getLoc (), op.getKind (), lhsPtrField, ptrdiffZero);
503+
504+ mlir::Value lhsAdjField = builder.create <cir::ExtractMemberOp>(
505+ op.getLoc (), ptrdiffCIRTy, loweredLhs, 1 );
506+ mlir::Value rhsAdjField = builder.create <cir::ExtractMemberOp>(
507+ op.getLoc (), ptrdiffCIRTy, loweredRhs, 1 );
508+ mlir::Value adjCmp = builder.create <cir::CmpOp>(op.getLoc (), op.getKind (),
509+ lhsAdjField, rhsAdjField);
510+
511+ // We use cir.select to represent "||" and "&&" operations below:
512+ // - cir.select if %a then %b else false => %a && %b
513+ // - cir.select if %a then true else %b => %a || %b
514+ // TODO: Do we need to invent dedicated "cir.logical_or" and "cir.logical_and"
515+ // operations for this?
516+ auto boolTy = cir::BoolType::get (op.getContext ());
517+ mlir::Value trueValue = builder.create <cir::ConstantOp>(
518+ op.getLoc (), boolTy, cir::BoolAttr::get (op.getContext (), boolTy, true ));
519+ mlir::Value falseValue = builder.create <cir::ConstantOp>(
520+ op.getLoc (), boolTy, cir::BoolAttr::get (op.getContext (), boolTy, false ));
521+ auto create_and = [&](mlir::Value lhs, mlir::Value rhs) {
522+ return builder.create <cir::SelectOp>(op.getLoc (), lhs, rhs, falseValue);
523+ };
524+ auto create_or = [&](mlir::Value lhs, mlir::Value rhs) {
525+ return builder.create <cir::SelectOp>(op.getLoc (), lhs, trueValue, rhs);
526+ };
527+
528+ mlir::Value result;
529+ if (op.getKind () == cir::CmpOpKind::eq) {
530+ // (lhs.ptr == null || lhs.adj == rhs.adj) && lhs.ptr == rhs.ptr
531+ result = create_and (create_or (ptrCmpToNull, adjCmp), ptrCmp);
532+ } else {
533+ // (lhs.ptr != null && lhs.adj != rhs.adj) || lhs.ptr != rhs.ptr
534+ result = create_or (create_and (ptrCmpToNull, adjCmp), ptrCmp);
535+ }
536+
537+ return result;
538+ }
539+
481540mlir::Value
482541ItaniumCXXABI::lowerDataMemberBitcast (cir::CastOp op, mlir::Type loweredDstTy,
483542 mlir::Value loweredSrc,
0 commit comments