clangir icon indicating copy to clipboard operation
clangir copied to clipboard

Use @llvm.memcpy.p0.p0.i64 instead of @llvm.memcpy.p0.p0.i32

Open bcardosolopes opened this issue 1 year ago • 14 comments

See clang/test/CIR/Lowering/store-memcpy.cpp.

Brief search in mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td indicates there isn't a way to get it via the default operation, but I see mlir/test/Target/LLVMIR/omptarget-depend.mlir generates it, perhaps they generate a direct call?

bcardosolopes avatar Oct 30 '24 23:10 bcardosolopes

I will spend some time on it..

liusy58 avatar Nov 03 '24 02:11 liusy58

I found the error..

class CIRCopyOpLowering : public mlir::OpConversionPattern<cir::CopyOp> {
public:
  using mlir::OpConversionPattern<cir::CopyOp>::OpConversionPattern;

  mlir::LogicalResult
  matchAndRewrite(cir::CopyOp op, OpAdaptor adaptor,
                  mlir::ConversionPatternRewriter &rewriter) const override {
    const mlir::Value length = rewriter.create<mlir::LLVM::ConstantOp>(
        op.getLoc(), rewriter.getI32Type(), op.getLength());
    rewriter.replaceOpWithNewOp<mlir::LLVM::MemcpyOp>(
        op, adaptor.getDst(), adaptor.getSrc(), length, op.getIsVolatile());
    return mlir::success();
  }
};

rewriter.getI32Type() directly define the type as int32.

liusy58 avatar Nov 21 '24 06:11 liusy58

Not sure that using rewriter.getI64Type() will solve this issue without leading to other errors. But I will try to run all tests later.

liusy58 avatar Nov 21 '24 06:11 liusy58

@liusy58 good point, perhaps passing the type as i64 is enough to trigger the right type (we probably just need to figure out a rule of which one to use based on the CIR type in question)

bcardosolopes avatar Nov 22 '24 20:11 bcardosolopes

@bcardosolopes Sorry for my late response. I don't understand what you mean by saying we probably just need to figure out a rule of which one to use based on the CIR type in question. Could you please give more details?

liusy58 avatar Nov 24 '24 07:11 liusy58

Could you please give more details?

My point is that sometimes it's not clear if we should generate i32 or i64 (e.g. for arrays it might use i32 and for structs i64, or the other way around - I don't remember, just one possible example). It's possible OG codegen does something that doesn't rely on the original type to decide, we'll need to figure out if right now we already have all the information to emit the right size or if we need to add more information to CIR operations. Does that make sense?

bcardosolopes avatar Nov 25 '24 21:11 bcardosolopes

Thank you. I will check later. By the way, what is OG codegen?

liusy58 avatar Nov 26 '24 02:11 liusy58

The original LLVM codegen in lib/CodeGen

bcardosolopes avatar Nov 26 '24 04:11 bcardosolopes

Thank you! Sorry for my slow response. But I will try to figure out this issue.

liusy58 avatar Nov 27 '24 01:11 liusy58

@liusy58 assigned a few of the issues to you just to keep track, feel free to remove it!

bcardosolopes avatar Nov 27 '24 23:11 bcardosolopes

in LLVMIntrinsicConversions.inc (which is generated by llvm I guess?)

if (auto op = dyn_cast<::mlir::LLVM::MemcpyOp>(opInst)) {

    auto *inst = LLVM::detail::createIntrinsicCall(
      builder, moduleTranslation, &opInst, llvm::Intrinsic::memcpy,0,{},{0, 1, 2},{3},{StringLiteral("isVolatile")});
    (void) inst;
    
    moduleTranslation.setAccessGroupsMetadata(op, inst);
  
    moduleTranslation.setAliasScopeMetadata(op, inst);
    moduleTranslation.setTBAAMetadata(op, inst);
  
  return success();
}

Image

llvm.memcpy.p0.p0.i32 is generated by combing the types of operands https://github.com/llvm/clangir/blob/main/llvm/lib/IR/Intrinsics.cpp#L168. As we said before, rewriter.getI32Type() directly define the type as int32.

I try to use rewriter.getI64Type(), but some tests will fail.

liusy58 avatar Nov 28 '24 03:11 liusy58

I try to use rewriter.getI64Type(), but some tests will fail.

Possible reasons:

  • They fail because they were wrong and testing the wrong thing (i.e. they were not matching OG). If that's the case, just change the test to check for what it now should.
  • They fail because you need to add more logic to account for corner cases.

You seem to be going the right direction though :)

bcardosolopes avatar Dec 06 '24 19:12 bcardosolopes

I think I figured out the problem. https://github.com/llvm/clangir/blob/c69469e4d8219e3202d7055106c6b692a9076564/clang/lib/CodeGen/CGDecl.cpp#L1185 OG uses CGM.IntPtrTy as the type of size. If changing to CGM.Int32Ty, the result will match. However, I haven't figured out how to fix the problem.

FantasqueX avatar Feb 18 '25 03:02 FantasqueX

I haven't figured out how to fix the problem.

Any specific thing you need help understanding? let me know if you have extra questions

bcardosolopes avatar Feb 20 '25 21:02 bcardosolopes