================ @@ -68,20 +168,70 @@ static cir::CIRCallOpInterface emitCallLikeOp(CIRGenFunction &cgf, assert(builder.getInsertionBlock() && "expected valid basic block"); assert(!cir::MissingFeatures::opCallIndirect()); - return builder.createCallOp(callLoc, directFuncOp); + return builder.createCallOp(callLoc, directFuncOp, cirCallArgs); } RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, + const CallArgList &args, cir::CIRCallOpInterface *callOp, mlir::Location loc) { QualType retTy = funcInfo.getReturnType(); const cir::ABIArgInfo &retInfo = funcInfo.getReturnInfo(); - assert(!cir::MissingFeatures::opCallArgs()); + ClangToCIRArgMapping cirFuncArgs(cgm.getASTContext(), funcInfo); + SmallVector<mlir::Value, 16> cirCallArgs(cirFuncArgs.totalCIRArgs()); + assert(!cir::MissingFeatures::emitLifetimeMarkers()); + // Translate all of the arguments as necessary to match the CIR lowering. + assert(funcInfo.arg_size() == args.size() && + "Mismatch between function signature & arguments."); + unsigned argNo = 0; + const auto *infoIter = funcInfo.arg_begin(); + for (auto i = args.begin(), e = args.end(); i != e; + ++i, ++infoIter, ++argNo) { + const cir::ABIArgInfo &argInfo = infoIter->info; + + // Insert a padding argument to ensure proper alignment. + assert(!cir::MissingFeatures::opCallPaddingArgs()); + + unsigned firstCIRArg; + unsigned numCIRArgs; + std::tie(firstCIRArg, numCIRArgs) = cirFuncArgs.getCIRArgs(argNo); + + switch (argInfo.getKind()) { + case cir::ABIArgInfo::Direct: { + if (!mlir::isa<cir::RecordType>(argInfo.getCoerceToType()) && + argInfo.getCoerceToType() == convertType(infoIter->type) && + argInfo.getDirectOffset() == 0) { + assert(numCIRArgs == 1); + assert(!cir::MissingFeatures::opCallAggregateArgs()); + mlir::Value v = i->getKnownRValue().getScalarVal(); + + assert(!cir::MissingFeatures::opCallExtParameterInfo()); + + // We might have to widen integers, but we should never truncate. + assert(!cir::MissingFeatures::opCallWidenArg()); + + // If the argument doesn't match, perform a bitcast to coerce it. This + // can happen due to trivial type mismatches. + assert(!cir::MissingFeatures::opCallBitcastArg()); ---------------- andykaylor wrote:
So the question is when we should perform calling convention lowering? Is this another of those things that we'll want to change in the incubator first? I haven't done much work on code that is consuming CIR, but my gut feel is that it would be best to have an initial state that represents the calls just as they are, without changing any of the types to meet ABI requirements, but I'd want there to be something in the CIR that clearly indicated that we were in that state and prevented some other transformation from casually lowering the call to a different dialect without knowing that the calling convention lowering was necessary. CC lowering should be required to get anything lowered to another dialect, unless that dialect also handles ABI and calling convention issues. https://github.com/llvm/llvm-project/pull/136810 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits