================
@@ -2503,6 +2503,125 @@ mlir::LogicalResult 
CIRToLLVMCmpOpLowering::matchAndRewrite(
   return cmpOp.emitError() << "unsupported type for CmpOp: " << type;
 }
 
+mlir::LogicalResult CIRToLLVMBinOpOverflowOpLowering::matchAndRewrite(
+    cir::BinOpOverflowOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  mlir::Location loc = op.getLoc();
+  cir::BinOpOverflowKind arithKind = op.getKind();
+  cir::IntType operandTy = op.getLhs().getType();
+  cir::IntType resultTy = op.getResult().getType();
+
+  EncompassedTypeInfo encompassedTyInfo =
+      computeEncompassedTypeWidth(operandTy, resultTy);
+  mlir::IntegerType encompassedLLVMTy =
+      rewriter.getIntegerType(encompassedTyInfo.width);
+
+  mlir::Value lhs = adaptor.getLhs();
+  mlir::Value rhs = adaptor.getRhs();
+  if (operandTy.getWidth() < encompassedTyInfo.width) {
+    if (operandTy.isSigned()) {
+      lhs = mlir::LLVM::SExtOp::create(rewriter, loc, encompassedLLVMTy, lhs);
+      rhs = mlir::LLVM::SExtOp::create(rewriter, loc, encompassedLLVMTy, rhs);
+    } else {
+      lhs = mlir::LLVM::ZExtOp::create(rewriter, loc, encompassedLLVMTy, lhs);
+      rhs = mlir::LLVM::ZExtOp::create(rewriter, loc, encompassedLLVMTy, rhs);
+    }
+  }
+
+  std::string intrinName = getLLVMIntrinName(
+      arithKind, encompassedTyInfo.sign, encompassedTyInfo.width);
+  mlir::StringAttr intrinNameAttr =
+      mlir::StringAttr::get(op.getContext(), intrinName);
+
+  mlir::IntegerType overflowLLVMTy = rewriter.getI1Type();
+  mlir::LLVM::LLVMStructType intrinRetTy =
+      mlir::LLVM::LLVMStructType::getLiteral(
+          rewriter.getContext(), {encompassedLLVMTy, overflowLLVMTy});
+
+  mlir::LLVM::CallIntrinsicOp callLLVMIntrinOp =
+      mlir::LLVM::CallIntrinsicOp::create(rewriter, loc, intrinRetTy,
+                                          intrinNameAttr, 
mlir::ValueRange{lhs, rhs});
+  mlir::Value intrinRet = callLLVMIntrinOp.getResult(0);
+
+  mlir::Value result =
+      mlir::LLVM::ExtractValueOp::create(rewriter, loc, intrinRet,
+                                         ArrayRef<int64_t>{0})
+          .getResult();
+  mlir::Value overflow =
+      mlir::LLVM::ExtractValueOp::create(rewriter, loc, intrinRet,
+                                         ArrayRef<int64_t>{1})
+          .getResult();
+
+  if (resultTy.getWidth() < encompassedTyInfo.width) {
+    mlir::Type resultLLVMTy = getTypeConverter()->convertType(resultTy);
+    mlir::Value truncResult =
+        mlir::LLVM::TruncOp::create(rewriter, loc, resultLLVMTy, result);
+
+    // Extend the truncated result back to the encompassing type to check for
+    // any overflows during the truncation.
+    mlir::Value truncResultExt;
+    if (resultTy.isSigned())
+      truncResultExt = mlir::LLVM::SExtOp::create(rewriter, loc,
+                                                  encompassedLLVMTy, 
truncResult);
+    else
+      truncResultExt = mlir::LLVM::ZExtOp::create(rewriter, loc,
+                                                  encompassedLLVMTy, 
truncResult);
+    mlir::Value truncOverflow =
+        mlir::LLVM::ICmpOp::create(rewriter, loc, 
mlir::LLVM::ICmpPredicate::ne,
+                                   truncResultExt, result);
----------------
xlauko wrote:

```suggestion
    auto truncOverflow =
        mlir::LLVM::ICmpOp::create(rewriter, loc, mlir::LLVM::ICmpPredicate::ne,
                                   truncResultExt, result);
```

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