Skip to content

Commit 34dd8ec

Browse files
authored
[clang, SystemZ] Support -munaligned-symbols (#73511)
When this option is passed to clang, external (and/or weak) symbols are not assumed to have the minimum ABI alignment normally required. Symbols defined locally that are not weak are however still given the minimum alignment. This is implemented by passing a new parameter to getMinGlobalAlign() named HasNonWeakDef that is used to return the right alignment value. This is needed when external symbols created from a linker script may not get the ABI minimum alignment and must therefore be treated as unaligned by the compiler.
1 parent 718aac9 commit 34dd8ec

File tree

17 files changed

+195
-23
lines changed

17 files changed

+195
-23
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2413,12 +2413,18 @@ class ASTContext : public RefCountedBase<ASTContext> {
24132413
unsigned getTargetDefaultAlignForAttributeAligned() const;
24142414

24152415
/// Return the alignment in bits that should be given to a
2416-
/// global variable with type \p T.
2417-
unsigned getAlignOfGlobalVar(QualType T) const;
2416+
/// global variable with type \p T. If \p VD is non-null it will be
2417+
/// considered specifically for the query.
2418+
unsigned getAlignOfGlobalVar(QualType T, const VarDecl *VD) const;
24182419

24192420
/// Return the alignment in characters that should be given to a
2420-
/// global variable with type \p T.
2421-
CharUnits getAlignOfGlobalVarInChars(QualType T) const;
2421+
/// global variable with type \p T. If \p VD is non-null it will be
2422+
/// considered specifically for the query.
2423+
CharUnits getAlignOfGlobalVarInChars(QualType T, const VarDecl *VD) const;
2424+
2425+
/// Return the minimum alignement as specified by the target. If \p VD is
2426+
/// non-null it may be used to identify external or weak variables.
2427+
unsigned getMinGlobalAlignOfVar(uint64_t Size, const VarDecl *VD) const;
24222428

24232429
/// Return a conservative estimate of the alignment of the specified
24242430
/// decl \p D.

clang/include/clang/Basic/TargetInfo.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -704,8 +704,10 @@ class TargetInfo : public TransferrableTargetInfo,
704704
}
705705

706706
/// getMinGlobalAlign - Return the minimum alignment of a global variable,
707-
/// unless its alignment is explicitly reduced via attributes.
708-
virtual unsigned getMinGlobalAlign (uint64_t) const {
707+
/// unless its alignment is explicitly reduced via attributes. If \param
708+
/// HasNonWeakDef is true, this concerns a VarDecl which has a definition
709+
/// in current translation unit and that is not weak.
710+
virtual unsigned getMinGlobalAlign(uint64_t Size, bool HasNonWeakDef) const {
709711
return MinGlobalAlign;
710712
}
711713

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4619,6 +4619,10 @@ def munaligned_access : Flag<["-"], "munaligned-access">, Group<m_Group>,
46194619
HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64/LoongArch/RISC-V only)">;
46204620
def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group<m_Group>,
46214621
HelpText<"Force all memory accesses to be aligned (AArch32/AArch64/LoongArch/RISC-V only)">;
4622+
def munaligned_symbols : Flag<["-"], "munaligned-symbols">, Group<m_Group>,
4623+
HelpText<"Expect external char-aligned symbols to be without ABI alignment (SystemZ only)">;
4624+
def mno_unaligned_symbols : Flag<["-"], "mno-unaligned-symbols">, Group<m_Group>,
4625+
HelpText<"Expect external char-aligned symbols to be without ABI alignment (SystemZ only)">;
46224626
} // let Flags = [TargetSpecific]
46234627
def mstrict_align : Flag<["-"], "mstrict-align">, Alias<mno_unaligned_access>,
46244628
Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>,

clang/lib/AST/ASTContext.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1688,7 +1688,7 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
16881688
if (VD->hasGlobalStorage() && !ForAlignof) {
16891689
uint64_t TypeSize =
16901690
!BaseT->isIncompleteType() ? getTypeSize(T.getTypePtr()) : 0;
1691-
Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize));
1691+
Align = std::max(Align, getMinGlobalAlignOfVar(TypeSize, VD));
16921692
}
16931693

