Skip to content

Commit

Permalink
Also handle weak symbols
Browse files Browse the repository at this point in the history
  • Loading branch information
JonPsson1 committed Dec 19, 2023
1 parent de67383 commit c0001b5
Show file tree
Hide file tree
Showing 14 changed files with 37 additions and 30 deletions.
4 changes: 2 additions & 2 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -2406,11 +2406,11 @@ class ASTContext : public RefCountedBase<ASTContext> {

/// Return the alignment in bits that should be given to a
/// global variable with type \p T.
unsigned getAlignOfGlobalVar(QualType T, bool HasDef) const;
unsigned getAlignOfGlobalVar(QualType T, const VarDecl *VD) const;

/// Return the alignment in characters that should be given to a
/// global variable with type \p T.
CharUnits getAlignOfGlobalVarInChars(QualType T, bool HasDef) const;
CharUnits getAlignOfGlobalVarInChars(QualType T, const VarDecl *VD) const;

/// Return a conservative estimate of the alignment of the specified
/// decl \p D.
Expand Down
9 changes: 4 additions & 5 deletions clang/include/clang/Basic/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class DiagnosticsEngine;
class LangOptions;
class CodeGenOptions;
class MacroBuilder;
class VarDecl;

/// Contains information gathered from parsing the contents of TargetAttr.
struct ParsedTargetAttr {
Expand Down Expand Up @@ -704,11 +705,9 @@ class TargetInfo : public TransferrableTargetInfo,
}

/// getMinGlobalAlign - Return the minimum alignment of a global variable,
/// unless its alignment is explicitly reduced via attributes. It may be
/// that an external symbol needs to be considered unaligned (like
/// artificial symbols created from a linker script). If \param HasDef is
/// false, this symbol does not have a definition and is external.
virtual unsigned getMinGlobalAlign(uint64_t Size, bool HasDef) const {
/// unless its alignment is explicitly reduced via attributes. If \param VD
/// is non-null, it may be used to examine the specific variable's attributes.
virtual unsigned getMinGlobalAlign(uint64_t Size, const VarDecl *VD) const {
return MinGlobalAlign;
}

Expand Down
14 changes: 6 additions & 8 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1681,8 +1681,7 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
if (VD->hasGlobalStorage() && !ForAlignof) {
uint64_t TypeSize =
!BaseT->isIncompleteType() ? getTypeSize(T.getTypePtr()) : 0;
Align = std::max(Align, getTargetInfo().getMinGlobalAlign(
TypeSize, VD->hasDefinition()));
Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize, VD));
}

// Fields can be subject to extra alignment constraints, like if
Expand Down Expand Up @@ -2503,19 +2502,18 @@ unsigned ASTContext::getTargetDefaultAlignForAttributeAligned() const {
}

/// getAlignOfGlobalVar - Return the alignment in bits that should be given
/// to a global variable of the specified type (see comment for
/// getMinGlobalAlign about HasDef).
unsigned ASTContext::getAlignOfGlobalVar(QualType T, bool HasDef) const {
/// to a global variable of the specified type.
unsigned ASTContext::getAlignOfGlobalVar(QualType T, const VarDecl *VD) const {
uint64_t TypeSize = getTypeSize(T.getTypePtr());
return std::max(getPreferredTypeAlign(T),
getTargetInfo().getMinGlobalAlign(TypeSize, HasDef));
getTargetInfo().getMinGlobalAlign(TypeSize, VD));
}

/// getAlignOfGlobalVarInChars - Return the alignment in characters that
/// should be given to a global variable of the specified type.
CharUnits ASTContext::getAlignOfGlobalVarInChars(QualType T,
bool HasDef) const {
return toCharUnitsFromBits(getAlignOfGlobalVar(T, HasDef));
const VarDecl *VD) const {
return toCharUnitsFromBits(getAlignOfGlobalVar(T, VD));
}

CharUnits ASTContext::getOffsetOfBaseWithVBPtr(const CXXRecordDecl *RD) const {
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Basic/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1518,8 +1518,8 @@ MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
}

unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize,
bool HasDef) const {
unsigned Align = WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize, HasDef);
const VarDecl *VD) const {
unsigned Align = WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize, VD);

// MSVC does size based alignment for arm64 based on alignment section in
// below document, replicate that to keep alignment consistent with object
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Basic/Targets/AArch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,8 @@ class LLVM_LIBRARY_VISIBILITY MicrosoftARM64TargetInfo
TargetInfo::CallingConvKind
getCallingConvKind(bool ClangABICompat4) const override;

unsigned getMinGlobalAlign(uint64_t TypeSize, bool HasDef) const override;
unsigned getMinGlobalAlign(uint64_t TypeSize,
const VarDecl *VD) const override;
};

// ARM64 MinGW target
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Basic/Targets/CSKY.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,8 @@ bool CSKYTargetInfo::validateAsmConstraint(
}
}

