Skip to content

Commit 84831bd

Browse files
committed
[SystemZ] Make 128 bit integers be aligned to 8 bytes.
The SystemZ ABI says that 128 bit integers should be aligned to only 8 bytes. Reviewed By: Ulrich Weigand, Nikita Popov Differential Revision: https://reviews.llvm.org/D130900
1 parent b7fb856 commit 84831bd

File tree

8 files changed

+36
-3
lines changed

8 files changed

+36
-3
lines changed

clang/include/clang/Basic/TargetInfo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ struct TransferrableTargetInfo {
7878
unsigned char LargeArrayMinWidth, LargeArrayAlign;
7979
unsigned char LongWidth, LongAlign;
8080
unsigned char LongLongWidth, LongLongAlign;
81+
unsigned char Int128Align;
8182

8283
// Fixed point bit widths
8384
unsigned char ShortAccumWidth, ShortAccumAlign;
@@ -470,6 +471,9 @@ class TargetInfo : public virtual TransferrableTargetInfo,
470471
unsigned getLongLongWidth() const { return LongLongWidth; }
471472
unsigned getLongLongAlign() const { return LongLongAlign; }
472473

474+
/// getInt128Align() - Returns the alignment of Int128.
475+
unsigned getInt128Align() const { return Int128Align; }
476+
473477
/// getShortAccumWidth/Align - Return the size of 'signed short _Accum' and
474478
/// 'unsigned short _Accum' for this target, in bits.
475479
unsigned getShortAccumWidth() const { return ShortAccumWidth; }

clang/lib/AST/ASTContext.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2082,7 +2082,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
20822082
case BuiltinType::Int128:
20832083
case BuiltinType::UInt128:
20842084
Width = 128;
2085-
Align = 128; // int128_t is 128-bit aligned on all targets.
2085+
Align = Target->getInt128Align();
20862086
break;
20872087
case BuiltinType::ShortAccum:
20882088
case BuiltinType::UShortAccum:

clang/lib/Basic/TargetInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {
4545
IntWidth = IntAlign = 32;
4646
LongWidth = LongAlign = 32;
4747
LongLongWidth = LongLongAlign = 64;
48+
Int128Align = 128;
4849

4950
// Fixed point default bit widths
5051
ShortAccumWidth = ShortAccumAlign = 16;

clang/lib/Basic/Targets/SystemZ.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
4040
TLSSupported = true;
4141
IntWidth = IntAlign = 32;
4242
LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
43+
Int128Align = 64;
4344
PointerWidth = PointerAlign = 64;
4445
LongDoubleWidth = 128;
4546
LongDoubleAlign = 64;

clang/test/CodeGen/SystemZ/align-systemz.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ void func (void)
2626
}
2727

2828

29+
// The SystemZ ABI aligns __int128_t to only eight bytes.
30+
31+
struct S_int128 { __int128_t B; } Obj_I128;
32+
__int128_t GlobI128;
33+
// CHECK: @Obj_I128 = global %struct.S_int128 zeroinitializer, align 8
34+
// CHECK: @GlobI128 = global i128 0, align 8
35+
36+
2937
// Alignment should be respected for coerced argument loads
3038

3139
struct arg { long y __attribute__((packed, aligned(4))); };
@@ -40,4 +48,3 @@ void test (void)
4048

4149
// CHECK-LABEL: @test
4250
// CHECK: load i64, i64* getelementptr inbounds (%struct.arg, %struct.arg* @x, i32 0, i32 0), align 4
43-

clang/test/CodeGen/SystemZ/systemz-abi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ long long pass_longlong(long long arg) { return arg; }
4343
// CHECK-LABEL: define{{.*}} i64 @pass_longlong(i64 %{{.*}})
4444

4545
__int128 pass_int128(__int128 arg) { return arg; }
46-
// CHECK-LABEL: define{{.*}} void @pass_int128(i128* noalias sret(i128) align 16 %{{.*}}, i128* %0)
46+
// CHECK-LABEL: define{{.*}} void @pass_int128(i128* noalias sret(i128) align 8 %{{.*}}, i128* %0)
4747

4848
float pass_float(float arg) { return arg; }
4949
// CHECK-LABEL: define{{.*}} float @pass_float(float %{{.*}})

clang/test/CodeGen/SystemZ/zos-alignment.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,13 @@ struct s11 {
160160
// CHECK-NEXT: 8 | char b
161161
// CHECK-NEXT: | [sizeof=16, align=8]
162162

163+
struct s12 {
164+
__int128_t a;
165+
} S12;
166+
// CHECK: 0 | struct s12
167+
// CHECK-NEXT: 0 | __int128_t a
168+
// CHECK-NEXT: | [sizeof=16, align=8]
169+
163170
union u0 {
164171
unsigned short d1 __attribute__((packed));
165172
int d2 : 10;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
; Check that an unaligned i128 access get the correct alignment added.
2+
;
3+
; RUN: llc < %s -mtriple=s390x-linux-gnu -stop-after=pre-isel-intrinsic-lowering \
4+
; RUN: | FileCheck %s
5+
6+
define void @f1(ptr %ptr) {
7+
; CHECK: define void @f1(ptr %ptr) {
8+
; CHECK-NEXT: store i128 0, ptr %ptr, align 8
9+
; CHECK-NEXT: ret void
10+
; CHECK-NEXT: }
11+
store i128 0, ptr %ptr
12+
ret void
13+
}

0 commit comments

Comments
 (0)