aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp6
-rw-r--r--clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp48
2 files changed, 51 insertions, 3 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 637f9ef..138082b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1734,9 +1734,9 @@ mlir::Value ScalarExprEmitter::emitSub(const BinOpInfo &ops) {
// LLVM we shall take VLA's, division by element size, etc.
//
// See more in `EmitSub` in CGExprScalar.cpp.
- assert(!cir::MissingFeatures::ptrDiffOp());
- cgf.cgm.errorNYI("ptrdiff");
- return {};
+ assert(!cir::MissingFeatures::llvmLoweringPtrDiffConsidersPointee());
+ return cir::PtrDiffOp::create(builder, cgf.getLoc(ops.loc), cgf.PtrDiffTy,
+ ops.lhs, ops.rhs);
}
mlir::Value ScalarExprEmitter::emitShl(const BinOpInfo &ops) {
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index e61b65f..1fc98ec 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1499,6 +1499,54 @@ mlir::LogicalResult CIRToLLVMConstantOpLowering::matchAndRewrite(
return mlir::success();
}
+static uint64_t getTypeSize(mlir::Type type, mlir::Operation &op) {
+ mlir::DataLayout layout(op.getParentOfType<mlir::ModuleOp>());
+ // For LLVM purposes we treat void as u8.
+ if (isa<cir::VoidType>(type))
+ type = cir::IntType::get(type.getContext(), 8, /*isSigned=*/false);
+ return llvm::divideCeil(layout.getTypeSizeInBits(type), 8);
+}
+
+mlir::LogicalResult CIRToLLVMPtrDiffOpLowering::matchAndRewrite(
+ cir::PtrDiffOp op, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ auto dstTy = mlir::cast<cir::IntType>(op.getType());
+ mlir::Type llvmDstTy = getTypeConverter()->convertType(dstTy);
+
+ auto lhs = rewriter.create<mlir::LLVM::PtrToIntOp>(op.getLoc(), llvmDstTy,
+ adaptor.getLhs());
+ auto rhs = rewriter.create<mlir::LLVM::PtrToIntOp>(op.getLoc(), llvmDstTy,
+ adaptor.getRhs());
+
+ auto diff =
+ rewriter.create<mlir::LLVM::SubOp>(op.getLoc(), llvmDstTy, lhs, rhs);
+
+ cir::PointerType ptrTy = op.getLhs().getType();
+ assert(!cir::MissingFeatures::llvmLoweringPtrDiffConsidersPointee());
+ uint64_t typeSize = getTypeSize(ptrTy.getPointee(), *op);
+
+ // Avoid silly division by 1.
+ mlir::Value resultVal = diff.getResult();
+ if (typeSize != 1) {
+ auto typeSizeVal = rewriter.create<mlir::LLVM::ConstantOp>(
+ op.getLoc(), llvmDstTy, typeSize);
+
+ if (dstTy.isUnsigned()) {
+ auto uDiv =
+ rewriter.create<mlir::LLVM::UDivOp>(op.getLoc(), diff, typeSizeVal);
+ uDiv.setIsExact(true);
+ resultVal = uDiv.getResult();
+ } else {
+ auto sDiv =
+ rewriter.create<mlir::LLVM::SDivOp>(op.getLoc(), diff, typeSizeVal);
+ sDiv.setIsExact(true);
+ resultVal = sDiv.getResult();
+ }
+ }
+ rewriter.replaceOp(op, resultVal);
+ return mlir::success();
+}
+
mlir::LogicalResult CIRToLLVMExpectOpLowering::matchAndRewrite(
cir::ExpectOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {