xref: /llvm-project/clang/test/CodeGen/SystemZ/align-systemz.c (revision 521b4682a55eb735b75e08d5f71c8cbe47395e40)
1 // RUN: %clang_cc1 -triple s390x-linux-gnu -emit-llvm %s -o - | FileCheck %s
2 
3 // SystemZ prefers to align all global variables to two bytes.
4 
5 struct test {
6    signed char a;
7 };
8 
9 char c;
10 // CHECK-DAG: @c ={{.*}} global i8 0, align 2
11 
12 struct test s;
13 // CHECK-DAG: @s ={{.*}} global %struct.test zeroinitializer, align 2
14 
15 extern char ec;
16 // CHECK-DAG: @ec = external global i8, align 2
17 
18 extern struct test es;
19 // CHECK-DAG: @es = external global %struct.test, align 2
20 
21 // Dummy function to make sure external symbols are used.
func(void)22 void func (void)
23 {
24   c = ec;
25   s = es;
26 }
27 
28 // Test that a global variable with an incomplete type gets the minimum
29 // alignment of 2 per the ABI if no alignment was specified by user.
30 //
31 // CHECK-DAG: @VarNoAl {{.*}} align 2
32 // CHECK-DAG: @VarExplAl1  {{.*}} align 1
33 // CHECK-DAG: @VarExplAl4  {{.*}} align 4
34 struct incomplete_ty;
35 extern struct incomplete_ty VarNoAl;
36 extern struct incomplete_ty __attribute__((aligned(1))) VarExplAl1;
37 extern struct incomplete_ty __attribute__((aligned(4))) VarExplAl4;
fun0(void)38 struct incomplete_ty *fun0 (void) { return &VarNoAl; }
fun1(void)39 struct incomplete_ty *fun1 (void) { return &VarExplAl1; }
fun2(void)40 struct incomplete_ty *fun2 (void) { return &VarExplAl4; }
41 
42 // The SystemZ ABI aligns __int128_t to only eight bytes.
43 
44 struct S_int128 {  __int128_t B; } Obj_I128;
45 __int128_t GlobI128;
46 // CHECK: @Obj_I128 = global %struct.S_int128 zeroinitializer, align 8
47 // CHECK: @GlobI128 = global i128 0, align 8
48 
49 
50 // Alignment should be respected for coerced argument loads
51 
52 struct arg { long y __attribute__((packed, aligned(4))); };
53 
54 extern struct arg x;
55 void f(struct arg);
56 
test(void)57 void test (void)
58 {
59   f(x);
60 }
61 
62 // CHECK-LABEL: @test
63 // CHECK: load i64, ptr @x, align 4
64