diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 6b718f923f3c..1aeb03f90b61 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -2278,6 +2278,36 @@ class CIRBitClrsbOpLowering } }; +class CIRObjSizeOpLowering + : public mlir::OpConversionPattern { +public: + using OpConversionPattern::OpConversionPattern; + + mlir::LogicalResult + matchAndRewrite(mlir::cir::ObjSizeOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const override { + auto llvmResTy = getTypeConverter()->convertType(op.getType()); + auto loc = op->getLoc(); + + auto llvmIntrinNameAttr = + mlir::StringAttr::get(rewriter.getContext(), "llvm.objectsize"); + mlir::cir::SizeInfoType kindInfo = op.getKind(); + auto falseValue = rewriter.create( + loc, rewriter.getI1Type(), false); + auto trueValue = rewriter.create( + loc, rewriter.getI1Type(), true); + + rewriter.replaceOpWithNewOp( + op, llvmResTy, llvmIntrinNameAttr, + mlir::ValueRange{adaptor.getPtr(), + kindInfo == mlir::cir::SizeInfoType::max ? falseValue + : trueValue, + trueValue, op.getDynamic() ? trueValue : falseValue}); + + return mlir::LogicalResult::success(); + } +}; + class CIRBitClzOpLowering : public mlir::OpConversionPattern { public: @@ -3024,8 +3054,8 @@ void populateCIRToLLVMConversionPatterns(mlir::RewritePatternSet &patterns, CIRVectorShuffleVecLowering, CIRStackSaveLowering, CIRStackRestoreLowering, CIRUnreachableLowering, CIRTrapLowering, CIRInlineAsmOpLowering, CIRSetBitfieldLowering, CIRGetBitfieldLowering, - CIRPrefetchLowering, CIRIsConstantOpLowering>(converter, - patterns.getContext()); + CIRPrefetchLowering, CIRObjSizeOpLowering, CIRIsConstantOpLowering>( + converter, patterns.getContext()); } namespace { diff --git a/clang/test/CIR/CodeGen/pass-object-size.c b/clang/test/CIR/CodeGen/pass-object-size.c new file mode 100644 index 000000000000..909802d522b8 --- /dev/null +++ b/clang/test/CIR/CodeGen/pass-object-size.c @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir-enable -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir-enable -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM +void b(void *__attribute__((pass_object_size(0)))); +void e(void *__attribute__((pass_object_size(2)))); +void c() { + int a; + int d[a]; + b(d); + e(d); +} + +// CIR: cir.func no_proto @c() +// CIR: [[TMP0:%.*]] = cir.alloca !s32i, cir.ptr , %{{[0-9]+}} : !u64i, ["vla"] {alignment = 16 : i64} +// CIR: [[TMP1:%.*]] = cir.cast(bitcast, [[TMP0]] : !cir.ptr), !cir.ptr +// CIR-NEXT: [[TMP2:%.*]] = cir.objsize([[TMP1]] : , max) -> !u64i +// CIR-NEXT: cir.call @b([[TMP1]], [[TMP2]]) : (!cir.ptr, !u64i) -> () +// CIR: [[TMP3:%.*]] = cir.cast(bitcast, [[TMP0]] : !cir.ptr), !cir.ptr +// CIR: [[TMP4:%.*]] = cir.objsize([[TMP3]] : , min) -> !u64i +// CIR-NEXT: cir.call @e([[TMP3]], [[TMP4]]) : (!cir.ptr, !u64i) -> () + +// LLVM: define void @c() +// LLVM: [[TMP0:%.*]] = alloca i32, i64 %{{[0-9]+}}, +// LLVM: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 false), +// LLVM-NEXT: call void @b(ptr [[TMP0]], i64 [[TMP1]]) +// LLVM: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 true, i1 true, i1 false), +// LLVM-NEXT: call void @e(ptr [[TMP0]], i64 [[TMP2]])