diff options
Diffstat (limited to 'clang/lib/CIR/Lowering')
-rw-r--r-- | clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 69 |
1 files changed, 66 insertions, 3 deletions
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 3abba3d..0243bf1 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 { @@ -1539,6 +1587,7 @@ void CIRToLLVMFuncOpLowering::lowerFuncAttributes( attr.getName() == getLinkageAttrNameString() || attr.getName() == func.getGlobalVisibilityAttrName() || attr.getName() == func.getDsoLocalAttrName() || + attr.getName() == func.getInlineKindAttrName() || (filterArgAndResAttrs && (attr.getName() == func.getArgAttrsAttrName() || attr.getName() == func.getResAttrsAttrName()))) @@ -1623,6 +1672,12 @@ mlir::LogicalResult CIRToLLVMFuncOpLowering::matchAndRewrite( assert(!cir::MissingFeatures::opFuncMultipleReturnVals()); + if (auto inlineKind = op.getInlineKind()) { + fn.setNoInline(inlineKind == cir::InlineKind::NoInline); + fn.setInlineHint(inlineKind == cir::InlineKind::InlineHint); + fn.setAlwaysInline(inlineKind == cir::InlineKind::AlwaysInline); + } + fn.setVisibility_Attr(mlir::LLVM::VisibilityAttr::get( getContext(), lowerCIRVisibilityToLLVMVisibility( op.getGlobalVisibilityAttr().getValue()))); @@ -1793,12 +1848,20 @@ CIRToLLVMGlobalOpLowering::getComdatAttr(cir::GlobalOp &op, if (!comdatOp) { builder.setInsertionPointToStart(module.getBody()); comdatOp = - builder.create<mlir::LLVM::ComdatOp>(module.getLoc(), comdatName); + mlir::LLVM::ComdatOp::create(builder, module.getLoc(), comdatName); + } + + if (auto comdatSelector = comdatOp.lookupSymbol<mlir::LLVM::ComdatSelectorOp>( + op.getSymName())) { + return mlir::SymbolRefAttr::get( + builder.getContext(), comdatName, + mlir::FlatSymbolRefAttr::get(comdatSelector.getSymNameAttr())); } builder.setInsertionPointToStart(&comdatOp.getBody().back()); - auto selectorOp = builder.create<mlir::LLVM::ComdatSelectorOp>( - comdatOp.getLoc(), op.getSymName(), mlir::LLVM::comdat::Comdat::Any); + auto selectorOp = mlir::LLVM::ComdatSelectorOp::create( + builder, comdatOp.getLoc(), op.getSymName(), + mlir::LLVM::comdat::Comdat::Any); return mlir::SymbolRefAttr::get( builder.getContext(), comdatName, mlir::FlatSymbolRefAttr::get(selectorOp.getSymNameAttr())); |