@@ -103,6 +103,10 @@ class ItaniumCXXABI : public CIRCXXABI {
103
103
mlir::Value loweredRhs,
104
104
mlir::OpBuilder &builder) const override ;
105
105
106
+ mlir::Value lowerMethodCmp (cir::CmpOp op, mlir::Value loweredLhs,
107
+ mlir::Value loweredRhs,
108
+ mlir::OpBuilder &builder) const override ;
109
+
106
110
mlir::Value lowerDataMemberBitcast (cir::CastOp op, mlir::Type loweredDstTy,
107
111
mlir::Value loweredSrc,
108
112
mlir::OpBuilder &builder) const override ;
@@ -478,6 +482,61 @@ mlir::Value ItaniumCXXABI::lowerDataMemberCmp(cir::CmpOp op,
478
482
loweredRhs);
479
483
}
480
484
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
+
481
540
mlir::Value
482
541
ItaniumCXXABI::lowerDataMemberBitcast (cir::CastOp op, mlir::Type loweredDstTy,
483
542
mlir::Value loweredSrc,
0 commit comments