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();

clang/lib/Basic/Targets/SystemZ.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,16 @@ bool SystemZTargetInfo::hasFeature(StringRef Feature) const {
138138
.Default(false);
139139
}
140140

141+
unsigned SystemZTargetInfo::getMinGlobalAlign(uint64_t Size,
142+
bool HasNonWeakDef) const {
143+
// Don't enforce the minimum alignment on an external or weak symbol if
144+
// -munaligned-symbols is passed.
145+
if (UnalignedSymbols && !HasNonWeakDef)
146+
return 0;
147+
148+
return MinGlobalAlign;
149+
}
150+
141151
void SystemZTargetInfo::getTargetDefines(const LangOptions &Opts,
142152
MacroBuilder &Builder) const {
143153
Builder.defineMacro("__s390__");

clang/lib/Basic/Targets/SystemZ.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
2929
bool HasTransactionalExecution;
3030
bool HasVector;
3131
bool SoftFloat;
32+
bool UnalignedSymbols;
3233

3334
public:
3435
SystemZTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
3536
: TargetInfo(Triple), CPU("z10"), ISARevision(8),
36-
HasTransactionalExecution(false), HasVector(false), SoftFloat(false) {
37+
HasTransactionalExecution(false), HasVector(false), SoftFloat(false),
38+
UnalignedSymbols(false) {
3739
IntMaxType = SignedLong;
3840
Int64Type = SignedLong;
3941
IntWidth = IntAlign = 32;
@@ -64,6 +66,8 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
6466
HasStrictFP = true;
6567
}
6668

69+
unsigned getMinGlobalAlign(uint64_t Size, bool HasNonWeakDef) const override;
70+
6771
void getTargetDefines(const LangOptions &Opts,
6872
MacroBuilder &Builder) const override;
6973

@@ -163,13 +167,16 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
163167
HasTransactionalExecution = false;
164168
HasVector = false;
165169
SoftFloat = false;
170+
UnalignedSymbols = false;
166171
for (const auto &Feature : Features) {
167172
if (Feature == "+transactional-execution")
168173
HasTransactionalExecution = true;
169174
else if (Feature == "+vector")
170175
HasVector = true;
171176
else if (Feature == "+soft-float")
172177
SoftFloat = true;
178+
else if (Feature == "+unaligned-symbols")
179+
UnalignedSymbols = true;
173180
}
174181
HasVector &= !SoftFloat;
175182

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6330,7 +6330,8 @@ GenerateStringLiteral(llvm::Constant *C, llvm::GlobalValue::LinkageTypes LT,
63306330
ConstantAddress
63316331
CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S,
63326332
StringRef Name) {
6333-
CharUnits Alignment = getContext().getAlignOfGlobalVarInChars(S->getType());
6333+
CharUnits Alignment =
6334+
getContext().getAlignOfGlobalVarInChars(S->getType(), /*VD=*/nullptr);
63346335

63356336
llvm::Constant *C = GetConstantArrayFromStringLiteral(S);
63366337
llvm::GlobalVariable **Entry = nullptr;
@@ -6393,8 +6394,8 @@ CodeGenModule::GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *E) {
63936394
ConstantAddress CodeGenModule::GetAddrOfConstantCString(
63946395
const std::string &Str, const char *GlobalName) {
63956396
StringRef StrWithNull(Str.c_str(), Str.size() + 1);
6396-
CharUnits Alignment =
6397-
getContext().getAlignOfGlobalVarInChars(getContext().CharTy);
6397+
CharUnits Alignment = getContext().getAlignOfGlobalVarInChars(
6398+
getContext().CharTy, /*VD=*/nullptr);
63986399

63996400
llvm::Constant *C =
64006401
llvm::ConstantDataArray::getString(getLLVMContext(), StrWithNull, false);

clang/lib/Driver/ToolChains/Arch/SystemZ.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,12 @@ void systemz::getSystemZTargetFeatures(const Driver &D, const ArgList &Args,
7171
systemz::FloatABI FloatABI = systemz::getSystemZFloatABI(D, Args);
7272
if (FloatABI == systemz::FloatABI::Soft)
7373
Features.push_back("+soft-float");
74+
75+
if (const Arg *A = Args.getLastArg(options::OPT_munaligned_symbols,
76+
options::OPT_mno_unaligned_symbols)) {
77+
if (A->getOption().matches(options::OPT_munaligned_symbols))
78+
Features.push_back("+unaligned-symbols");
79+
else
80+
Features.push_back("-unaligned-symbols");
81+
}
7482
}

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2295,7 +2295,7 @@ bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
22952295
// instead.
22962296
if (!IsByRef && (Ctx.getTypeSizeInChars(Ty) >
22972297
Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2298-
Ctx.getAlignOfGlobalVarInChars(Ty) >
2298+
Ctx.getAlignOfGlobalVarInChars(Ty, dyn_cast<VarDecl>(D)) >
22992299
Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
23002300
IsByRef = true;
23012301
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// RUN: %clang -target s390x-linux-gnu %s -o - -emit-llvm -S \
2+
// RUN: | FileCheck %s -check-prefixes=CHECK,ALIGNED
3+
4+
// RUN: %clang -target s390x-linux-gnu %s -o - -emit-llvm -S \
5+
// RUN: -mno-unaligned-symbols | FileCheck %s -check-prefixes=CHECK,ALIGNED
6+
7+
// RUN: %clang -target s390x-linux-gnu %s -o - -emit-llvm -S \
8+
// RUN: -munaligned-symbols | FileCheck %s -check-prefixes=CHECK,UNALIGN
9+
10+
// RUN: %clang -cc1 -triple s390x-linux-gnu %s -o - -emit-llvm \
11+
// RUN: -target-feature +unaligned-symbols | FileCheck %s -check-prefixes=CHECK,UNALIGN
12+
13+
14+
// With -munaligned-symbols, the external and unaligned ("ExtUnal...")
15+
// variable of each test should be treated as unaligned. For the explicitly
16+
// aligned ("ExtExplAlign...") variables and those defined in the translation
17+
// unit ("Aligned..."), the normal ABI alignment of 2 should still be
18+
// in effect.
19+
20+
// ALIGNED: @ExtUnal = external global i8, align 2
21+
// UNALIGN: @ExtUnal = external global i8, align 1
22+
// CHECK: @ExtExplAlign = external global i8, align 2
23+
// CHECK: @Aligned = {{(dso_local )?}}global i8 0, align 2
24+
extern unsigned char ExtUnal;
25+
extern unsigned char ExtExplAlign __attribute__((aligned(2)));
26+
unsigned char Aligned;
27+
unsigned char foo0 () {
28+
return ExtUnal + ExtExplAlign + Aligned;
29+
}
30+
31+
// ALIGNED: @ExtUnal_c2Arr = external global [2 x i8], align 2
32+
// UNALIGN: @ExtUnal_c2Arr = external global [2 x i8], align 1
33+
// CHECK: @ExtExplAlign_c2Arr = external global [2 x i8], align 2
34+
// CHECK: @Aligned_c2Arr = {{(dso_local )?}}global [2 x i8] zeroinitializer, align 2
35+
extern unsigned char ExtUnal_c2Arr[2];
36+
extern unsigned char ExtExplAlign_c2Arr[2] __attribute__((aligned(2)));
37+
unsigned char Aligned_c2Arr[2];
38+
unsigned char foo1 () {
39+
return ExtUnal_c2Arr[0] + ExtExplAlign_c2Arr[0] + Aligned_c2Arr[0];
40+
}
41+
42+
// ALIGNED: @ExtUnal_s1c = external global %struct.s1c, align 2
43+
// UNALIGN: @ExtUnal_s1c = external global %struct.s1c, align 1
44+
// CHECK: @ExtExplAlign_s1c = external global %struct.s1c, align 2
45+
// CHECK: @Aligned_s1c = {{(dso_local )?}}global %struct.s1c zeroinitializer, align 2
46+
struct s1c { char c; };
47+
extern struct s1c ExtUnal_s1c;
48+
extern struct s1c ExtExplAlign_s1c __attribute__((aligned(2)));
49+
struct s1c Aligned_s1c;
50+
unsigned char foo2 () {
51+
return ExtUnal_s1c.c + ExtExplAlign_s1c.c + Aligned_s1c.c;
52+
}
53+
54+
// ALIGNED: @ExtUnal_s2c = external global %struct.s2c, align 2
55+
// UNALIGN: @ExtUnal_s2c = external global %struct.s2c, align 1
56+
// CHECK: @ExtExplAlign_s2c = external global %struct.s2c, align 2
57+
// CHECK: @Aligned_s2c = {{(dso_local )?}}global %struct.s2c zeroinitializer, align 2
58+
struct s2c { char c; char c1;};
59+
extern struct s2c ExtUnal_s2c;
60+
extern struct s2c ExtExplAlign_s2c __attribute__((aligned(2)));
61+
struct s2c Aligned_s2c;
62+
unsigned char foo3 () {
63+
return ExtUnal_s2c.c + ExtExplAlign_s2c.c + Aligned_s2c.c;
64+
}
65+
66+
// ALIGNED: @ExtUnal_s_c2Arr = external global %struct.s_c2Arr, align 2
67+
// UNALIGN: @ExtUnal_s_c2Arr = external global %struct.s_c2Arr, align 1
68+
// CHECK: @ExtExplAlign_s_c2Arr = external global %struct.s_c2Arr, align 2
69+
// CHECK: @Aligned_s_c2Arr = {{(dso_local )?}}global %struct.s_c2Arr zeroinitializer, align 2
70+
struct s_c2Arr { char c[2]; };
71+
extern struct s_c2Arr ExtUnal_s_c2Arr;
72+
extern struct s_c2Arr ExtExplAlign_s_c2Arr __attribute__((aligned(2)));
73+
struct s_c2Arr Aligned_s_c2Arr;
74+
unsigned char foo4 () {
75+
return ExtUnal_s_c2Arr.c[0] + ExtExplAlign_s_c2Arr.c[0] + Aligned_s_c2Arr.c[0];
76+
}
77+
78+
// ALIGNED: @ExtUnal_s_packed = external global %struct.s_packed, align 2
79+
// UNALIGN: @ExtUnal_s_packed = external global %struct.s_packed, align 1
80+
// CHECK: @ExtExplAlign_s_packed = external global %struct.s_packed, align 2
81+
// CHECK: @Aligned_s_packed = {{(dso_local )?}}global %struct.s_packed zeroinitializer, align 2
82+
struct s_packed {
83+
int __attribute__((__packed__)) i;
84+
char c;
85+
};
86+
extern struct s_packed ExtUnal_s_packed;
87+
extern struct s_packed ExtExplAlign_s_packed __attribute__((aligned(2)));
88+
struct s_packed Aligned_s_packed;
89+
unsigned char foo5 () {
90+
return ExtUnal_s_packed.c + ExtExplAlign_s_packed.c + Aligned_s_packed.c;
91+
}
92+
93+
// ALIGNED: @ExtUnAl_s_nested = external global [2 x %struct.s_nested], align 2
94+
// UNALIGN: @ExtUnAl_s_nested = external global [2 x %struct.s_nested], align 1
95+
// CHECK: @ExtExplAlign_s_nested = external global [2 x %struct.s_nested], align 2
96+
// CHECK: @Aligned_s_nested = {{(dso_local )?}}global [2 x %struct.s_nested] zeroinitializer, align 2
97+
struct s_nested { struct s_c2Arr a[2]; };
98+
extern struct s_nested ExtUnAl_s_nested[2];
99+
extern struct s_nested ExtExplAlign_s_nested[2] __attribute__((aligned(2)));
100+
struct s_nested Aligned_s_nested[2];
101+
unsigned char foo6 () {
102+
return ExtUnAl_s_nested[0].a[0].c[0] + ExtExplAlign_s_nested[0].a[0].c[0] +
103+
Aligned_s_nested[0].a[0].c[0];
104+
}
105+
106+
// A weak symbol could be replaced with an unaligned one at link time.
107+
// CHECK-LABEL: foo7
108+
// ALIGNED: %0 = load i8, ptr @Weaksym, align 2
109+
// UNALIGN: %0 = load i8, ptr @Weaksym, align 1
110+
unsigned char __attribute__((weak)) Weaksym = 0;
111+
unsigned char foo7 () {
112+
return Weaksym;
113+
}

llvm/lib/Target/SystemZ/SystemZFeatures.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ def FeatureBackChain : SystemZFeature<
3737
"Store the address of the caller's frame into the callee's stack frame"
3838
>;
3939

40+
def FeatureUnalignedSymbols : SystemZFeature<
41+
"unaligned-symbols", "UnalignedSymbols", (all_of FeatureUnalignedSymbols),
42+
"Don't apply the ABI minimum alignment to external symbols."
43+
>;
44+
4045
//===----------------------------------------------------------------------===//
4146
//
4247
// New features added in the Ninth Edition of the z/Architecture

0 commit comments

Comments
 (0)