Author: Nikita Popov Date: 2026-06-23T09:08:30+02:00 New Revision: c1bc84866a5ada0ec12c810ca42b381b776d198a
URL: https://github.com/llvm/llvm-project/commit/c1bc84866a5ada0ec12c810ca42b381b776d198a DIFF: https://github.com/llvm/llvm-project/commit/c1bc84866a5ada0ec12c810ca42b381b776d198a.diff LOG: [Clang][ABI] Validate consistency between ABI lowering implementation (#203281) If the LLVM ABI library is used, and assertions are enabled, compute the ABI both using Clang's implementation the the LLVM ABI library, and verify that the results are the same. Added: Modified: clang/lib/CodeGen/CGCall.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 82b374e50fd41..c4cd66d14f1dd 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -832,6 +832,32 @@ void computeSPIRKernelABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI); } // namespace CodeGen } // namespace clang +#ifndef NDEBUG +static const char *abiKindToString(ABIArgInfo::Kind K) { + switch (K) { + case ABIArgInfo::Direct: + return "Direct"; + case ABIArgInfo::Extend: + return "Extend"; + case ABIArgInfo::Indirect: + return "Indirect"; + case ABIArgInfo::IndirectAliased: + return "IndirectAliased"; + case ABIArgInfo::Ignore: + return "Ignore"; + case ABIArgInfo::Expand: + return "Expand"; + case ABIArgInfo::CoerceAndExpand: + return "CoerceAndExpand"; + case ABIArgInfo::TargetSpecific: + return "TargetSpecific"; + case ABIArgInfo::InAlloca: + return "InAlloca"; + } + llvm_unreachable("Unknown kind"); +} +#endif + void CodeGenModule::computeABIInfoUsingLib(CGFunctionInfo &FI) { SmallVector<const llvm::abi::Type *> MappedArgTypes; MappedArgTypes.reserve(FI.arg_size()); @@ -849,12 +875,100 @@ void CodeGenModule::computeABIInfoUsingLib(CGFunctionInfo &FI) { getLLVMABITargetInfo(AbiMapper->getTypeBuilder()).computeInfo(*AbiFI); - FI.getReturnInfo() = - convertABIArgInfo(AbiFI->getReturnInfo(), FI.getReturnType()); +#ifndef NDEBUG + // With assertions enabled, also compute info using Clang ABI logic, + // so we can ensure the results are consistent. + getABIInfo().computeInfo(FI); + + auto ConvertABIArgInfo = [&](ABIArgInfo &Target, + const llvm::abi::ArgInfo &AbiInfo, QualType Type, + int ArgNo) { + auto Check = [&](bool Cond, llvm::function_ref<void()> MessageFn) { + if (Cond) + return; + if (ArgNo == -1) + llvm::dbgs() << "For return value of type "; + else + llvm::dbgs() << "For argument " << ArgNo << " of type "; + llvm::dbgs() << Type << ": "; + MessageFn(); + llvm::dbgs() << "\n"; + abort(); + }; + auto CheckSimple = [&](auto TargetVal, auto ResVal, StringRef What) { + Check(TargetVal == ResVal, [&]() { + llvm::dbgs() << What << " mismatch (expected: " << TargetVal + << ", given: " << ResVal << ")"; + }); + }; + + ABIArgInfo Res = convertABIArgInfo(AbiInfo, Type); + Check(Target.getKind() == Res.getKind(), [&]() { + llvm::dbgs() << "Kind mismatch (expected: " + << abiKindToString(Target.getKind()) + << ", given: " << abiKindToString(Res.getKind()) << ")"; + }); + + if (Res.canHaveCoerceToType()) { + // Normalize nullptr types. + llvm::Type *TargetType = Target.getCoerceToType(); + llvm::Type *ResType = Res.getCoerceToType(); + if (!TargetType) + TargetType = getTypes().ConvertType(Type); + if (!ResType) + ResType = getTypes().ConvertType(Type); + + Check(TargetType == ResType, [&]() { + llvm::dbgs() << "CoerceToType mismatch (expected: " << *TargetType + << ", given: " << *ResType << ")"; + }); + } + + switch (Res.getKind()) { + case ABIArgInfo::Extend: + CheckSimple(Target.isSignExt(), Res.isSignExt(), "SignExt"); + CheckSimple(Target.isZeroExt(), Res.isZeroExt(), "ZeroExt"); + [[fallthrough]]; + case ABIArgInfo::Direct: + CheckSimple(Target.getDirectAlign(), Res.getDirectAlign(), "DirectAlign"); + CheckSimple(Target.getDirectOffset(), Res.getDirectOffset(), + "DirectOffset"); + break; + case ABIArgInfo::Indirect: + CheckSimple(Target.getIndirectByVal(), Res.getIndirectByVal(), + "IndirectByVal"); + [[fallthrough]]; + case ABIArgInfo::IndirectAliased: + CheckSimple(Target.getIndirectAddrSpace(), Res.getIndirectAddrSpace(), + "IndirectAddrSpace"); + CheckSimple(Target.getIndirectRealign(), Res.getIndirectRealign(), + "IndirectRealign"); + Check(Target.getIndirectAlign() == Res.getIndirectAlign(), [&]() { + llvm::dbgs() << "IndirectAlign mismatch (expected: " + << Target.getIndirectAlign().getQuantity() + << ", given: " << Res.getIndirectAlign().getQuantity() + << ")"; + }); + break; + default: + break; + } + + Target = Res; + }; +#else + auto ConvertABIArgInfo = + [&](ABIArgInfo &Target, const llvm::abi::ArgInfo &AbiInfo, QualType Type, + int ArgNo) { Target = convertABIArgInfo(AbiInfo, Type); }; +#endif + + ConvertABIArgInfo(FI.getReturnInfo(), AbiFI->getReturnInfo(), + FI.getReturnType(), -1); + int ArgNo = 0; for (auto [CGArg, AbiArg] : llvm::zip_equal(FI.arguments(), AbiFI->arguments())) - CGArg.info = convertABIArgInfo(AbiArg.Info, CGArg.type); + ConvertABIArgInfo(CGArg.info, AbiArg.Info, CGArg.type, ArgNo++); } ABIArgInfo CodeGenModule::convertABIArgInfo(const llvm::abi::ArgInfo &AbiInfo, _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