16941694
// Fields can be subject to extra alignment constraints, like if
@@ -2511,16 +2511,25 @@ unsigned ASTContext::getTargetDefaultAlignForAttributeAligned() const {
25112511

25122512
/// getAlignOfGlobalVar - Return the alignment in bits that should be given
25132513
/// to a global variable of the specified type.
2514-
unsigned ASTContext::getAlignOfGlobalVar(QualType T) const {
2514+
unsigned ASTContext::getAlignOfGlobalVar(QualType T, const VarDecl *VD) const {
25152515
uint64_t TypeSize = getTypeSize(T.getTypePtr());
25162516
return std::max(getPreferredTypeAlign(T),
2517-
getTargetInfo().getMinGlobalAlign(TypeSize));
2517+
getMinGlobalAlignOfVar(TypeSize, VD));
25182518
}
25192519

25202520
/// getAlignOfGlobalVarInChars - Return the alignment in characters that
25212521
/// should be given to a global variable of the specified type.
2522-
CharUnits ASTContext::getAlignOfGlobalVarInChars(QualType T) const {
2523-
return toCharUnitsFromBits(getAlignOfGlobalVar(T));
2522+
CharUnits ASTContext::getAlignOfGlobalVarInChars(QualType T,
2523+
const VarDecl *VD) const {
2524+
return toCharUnitsFromBits(getAlignOfGlobalVar(T, VD));
2525+
}
2526+
2527+
unsigned ASTContext::getMinGlobalAlignOfVar(uint64_t Size,
2528+
const VarDecl *VD) const {
2529+
// Make the default handling as that of a non-weak definition in the
2530+
// current translation unit.
2531+
bool HasNonWeakDef = !VD || (VD->hasDefinition() && !VD->isWeak());
2532+
return getTargetInfo().getMinGlobalAlign(Size, HasNonWeakDef);
25242533
}
25252534

25262535
CharUnits ASTContext::getOffsetOfBaseWithVBPtr(const CXXRecordDecl *RD) const {

clang/lib/Basic/Targets/AArch64.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,8 +1517,10 @@ MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
15171517
return CCK_MicrosoftWin64;
15181518
}
15191519

1520-
unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize) const {
1521-
unsigned Align = WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize);
1520+
unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize,
1521+
bool HasNonWeakDef) const {
1522+
unsigned Align =
1523+
WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize, HasNonWeakDef);
15221524

15231525
// MSVC does size based alignment for arm64 based on alignment section in
15241526
// below document, replicate that to keep alignment consistent with object

clang/lib/Basic/Targets/AArch64.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,8 @@ class LLVM_LIBRARY_VISIBILITY MicrosoftARM64TargetInfo
236236
TargetInfo::CallingConvKind
237237
getCallingConvKind(bool ClangABICompat4) const override;
238238

239-
unsigned getMinGlobalAlign(uint64_t TypeSize) const override;
239+
unsigned getMinGlobalAlign(uint64_t TypeSize,
240+
bool HasNonWeakDef) const override;
240241
};
241242

242243
// ARM64 MinGW target

clang/lib/Basic/Targets/CSKY.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,8 @@ bool CSKYTargetInfo::validateAsmConstraint(
308308
}
309309
}
310310

311-
unsigned CSKYTargetInfo::getMinGlobalAlign(uint64_t Size) const {
311+
unsigned CSKYTargetInfo::getMinGlobalAlign(uint64_t Size,
312+
bool HasNonWeakDef) const {
312313
if (Size >= 32)
313314
return 32;
314315
return 0;

clang/lib/Basic/Targets/CSKY.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class LLVM_LIBRARY_VISIBILITY CSKYTargetInfo : public TargetInfo {
7171

7272
bool isValidCPUName(StringRef Name) const override;
7373

74-
unsigned getMinGlobalAlign(uint64_t) const override;
74+
unsigned getMinGlobalAlign(uint64_t, bool HasNonWeakDef) const override;
7575

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

clang/lib/Basic/Targets/NVPTX.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple,
115115
LongAlign = HostTarget->getLongAlign();
116116
LongLongWidth = HostTarget->getLongLongWidth();
117117
LongLongAlign = HostTarget->getLongLongAlign();
118-
MinGlobalAlign = HostTarget->getMinGlobalAlign(/* TypeSize = */ 0);
118+
MinGlobalAlign = HostTarget->getMinGlobalAlign(/* TypeSize = */ 0,
119+
/* HasNonWeakDef = */ true);
119120
NewAlign = HostTarget->getNewAlign();
120121
DefaultAlignForAttributeAligned =
121122
HostTarget->getDefaultAlignForAttributeAligned();

clang/lib/Basic/Targets/SPIR.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,9 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo {
125125
LongAlign = HostTarget->getLongAlign();
126126
LongLongWidth = HostTarget->getLongLongWidth();
127127
LongLongAlign = HostTarget->getLongLongAlign();
128-
MinGlobalAlign = HostTarget->getMinGlobalAlign(/* TypeSize = */ 0);
128+
MinGlobalAlign =
129+
HostTarget->getMinGlobalAlign(/* TypeSize = */ 0,
130+
/* HasNonWeakDef = */ true);
129131
NewAlign = HostTarget->getNewAlign();
130132
DefaultAlignForAttributeAligned =
131133
HostTarget->getDefaultAlignForAttributeAligned();

0 commit comments

Comments
 (0)