Skip to content

Commit e60a332

Browse files
anoopkg6anoopkg6
andauthored
[JITLink] Add orc-runtime support for SystemZ (#171062)
Add orc-runtime support and tests for SystemZ. Co-authored-by: anoopkg6 <anoopkg6@github.com>
1 parent 86755dd commit e60a332

File tree

12 files changed

+305
-3
lines changed

12 files changed

+305
-3
lines changed

compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ set(ALL_SHADOWCALLSTACK_SUPPORTED_ARCH ${ARM64})
114114

115115
if (UNIX)
116116
if (OS_NAME MATCHES "Linux")
117-
set(ALL_ORC_SUPPORTED_ARCH ${X86_64} ${ARM64} ${ARM32} ${PPC64} ${LOONGARCH64})
117+
set(ALL_ORC_SUPPORTED_ARCH ${X86_64} ${ARM64} ${ARM32} ${PPC64} ${LOONGARCH64} ${S390X})
118118
else()
119119
set(ALL_ORC_SUPPORTED_ARCH ${X86_64} ${ARM64} ${ARM32})
120120
endif()
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %clangxx -fexceptions -fPIC -c -o %t %s
2+
// RUN: %llvm_jitlink %t
3+
4+
extern "C" void llvm_jitlink_setTestResultOverride(long Value);
5+
6+
int main(int argc, char *argv[]) {
7+
llvm_jitlink_setTestResultOverride(1);
8+
try {
9+
throw 0;
10+
} catch (int X) {
11+
llvm_jitlink_setTestResultOverride(X);
12+
}
13+
return 0;
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// REQUIRES: libunwind-available
2+
// RUN: %clangxx -fexceptions -fPIC -c -o %t %s
3+
// RUN: env LD_PRELOAD=%shared_libunwind %llvm_jitlink %t
4+
5+
extern "C" void llvm_jitlink_setTestResultOverride(long Value);
6+
7+
int main(int argc, char *argv[]) {
8+
llvm_jitlink_setTestResultOverride(1);
9+
try {
10+
throw 0;
11+
} catch (int X) {
12+
llvm_jitlink_setTestResultOverride(X);
13+
}
14+
return 0;
15+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
if config.root.host_arch != "s390x":
2+
config.unsupported = True
3+
4+
if config.target_arch != "s390x":
5+
config.unsupported = True
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %clangxx -fPIC -emit-llvm -c -o %t %s
2+
// RUN: %lli_orc_jitlink -relocation-model=pic %t | FileCheck %s
3+
4+
// CHECK: catch
5+
6+
#include <stdio.h>
7+
8+
int main(int argc, char *argv[]) {
9+
try {
10+
throw 0;
11+
} catch (int X) {
12+
puts("catch");
13+
}
14+
return 0;
15+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
; RUN: %lli_orc_jitlink %s | FileCheck %s
2+
3+
; CHECK: constructor
4+
; CHECK-NEXT: main
5+
; CHECK-NEXT: destructor
6+
7+
@__dso_handle = external hidden global i8
8+
@.str = private unnamed_addr constant [5 x i8] c"main\00", align 1
9+
@.str.1 = private unnamed_addr constant [12 x i8] c"constructor\00", align 1
10+
@.str.2 = private unnamed_addr constant [11 x i8] c"destructor\00", align 1
11+
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @constructor, i8* null }]
12+
13+
define dso_local void @destructor(i8* %0) {
14+
%2 = tail call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([11 x i8], [11 x i8]* @.str.2, i64 0, i64 0))
15+
ret void
16+
}
17+
18+
declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*)
19+
20+
; Function Attrs: nofree norecurse nounwind uwtable
21+
define dso_local i32 @main(i32 %0, i8** nocapture readnone %1) local_unnamed_addr #2 {
22+
%3 = tail call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0))
23+
ret i32 0
24+
}
25+
26+
declare i32 @puts(i8* nocapture readonly)
27+
28+
define internal void @constructor() {
29+
%1 = tail call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #5
30+
%2 = tail call i32 @__cxa_atexit(void (i8*)* @destructor, i8* null, i8* nonnull @__dso_handle) #5
31+
ret void
32+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Test that ELF static initializers with different constructor priorities work
2+
// and are executed in the proper order.
3+
//
4+
// RUN: %clang -c -o %t %s
5+
// RUN: %llvm_jitlink %t | FileCheck %s
6+
7+
// CHECK: constructor 100
8+
// CHECK-NEXT: constructor 200
9+
// CHECK-NEXT: constructor 65535
10+
// CHECK-NEXT: main
11+
// CHECK-NEXT: destructor
12+
13+
.text
14+
15+
.globl destructor
16+
.p2align 4, 0x90
17+
.type destructor,@function
18+
destructor:
19+
.Ldestructor$local:
20+
larl %r2, .Lstr.d
21+
jg puts@PLT
22+
23+
.globl main
24+
.p2align 4, 0x90
25+
.type main,@function
26+
main:
27+
.Lmain$local:
28+
stmg %r14, %r15, 112(%r15)
29+
aghi %r15, -160
30+
larl %r2, .Lstr
31+
brasl %r14, puts@PLT
32+
lghi %r2, 0
33+
lmg %r14, %r15, 272(%r15)
34+
br %r14
35+
36+
.p2align 4
37+
.type constructor.65535,@function
38+
constructor.65535:
39+
stmg %r14, %r15, 112(%r15)
40+
aghi %r15, -160
41+
larl %r2, .Lstr.65535
42+
brasl %r14, puts@PLT
43+
lgrl %r4, __dso_handle
44+
lgrl %r2, .Ldestructor$local@GOT
45+
lghi %r3, 0
46+
lmg %r14, %r15, 272(%r15)
47+
jg __cxa_atexit@PLT
48+
49+
.p2align 4
50+
.type constructor.200,@function
51+
constructor.200:
52+
larl %r2, .Lstr.200
53+
jg puts@PLT
54+
55+
.p2align 4
56+
.type constructor.100,@function
57+
constructor.100:
58+
larl %r2, .Lstr.100
59+
jg puts@PLT
60+
61+
.hidden __dso_handle
62+
.section .init_array.101,"aw",@init_array
63+
.p2align 3, 0x0
64+
.quad constructor.100
65+
.section .init_array.200,"aw",@init_array
66+
.p2align 3, 0x0
67+
.quad constructor.200
68+
.section .init_array,"aw",@init_array
69+
.p2align 3, 0x0
70+
.quad constructor.65535
71+
.type .Lstr.d,@object
72+
.section .rodata.str1.2,"aMS",@progbits,1
73+
.p2align 1, 0x0
74+
.Lstr.d:
75+
.asciz "destructor"
76+
.size .Lstr.d, 11
77+
78+
.type .Lstr.100,@object
79+
.p2align 1, 0x0
80+
.Lstr.100:
81+
.asciz "constructor 100"
82+
.size .Lstr.100, 16
83+
84+
.type .Lstr.200,@object
85+
.p2align 1, 0x0
86+
.Lstr.200:
87+
.asciz "constructor 200"
88+
.size .Lstr.200, 16
89+
90+
.type .Lstr.65535,@object
91+
.p2align 1, 0x0
92+
.Lstr.65535:
93+
.asciz "constructor 65535"
94+
.size .Lstr.65535, 18
95+
96+
.type .Lstr,@object
97+
.p2align 1, 0x0
98+
.Lstr:
99+
.asciz "main"
100+
.size .Lstr, 5
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// REQUIRES: disabled
2+
// This test is disabled until a proper atexit interpose can be implemented:
3+
// the current one assumes that atexit is defined in the dylib that calls it,
4+
// which is not true in general. See
5+
// https://github.com/llvm/llvm-project/issues/74641
6+
//
7+
// RUN: %clang -c -o %t %s
8+
// RUN: %llvm_jitlink %t
9+
10+
.text
11+
// OnExit destructor resets the test result override to zero.
12+
.section .text._ZN6OnExitD2Ev,"axG",@progbits,_ZN6OnExitD2Ev,comdat
13+
.p2align 4
14+
.type _ZN6OnExitD2Ev,@function
15+
_ZN6OnExitD2Ev:
16+
.cfi_startproc
17+
lghi %r2, 0
18+
jg llvm_jitlink_setTestResultOverride@PLT
19+
.cfi_endproc
20+
21+
// main registers the atexit and sets the test result to one.
22+
.globl main
23+
.p2align 4
24+
.type main,@function
25+
main:
26+
.cfi_startproc
27+
# %bb.0:
28+
stmg %r14, %r15, 48(%r15)
29+
lgrl %r2, _ZN6OnExitD2Ev@GOT
30+
brasl %r14, atexit@PLT
31+
lghi %r2, 1
32+
brasl %r14, llvm_jitlink_setTestResultOverride@PLT
33+
lghi %r2, 0
34+
lmg %r14, %r15, 48(%r15)
35+
br %r14
36+
.Lfunc_end1:
37+
.size main, .Lfunc_end1-main
38+
.cfi_endproc
39+
40+
.type _ZL6onExit,@object
41+
.local _ZL6onExit
42+
.comm _ZL6onExit,1,2
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Test that the runtime correctly interposes ___cxa_atexit.
2+
//
3+
// RUN: %clang -c -o %t %s
4+
// RUN: %llvm_jitlink %t
5+
6+
.text
7+
// OnExit destructor resets the test result override to zero.
8+
.section .text._ZN6OnExitD2Ev,"axG",@progbits,_ZN6OnExitD2Ev,comdat
9+
.p2align 4
10+
.type _ZN6OnExitD2Ev,@function
11+
_ZN6OnExitD2Ev:
12+
.cfi_startproc
13+
lghi %r2, 0
14+
jg llvm_jitlink_setTestResultOverride@PLT
15+
.cfi_endproc
16+
17+
// main registers the atexit and sets the test result to one.
18+
.globl main
19+
.p2align 4
20+
.type main,@function
21+
main:
22+
.cfi_startproc
23+
# %bb.0:
24+
stmg %r14, %r15, 48(%r15)
25+
lgrl %r2, _ZN6OnExitD2Ev@GOT
26+
lgrl %r4, __dso_handle@GOT
27+
larl %r3, _ZL6onExit
28+
brasl %r14, __cxa_atexit@PLT
29+
lghi %r2, 1
30+
brasl %r14, llvm_jitlink_setTestResultOverride@PLT
31+
lghi %r2, 0
32+
lmg %r14, %r15, 48(%r15)
33+
br %r14
34+
.Lfunc_end1:
35+
.size main, .Lfunc_end1-main
36+
.cfi_endproc
37+
38+
.type _ZL6onExit,@object
39+
.local _ZL6onExit
40+
.comm _ZL6onExit,1,2
41+
.hidden __dso_handle
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Test that basic ELF static initializers work. The main function in this
2+
// test returns the value of 'x', which is initially 1 in the data section,
3+
// and reset to 0 if the _static_init function is run. If the static initializer
4+
// does not run then main will return 1, causing the test to be treated as a
5+
// failure.
6+
//
7+
// RUN: %clang -c -o %t %s
8+
// RUN: %llvm_jitlink %t
9+
10+
.text
11+
12+
.globl main
13+
.p2align 4
14+
main:
15+
lgrl %r1, x@GOT
16+
lgf %r2, 0(%r1)
17+
br %r14
18+
19+
# static initializer sets the value of 'x' to zero.
20+
.p2align 4
21+
_static_init:
22+
lgrl %r1, x@GOT
23+
mvhi 0(%r1), 0
24+
br %r14
25+
26+
.data
27+
.globl x
28+
.p2align 2, 0x0
29+
x:
30+
.long 1
31+
.size x, 4
32+
33+
.section .init_array,"aw",@init_array
34+
.p2align 3, 0x0
35+
.quad _static_init

0 commit comments

Comments
 (0)