diff options
author | Nikita Popov <npopov@redhat.com> | 2025-07-01 10:43:40 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-01 10:43:40 +0200 |
commit | 5fa4eb1dfd8f463374e37799702411cca154d2e4 (patch) | |
tree | 43e8eba1d898e235a4a3ba16fe0a4d9f62a2b7ac /clang/lib/CodeGen/CodeGenModule.cpp | |
parent | cb806510914ed909b934d285062a9efb13b1cea4 (diff) | |
download | llvm-5fa4eb1dfd8f463374e37799702411cca154d2e4.zip llvm-5fa4eb1dfd8f463374e37799702411cca154d2e4.tar.gz llvm-5fa4eb1dfd8f463374e37799702411cca154d2e4.tar.bz2 |
[Clang] Verify data layout consistency (#144720)
Verify that the alignments specified by clang TargetInfo match the
alignments specified by LLVM data layout, which will hopefully prevent
accidental mismatches in the future.
This currently contains opt-outs for a number of of existing mismatches.
I'm also skipping the verification if options like `-malign-double` are
used, or a language that mandates sizes/alignments that differ from C.
The verification happens in CodeGen, as we can't have an IR dependency
in Basic.
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 96fdab2..e6d150f 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -332,6 +332,72 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { return *TheTargetCodeGenInfo; } +static void checkDataLayoutConsistency(const TargetInfo &Target, + llvm::LLVMContext &Context, + const LangOptions &Opts) { +#ifndef NDEBUG + // Don't verify non-standard ABI configurations. + if (Opts.AlignDouble || Opts.OpenCL || Opts.HLSL) + return; + + llvm::Triple Triple = Target.getTriple(); + llvm::DataLayout DL(Target.getDataLayoutString()); + auto Check = [&](const char *Name, llvm::Type *Ty, unsigned Alignment) { + llvm::Align DLAlign = DL.getABITypeAlign(Ty); + llvm::Align ClangAlign(Alignment / 8); + if (DLAlign != ClangAlign) { + llvm::errs() << "For target " << Triple.str() << " type " << Name + << " mapping to " << *Ty << " has data layout alignment " + << DLAlign.value() << " while clang specifies " + << ClangAlign.value() << "\n"; + abort(); + } + }; + + Check("bool", llvm::Type::getIntNTy(Context, Target.BoolWidth), + Target.BoolAlign); + Check("short", llvm::Type::getIntNTy(Context, Target.ShortWidth), + Target.ShortAlign); + Check("int", llvm::Type::getIntNTy(Context, Target.IntWidth), + Target.IntAlign); + Check("long", llvm::Type::getIntNTy(Context, Target.LongWidth), + Target.LongAlign); + // FIXME: M68k specifies incorrect long long alignment in both LLVM and Clang. + if (Triple.getArch() != llvm::Triple::m68k) + Check("long long", llvm::Type::getIntNTy(Context, Target.LongLongWidth), + Target.LongLongAlign); + // FIXME: There are int128 alignment mismatches on multiple targets. + if (Target.hasInt128Type() && !Target.getTargetOpts().ForceEnableInt128 && + !Triple.isAMDGPU() && !Triple.isSPIRV() && + Triple.getArch() != llvm::Triple::ve) + Check("__int128", llvm::Type::getIntNTy(Context, 128), Target.Int128Align); + + if (Target.hasFloat16Type()) + Check("half", llvm::Type::getFloatingPointTy(Context, *Target.HalfFormat), + Target.HalfAlign); + if (Target.hasBFloat16Type()) + Check("bfloat", llvm::Type::getBFloatTy(Context), Target.BFloat16Align); + Check("float", llvm::Type::getFloatingPointTy(Context, *Target.FloatFormat), + Target.FloatAlign); + // FIXME: AIX specifies wrong double alignment in DataLayout + if (!Triple.isOSAIX()) { + Check("double", + llvm::Type::getFloatingPointTy(Context, *Target.DoubleFormat), + Target.DoubleAlign); + Check("long double", + llvm::Type::getFloatingPointTy(Context, *Target.LongDoubleFormat), + Target.LongDoubleAlign); + } + // FIXME: Wasm has a mismatch in f128 alignment between Clang and LLVM. + if (Target.hasFloat128Type() && !Triple.isWasm()) + Check("__float128", llvm::Type::getFP128Ty(Context), Target.Float128Align); + if (Target.hasIbm128Type()) + Check("__ibm128", llvm::Type::getPPC_FP128Ty(Context), Target.Ibm128Align); + + Check("void*", llvm::PointerType::getUnqual(Context), Target.PointerAlign); +#endif +} + CodeGenModule::CodeGenModule(ASTContext &C, IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, const HeaderSearchOptions &HSO, @@ -487,6 +553,9 @@ CodeGenModule::CodeGenModule(ASTContext &C, llvm::sort(this->MSHotPatchFunctions); } + + if (!Context.getAuxTargetInfo()) + checkDataLayoutConsistency(Context.getTargetInfo(), LLVMContext, LangOpts); } CodeGenModule::~CodeGenModule() {} |