================
@@ -1473,3 +1425,255 @@ void
CIRABIRewriteContext::rewriteFunctionAddress(cir::GetGlobalOp addrOp,
cir::CastKind::bitcast, addrOp.getAddr());
addrOp.getAddr().replaceAllUsesExcept(bitcast.getResult(), bitcast);
}
+
+mlir::LogicalResult
+CIRABIRewriteContext::rewriteVAArg(mlir::Operation *vaArgOp,
+ const ArgClassification &ac,
+ mlir::OpBuilder &opBuilder) {
+ auto op = mlir::cast<cir::VAArgOp>(vaArgOp);
+ CIRBaseBuilderTy builder(opBuilder);
+ mlir::Location loc = op.getLoc();
+ mlir::Type resultTy = op.getType();
+ mlir::Value valist = op.getArgList();
+
+ auto reportNYI = [&](llvm::StringRef what) {
+ op->emitOpError() << "va_arg of " << what
+ << " not yet implemented in CallConvLowering";
+ return mlir::failure();
+ };
+
+ // An ignored type is passed in no register and no stack slot, so the fetch
+ // has nothing to read and must leave the va_list cursor where it found it,
+ // for the fetches that come after this one. The type holds no bytes, so
+ // the value the fetch produces carries no information either.
+ if (ac.kind == ArgKind::Ignore) {
+ builder.setInsertionPoint(op);
+ op.getResult().replaceAllUsesWith(builder.createDummyValue(
+ loc, resultTy,
+ clang::CharUnits::fromQuantity(dl.getTypeABIAlignment(resultTy))));
+ op->erase();
+ return mlir::success();
+ }
+
+ if (ac.kind == ArgKind::Indirect && !ac.byVal)
+ return reportNYI("a non-trivially-copyable type");
+
+ // How many eightbytes of each register class the fetched type occupies.
+ // Zero of both means the type travels in memory and is read straight from
+ // the overflow area.
+ unsigned neededInt = 0, neededSse = 0;
+ // Which coerced-pair element (0 = low eightbyte, 1 = high) is SSE rather
+ // than INTEGER class. Only meaningful when isRegPair is set.
+ std::array<bool, 2> pairIsSse = {false, false};
+ bool isRegPair = false;
+
+ if (ac.kind == ArgKind::Extend) {
+ neededInt = 1;
+ } else if (ac.kind == ArgKind::Direct) {
+ if (mlir::Type coerced = ac.coercedType) {
+ if (auto pairTy = mlir::dyn_cast<cir::RecordType>(coerced)) {
+ assert(pairTy.getNumElements() == 2 &&
+ "a register-class coercion spans at most two eightbytes");
+ for (auto [i, memberTy] : llvm::enumerate(pairTy.getMembers())) {
+ if (isSSERegisterClass(memberTy)) {
+ pairIsSse[i] = true;
+ ++neededSse;
+ } else {
+ ++neededInt;
+ }
+ }
+ isRegPair = true;
+ } else if (isSSERegisterClass(coerced)) {
+ if (fitsOneVectorSlot(coerced, dl))
+ neededSse = 1;
----------------
adams381 wrote:
Memory, through the overflow arm. The helper is deleted now. The classifier
reports no registers for such a vector, and the fetch reads that as memory,
which is the same answer without the guesswork.
https://github.com/llvm/llvm-project/pull/222420
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits