================
@@ -55,6 +60,156 @@ namespace mlir {
namespace {
+//===----------------------------------------------------------------------===//
+// x86_64 System V classifier bridge (scalar types)
+//
+// Maps scalar CIR types to llvm::abi::Type, runs the LLVM ABI Lowering
+// Library's SysV x86_64 classifier, and converts the result back into the
+// dialect-agnostic mlir::abi::FunctionClassification that CIRABIRewriteContext
+// consumes. Only integer / pointer / bool / f32 / f64 signatures are handled;
+// aggregates and other leaf types are reported NYI by classifyX86_64 so an
+// unsupported signature fails the pass instead of being misclassified.
+//===----------------------------------------------------------------------===//
+
+/// llvm::Align requires a power of two; DataLayout can report non-power-of-two
+/// alignments for unusual types.
+static llvm::Align safeAlign(uint64_t a) {
+ return llvm::Align(llvm::PowerOf2Ceil(std::max<uint64_t>(a, 1)));
+}
+
+/// The scalar CIR types the x86_64 bridge handles. A regular integer up to
+/// 64 bits, pointer, bool, void, f32, or f64 is a single-register Direct or
+/// Extend argument. `_BitInt`, `__int128`, and wider/other types need
coercion
+/// or indirect passing, which this scalar bridge does not do.
+static bool isSupportedScalarType(mlir::Type ty) {
+ if (isa<cir::VoidType, cir::BoolType, cir::PointerType, cir::SingleType,
+ cir::DoubleType>(ty))
+ return true;
+ if (auto intTy = dyn_cast<cir::IntType>(ty))
+ return !intTy.getIsBitInt() && intTy.getWidth() <= 64;
+ return false;
+}
+
+/// Convert an llvm::abi::Type coercion type back to a scalar CIR type.
+static mlir::Type abiTypeToCIR(const llvm::abi::Type *ty, MLIRContext *ctx) {
+ if (!ty)
+ return nullptr;
+ if (ty->isVoid())
+ return cir::VoidType::get(ctx);
+ if (auto *intTy = llvm::dyn_cast<llvm::abi::IntegerType>(ty))
+ return cir::IntType::get(ctx, intTy->getSizeInBits().getFixedValue(),
+ intTy->isSigned());
+ if (auto *fltTy = llvm::dyn_cast<llvm::abi::FloatType>(ty)) {
+ const llvm::fltSemantics *sem = fltTy->getSemantics();
+ if (sem == &llvm::APFloat::IEEEsingle())
+ return cir::SingleType::get(ctx);
+ if (sem == &llvm::APFloat::IEEEdouble())
+ return cir::DoubleType::get(ctx);
+ }
+ if (llvm::isa<llvm::abi::PointerType>(ty))
+ return cir::PointerType::get(cir::VoidType::get(ctx));
+ return nullptr;
+}
+
+/// Map a scalar CIR type to an llvm::abi::Type. classifyX86_64 pre-filters
the
+/// signature, so only the scalar types handled here can reach this function.
+static const llvm::abi::Type *mapCIRType(mlir::Type type,
+ mlir::abi::ABITypeMapper &typeMapper,
+ const DataLayout &dl) {
+ llvm::abi::TypeBuilder &tb = typeMapper.getTypeBuilder();
+ if (auto intTy = dyn_cast<cir::IntType>(type))
+ return tb.getIntegerType(intTy.getWidth(),
+ safeAlign(dl.getTypeABIAlignment(type)),
+ intTy.isSigned());
+ if (isa<cir::PointerType>(type))
+ return tb.getPointerType(dl.getTypeSizeInBits(type),
+ safeAlign(dl.getTypeABIAlignment(type)),
+ /*AddressSpace=*/0);
+ if (isa<cir::BoolType>(type))
+ return tb.getIntegerType(dl.getTypeSizeInBits(type),
+ safeAlign(dl.getTypeABIAlignment(type)),
+ /*Signed=*/false);
+ if (isa<cir::VoidType>(type))
+ return tb.getVoidType();
+ if (isa<cir::SingleType>(type))
+ return tb.getFloatType(llvm::APFloat::IEEEsingle(),
+ safeAlign(dl.getTypeABIAlignment(type)));
+ if (isa<cir::DoubleType>(type))
+ return tb.getFloatType(llvm::APFloat::IEEEdouble(),
+ safeAlign(dl.getTypeABIAlignment(type)));
+ llvm_unreachable("mapCIRType: type not pre-filtered by classifyX86_64");
+}
+
+/// Convert an llvm::abi::ArgInfo for a scalar type into the ArgClassification
+/// consumed by CIRABIRewriteContext.
+static ArgClassification convertABIArgInfo(const llvm::abi::ArgInfo &info,
+ MLIRContext *ctx,
+ mlir::Type origTy) {
+ if (info.isDirect())
+ return ArgClassification::getDirect(nullptr);
+ if (info.isExtend()) {
+ if (origTy && isa<cir::BoolType>(origTy))
+ return ArgClassification::getExtend(nullptr, info.isSignExt());
+ if (origTy && !isa<cir::IntType>(origTy))
+ return ArgClassification::getDirect(nullptr);
----------------
adams381 wrote:
This was guarding against an Extend classification for something that
isn't bool or int, like a pointer or float. It can't actually happen:
every `ArgInfo::getExtend` call site in X86.cpp/BPF.cpp is gated on the
operand being an integer. Replaced with an assert since the case is
unreachable.
https://github.com/llvm/llvm-project/pull/209636
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits