================
@@ -502,6 +530,154 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
     cir::PrefetchOp::create(builder, loc, address, locality, isWrite);
     return RValue::get(nullptr);
   }
+  case Builtin::BI__builtin_add_overflow:
+  case Builtin::BI__builtin_sub_overflow:
+  case Builtin::BI__builtin_mul_overflow: {
+    const clang::Expr *LeftArg = e->getArg(0);
+    const clang::Expr *RightArg = e->getArg(1);
+    const clang::Expr *ResultArg = e->getArg(2);
+
+    clang::QualType ResultQTy =
+        ResultArg->getType()->castAs<clang::PointerType>()->getPointeeType();
+
+    WidthAndSignedness LeftInfo =
+        getIntegerWidthAndSignedness(cgm.getASTContext(), LeftArg->getType());
+    WidthAndSignedness RightInfo =
+        getIntegerWidthAndSignedness(cgm.getASTContext(), RightArg->getType());
+    WidthAndSignedness ResultInfo =
+        getIntegerWidthAndSignedness(cgm.getASTContext(), ResultQTy);
+
+    // Note we compute the encompassing type with the consideration to the
+    // result type, so later in LLVM lowering we don't get redundant integral
+    // extension casts.
+    WidthAndSignedness EncompassingInfo =
+        EncompassingIntegerType({LeftInfo, RightInfo, ResultInfo});
+
+    auto EncompassingCIRTy = cir::IntType::get(
+        &getMLIRContext(), EncompassingInfo.width, EncompassingInfo.isSigned);
+    auto ResultCIRTy = mlir::cast<cir::IntType>(cgm.convertType(ResultQTy));
+
+    mlir::Value Left = emitScalarExpr(LeftArg);
+    mlir::Value Right = emitScalarExpr(RightArg);
+    Address ResultPtr = emitPointerWithAlignment(ResultArg);
+
+    // Extend each operand to the encompassing type, if necessary.
+    if (Left.getType() != EncompassingCIRTy)
+      Left =
+          builder.createCast(cir::CastKind::integral, Left, EncompassingCIRTy);
+    if (Right.getType() != EncompassingCIRTy)
+      Right =
+          builder.createCast(cir::CastKind::integral, Right, 
EncompassingCIRTy);
+
+    // Perform the operation on the extended values.
+    cir::BinOpOverflowKind OpKind;
+    switch (builtinID) {
+    default:
+      llvm_unreachable("Unknown overflow builtin id.");
+    case Builtin::BI__builtin_add_overflow:
+      OpKind = cir::BinOpOverflowKind::Add;
+      break;
+    case Builtin::BI__builtin_sub_overflow:
+      OpKind = cir::BinOpOverflowKind::Sub;
+      break;
+    case Builtin::BI__builtin_mul_overflow:
+      OpKind = cir::BinOpOverflowKind::Mul;
+      break;
+    }
+
+    auto Loc = getLoc(e->getSourceRange());
+    cir::BinOpOverflowOp ArithOp =
+        cir::BinOpOverflowOp::create(builder, Loc, ResultCIRTy, OpKind, Left, 
Right);
----------------
andykaylor wrote:

```suggestion
    auto arithOp =
        cir::BinOpOverflowOp::create(builder, Loc, ResultCIRTy, OpKind, Left, 
Right);
```
auto is ok here now that you're using the type's create call directly.

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

Reply via email to