unsigned CSKYTargetInfo::getMinGlobalAlign(uint64_t Size, bool HasDef) const {
unsigned CSKYTargetInfo::getMinGlobalAlign(uint64_t Size,
const VarDecl *VD) const {
if (Size >= 32)
return 32;
return 0;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/CSKY.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class LLVM_LIBRARY_VISIBILITY CSKYTargetInfo : public TargetInfo {

bool isValidCPUName(StringRef Name) const override;

unsigned getMinGlobalAlign(uint64_t, bool) const override;
unsigned getMinGlobalAlign(uint64_t, const VarDecl *) const override;

ArrayRef<Builtin::Info> getTargetBuiltins() const override;

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/NVPTX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple,
LongLongWidth = HostTarget->getLongLongWidth();
LongLongAlign = HostTarget->getLongLongAlign();
MinGlobalAlign = HostTarget->getMinGlobalAlign(/* TypeSize = */ 0,
/* HasDef = */ true);
/* VD = */ nullptr);
NewAlign = HostTarget->getNewAlign();
DefaultAlignForAttributeAligned =
HostTarget->getDefaultAlignForAttributeAligned();
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/SPIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo {
LongLongWidth = HostTarget->getLongLongWidth();
LongLongAlign = HostTarget->getLongLongAlign();
MinGlobalAlign = HostTarget->getMinGlobalAlign(/* TypeSize = */ 0,
/* HasDef = */ true);
/* VD = */ nullptr);
NewAlign = HostTarget->getNewAlign();
DefaultAlignForAttributeAligned =
HostTarget->getDefaultAlignForAttributeAligned();
Expand Down
7 changes: 4 additions & 3 deletions clang/lib/Basic/Targets/SystemZ.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//

#include "SystemZ.h"
#include "clang/AST/Decl.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/MacroBuilder.h"
Expand Down Expand Up @@ -139,10 +140,10 @@ bool SystemZTargetInfo::hasFeature(StringRef Feature) const {
}

unsigned SystemZTargetInfo::getMinGlobalAlign(uint64_t Size,
bool HasDef) const {
// Don't enforce the minimum alignment on an external symbol if
const VarDecl *VD) const {
// Don't enforce the minimum alignment on an external or weak symbol if
// -munaligned-symbols is passed.
if (UnalignedSymbols && !HasDef)
if (UnalignedSymbols && VD && (!VD->hasDefinition() || VD->isWeak()))
return 0;

return MinGlobalAlign;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/SystemZ.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
HasStrictFP = true;
}

unsigned getMinGlobalAlign(uint64_t Size, bool HasDef) const override;
unsigned getMinGlobalAlign(uint64_t Size, const VarDecl *VD) const override;

void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6303,7 +6303,7 @@ ConstantAddress
CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S,
StringRef Name) {
CharUnits Alignment =
getContext().getAlignOfGlobalVarInChars(S->getType(), /*HasDef=*/true);
getContext().getAlignOfGlobalVarInChars(S->getType(), /*VD=*/nullptr);

llvm::Constant *C = GetConstantArrayFromStringLiteral(S);
llvm::GlobalVariable **Entry = nullptr;
Expand Down Expand Up @@ -6367,7 +6367,7 @@ ConstantAddress CodeGenModule::GetAddrOfConstantCString(
const std::string &Str, const char *GlobalName) {
StringRef StrWithNull(Str.c_str(), Str.size() + 1);
CharUnits Alignment = getContext().getAlignOfGlobalVarInChars(
getContext().CharTy, /*HasDef=*/true);
getContext().CharTy, /*VD=*/nullptr);

llvm::Constant *C =
llvm::ConstantDataArray::getString(getLLVMContext(), StrWithNull, false);
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/Sema/SemaOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2293,10 +2293,9 @@ bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
// and alignment, because the runtime library only deals with uintptr types.
// If it does not fit the uintptr size, we need to pass the data by reference
// instead.
bool IsExtern = isa<VarDecl>(D) && !cast<VarDecl>(D)->hasDefinition();
if (!IsByRef && (Ctx.getTypeSizeInChars(Ty) >
Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
Ctx.getAlignOfGlobalVarInChars(Ty, /*HasDef=*/!IsExtern) >
Ctx.getAlignOfGlobalVarInChars(Ty, dyn_cast<VarDecl>(D)) >
Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
IsByRef = true;
}
Expand Down
8 changes: 8 additions & 0 deletions clang/test/CodeGen/SystemZ/unaligned-symbols.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,11 @@ unsigned char foo6 () {
return ExtUnAl_s_nested[0].a[0].c[0] + ExtExplAlign_s_nested[0].a[0].c[0] +
Aligned_s_nested[0].a[0].c[0];
}

// A weak symbol could be replaced with an unaligned one at link time.
// CHECK-LABEL: foo7
// CHECK-NOT: larl {{.*}}Weaksym
unsigned char __attribute__((weak)) Weaksym = 0;
unsigned char foo7 () {
return Weaksym;
}

0 comments on commit c0001b5

Please sign in to comment.