diff options
author | David Sherwood <57997763+david-arm@users.noreply.github.com> | 2023-12-08 12:58:39 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-08 12:58:39 +0000 |
commit | c1cfa1757c208cd15efec3541aadea6bec52092d (patch) | |
tree | dd84373259c0447849b78a2b43b96b41df1cc3e4 /clang/lib/CodeGen/CodeGenTBAA.cpp | |
parent | 2a0314f153b3fdc6d8b51d35c2e4a4bb67dfcaef (diff) | |
download | llvm-c1cfa1757c208cd15efec3541aadea6bec52092d.zip llvm-c1cfa1757c208cd15efec3541aadea6bec52092d.tar.gz llvm-c1cfa1757c208cd15efec3541aadea6bec52092d.tar.bz2 |
[Clang] Emit TBAA info for enums in C (#73326)
When emitting TBAA information for enums in C code we currently just
treat the data as an 'omnipotent char'. However, with C strict aliasing
this means we fail to optimise certain cases. For example, in the
SPEC2017 xz benchmark there are structs that contain arrays of enums,
and clang pessmistically assumes that accesses to those enums could
alias with other struct members that have a different type.
According to
https://en.cppreference.com/w/c/language/enum
enums should be treated as 'int' types unless explicitly specified (C23)
or if 'int' would not be large enough to hold all the enumerated values.
In the latter case the compiler is free to choose a suitable integer
that would hold all such values.
When compiling C code this patch generates TBAA information for the enum
by using an equivalent integer of the size clang has already chosen for
the enum. I have ignored C++ for now because the rules are more complex.
New test added here:
clang/test/CodeGen/tbaa.c
Diffstat (limited to 'clang/lib/CodeGen/CodeGenTBAA.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenTBAA.cpp | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index 5906b14..dc288bc 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -196,11 +196,14 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) { // Enum types are distinct types. In C++ they have "underlying types", // however they aren't related for TBAA. if (const EnumType *ETy = dyn_cast<EnumType>(Ty)) { + if (!Features.CPlusPlus) + return getTypeInfo(ETy->getDecl()->getIntegerType()); + // In C++ mode, types have linkage, so we can rely on the ODR and // on their mangled names, if they're external. // TODO: Is there a way to get a program-wide unique name for a // decl with local linkage or no linkage? - if (!Features.CPlusPlus || !ETy->getDecl()->isExternallyVisible()) + if (!ETy->getDecl()->isExternallyVisible()) return getChar(); SmallString<256> OutName; |