[clang] [CIR] Accept _BitInt up to 128 bits in x86_64 callconv lowering (PR #212668)

Adam Smith via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 30 11:46:53 PDT 2026


================
@@ -272,14 +277,36 @@ static std::optional<ArgClassification>
 convertABIArgInfo(const llvm::abi::ArgInfo &info, MLIRContext *ctx,
                   mlir::Type origTy) {
   if (info.isDirect()) {
-    // A scalar passes as-is; only an aggregate carries a coercion type.
-    if (!origTy || !isa<cir::RecordType, cir::ArrayType>(origTy))
+    // A non-null coerce type does not by itself mean the value needs a rewrite:
+    // the classifier names one even where it matches the natural type.  Three
+    // cases do need one: an aggregate must be unpacked into the register(s)
+    // holding it, a multi-register tuple coerce must be flattened into one
+    // argument per field, and a scalar the classifier widened must travel in
+    // the wider type.  Any other scalar keeps its natural CIR type, which a
+    // null coercion denotes here.  Keeping it off the abiTypeToCIR path is
+    // also what preserves its ABI alignment: that mapping does not carry the
+    // bit-precise flag.  A _BitInt(128) coerces to the bit-precise integer
+    // itself, so routing it through would produce a plain !cir.int<s, 128>
+    // with __int128's 16-byte alignment instead of 8.
+    const llvm::abi::Type *coerceAbi = info.getCoerceToType();
+    bool isAggregate = origTy && isa<cir::RecordType, cir::ArrayType>(origTy);
+    bool coerceIsRegisterTuple =
+        coerceAbi && isa<llvm::abi::RecordType>(coerceAbi);
----------------
adams381 wrote:

`isa_and_nonnull` is a wrapper that forwards to `isa_and_present`, which is what both lines use now.

```c++
template <typename... X, class Y>
[[nodiscard]] inline bool isa_and_nonnull(const Y &Val) {
  return isa_and_present<X...>(Val);
}
```

https://github.com/llvm/llvm-project/pull/212668


More information about the cfe-commits mailing list