|
3 | 3 | //
|
4 | 4 | // Check help message.
|
5 | 5 | //
|
| 6 | + |
6 | 7 | // RUN: clang-offload-wrapper --help | FileCheck %s --check-prefix CHECK-HELP
|
7 | 8 | // CHECK-HELP: {{.*}}OVERVIEW: A tool to create a wrapper bitcode for offload target binaries.
|
8 |
| -// CHECK-HELP: {{.*}}Takes offload target binaries as input and produces bitcode file containing |
9 |
| -// CHECK-HELP: {{.*}}target binaries packaged as data and initialization code which registers target |
10 |
| -// CHECK-HELP: {{.*}}binaries in offload runtime. |
| 9 | +// CHECK-HELP: {{.*}}Takes offload target binaries and optional manifest files as input |
| 10 | +// CHECK-HELP: {{.*}}and produces bitcode file containing target binaries packaged as data |
| 11 | +// CHECK-HELP: {{.*}}and initialization code which registers target binaries in the offload |
| 12 | +// CHECK-HELP: {{.*}}runtime. Manifest files format and contents are not restricted and are |
| 13 | +// CHECK-HELP: {{.*}}a subject of agreement between the device compiler and the native |
| 14 | +// CHECK-HELP: {{.*}}runtime for that device. When present, manifest file name should |
| 15 | +// CHECK-HELP: {{.*}}immediately follow the corresponding device image filename on the |
| 16 | +// CHECK-HELP: {{.*}}command line. Options annotating a device binary have effect on all |
| 17 | +// CHECK-HELP: {{.*}}subsequent input, until redefined. For example: |
| 18 | +// CHECK-HELP: {{.*}}$clang-offload-wrapper -host x86_64-pc-linux-gnu \ |
| 19 | +// CHECK-HELP: {{.*}} -kind=sycl -target=spir64 -format=spirv -build-opts=-g \ |
| 20 | +// CHECK-HELP: {{.*}} a.spv a_mf.txt \ |
| 21 | +// CHECK-HELP: {{.*}} -target=xxx -format=native -build-opts="" \ |
| 22 | +// CHECK-HELP: {{.*}} b.bin b_mf.txt \ |
| 23 | +// CHECK-HELP: {{.*}} -kind=openmp \ |
| 24 | +// CHECK-HELP: {{.*}} c.bin |
| 25 | +// CHECK-HELP: {{.*}}will generate an x86 wrapper object (.bc) enclosing the following |
| 26 | +// CHECK-HELP: {{.*}}tuples describing a single device binary each ('-' means 'none') |
| 27 | +// CHECK-HELP: {{.*}}offload kind | target | data format | data | manifest | build options: |
| 28 | +// CHECK-HELP: {{.*}}---------------------------------------------------------------------- |
| 29 | +// CHECK-HELP: {{.*}} sycl | spir64 | spirv | a.spv| a_mf.txt | -g |
| 30 | +// CHECK-HELP: {{.*}} sycl | xxx | native | b.bin| b_mf.txt | - |
| 31 | +// CHECK-HELP: {{.*}} openmp | xxx | native | c.bin| - | - |
11 | 32 | // CHECK-HELP: {{.*}}USAGE: clang-offload-wrapper [options] <input files>
|
12 |
| -// CHECK-HELP: {{.*}}-desc-name=<name> - Specifies offload descriptor symbol name: '.<offload kind>.<name>', and makes it globally visible |
13 |
| -// CHECK-HELP: {{.*}}-emit-entry-table - Emit offload entry table |
14 |
| -// CHECK-HELP: {{.*}}-emit-reg-funcs - Emit [un-]registration functions |
15 |
| -// CHECK-HELP: {{.*}}-o=<filename> - Output filename |
16 |
| -// CHECK-HELP: {{.*}}-reg-func-name=<name> - Offload descriptor registration function name |
17 |
| -// CHECK-HELP: {{.*}}-target=<kind-triple> - Offload kind + target triple of the wrapper object: <offload kind>-<target triple> |
18 |
| -// CHECK-HELP: {{.*}}-unreg-func-name=<name> - Offload descriptor un-registration function name |
| 33 | +// CHECK-HELP: {{.*}}OPTIONS: |
| 34 | +// CHECK-HELP: {{.*}}clang-offload-wrapper options: |
| 35 | +// CHECK-HELP: {{.*}} -build-opts=<string> - build options passed to the offload runtime |
| 36 | +// CHECK-HELP: {{.*}} -desc-name=<name> - Specifies offload descriptor symbol name: '.<offload kind>.<name>', and makes it globally visible |
| 37 | +// CHECK-HELP: {{.*}} -emit-reg-funcs - Emit [un-]registration functions |
| 38 | +// CHECK-HELP: {{.*}} -format - device binary image formats: |
| 39 | +// CHECK-HELP: {{.*}} =none - not set |
| 40 | +// CHECK-HELP: {{.*}} =native - unknown or native |
| 41 | +// CHECK-HELP: {{.*}} =spirv - SPIRV binary |
| 42 | +// CHECK-HELP: {{.*}} =llvmbc - LLVMIR bitcode |
| 43 | +// CHECK-HELP: {{.*}} -host=<triple> - wrapper object target triple |
| 44 | +// CHECK-HELP: {{.*}} -kind - offload kind: |
| 45 | +// CHECK-HELP: {{.*}} =unknown - unknown |
| 46 | +// CHECK-HELP: {{.*}} =host - host |
| 47 | +// CHECK-HELP: {{.*}} =openmp - OpenMP |
| 48 | +// CHECK-HELP: {{.*}} =hip - HIP |
| 49 | +// CHECK-HELP: {{.*}} =sycl - SYCL |
| 50 | +// CHECK-HELP: {{.*}} -o=<filename> - Output filename |
| 51 | +// CHECK-HELP: {{.*}} -reg-func-name=<name> - Offload descriptor registration function name |
| 52 | +// CHECK-HELP: {{.*}} -target=<string> - offload target triple |
| 53 | +// CHECK-HELP: {{.*}} -unreg-func-name=<name> - Offload descriptor un-registration function name |
| 54 | +// CHECK-HELP: {{.*}} -v - verbose output |
19 | 55 |
|
20 | 56 | // -------
|
21 |
| -// Generate a file to wrap. |
| 57 | +// Generate files to wrap. |
22 | 58 | //
|
23 |
| -// RUN: echo 'Content of device file' > %t.tgt |
| 59 | +// RUN: echo 'Content of device file1' > %t1.tgt |
| 60 | +// RUN: echo 'Content of device file2' > %t2.tgt |
| 61 | +// RUN: echo 'Content of device file3' > %t3.tgt |
| 62 | +// RUN: echo 'Content of manifest file1' > %t1_mf.txt |
24 | 63 | //
|
25 | 64 | // -------
|
26 | 65 | // Check bitcode produced by the wrapper tool.
|
27 | 66 | //
|
28 |
| -// RUN: clang-offload-wrapper -target=openmp-x86_64-pc-linux-gnu -o - %t.tgt | llvm-dis | FileCheck %s --check-prefix CHECK-IR |
29 |
| - |
| 67 | +// RUN: clang-offload-wrapper \ |
| 68 | +// RUN: -host=x86_64-pc-linux-gnu \ |
| 69 | +// RUN: -kind=openmp -target=tg2 -format=native %t3.tgt %t1_mf.txt \ |
| 70 | +// RUN: -kind=sycl -target=tg1 -build-opts=-g -format spirv %t1.tgt \ |
| 71 | +// RUN: -target=tg2 -build-opts= -format native %t2.tgt \ |
| 72 | +// RUN: -o - | llvm-dis | FileCheck %s --check-prefix CHECK-IR |
| 73 | + |
| 74 | +// CHECK-IR: source_filename = "offload.wrapper.object" |
30 | 75 | // CHECK-IR: target triple = "x86_64-pc-linux-gnu"
|
31 | 76 |
|
32 |
| -// CHECK-IR-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i{{32|64}}, i32, i32 } |
33 |
| -// CHECK-IR-DAG: [[IMAGETY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* } |
34 |
| -// CHECK-IR-DAG: [[DESCTY:%.+]] = type { i32, [[IMAGETY]]*, [[ENTTY]]*, [[ENTTY]]* } |
| 77 | +// CHECK-IR: [[ENTRYTY:%.+]] = type { i8*, i8*, i64, i32, i32 } |
| 78 | +// CHECK-IR: [[IMGTY:%.+]] = type { i16, i8, i8, i8*, i8*, i8*, i8*, i8*, i8*, [[ENTRYTY]]*, [[ENTRYTY]]* } |
| 79 | +// CHECK-IR: [[DESCTY:%.+]] = type { i16, i16, [[IMGTY]]*, [[ENTRYTY]]*, [[ENTRYTY]]* } |
| 80 | +// CHECK-IR: [[OMP_ENTRIESB:@.+]] = external constant [[ENTRYTY]] |
| 81 | +// CHECK-IR: [[OMP_ENTRIESE:@.+]] = external constant [[ENTRYTY]] |
35 | 82 |
|
36 |
| -// CHECK-IR: [[ENTBEGIN:@.+]] = external constant [[ENTTY]] |
37 |
| -// CHECK-IR: [[ENTEND:@.+]] = external constant [[ENTTY]] |
| 83 | +// CHECK-IR: [[OMP_TGT0:@.+]] = internal unnamed_addr constant [4 x i8] c"tg2\00" |
| 84 | +// CHECK-IR: [[OMP_OPTS0:@.+]] = internal unnamed_addr constant [1 x i8] zeroinitializer |
| 85 | +// CHECK-IR: [[OMP_MANIF0:@.+]] = internal unnamed_addr constant [26 x i8] c"Content of manifest file1\0A" |
| 86 | +// CHECK-IR: [[OMP_BIN0:@.+]] = internal unnamed_addr constant [24 x i8] c"Content of device file3\0A" |
38 | 87 |
|
39 |
| -// CHECK-IR: [[BIN:@.+]] = internal unnamed_addr constant [[BINTY:\[[0-9]+ x i8\]]] c"Content of device file{{.+}}" |
| 88 | +// CHECK-IR: [[OMP_IMGS:@.+]] = internal unnamed_addr constant [1 x [[IMGTY]]] [{{.+}} { i16 1, i8 2, i8 1, i8* [[GEP:getelementptr inbounds]] ([4 x i8], [4 x i8]* [[OMP_TGT0]], i64 0, i64 0), i8* [[GEP]] ([1 x i8], [1 x i8]* [[OMP_OPTS0]], i64 0, i64 0), i8* [[GEP]] ([26 x i8], [26 x i8]* [[OMP_MANIF0]], i64 0, i64 0), i8* [[GEP]] ([26 x i8], [26 x i8]* [[OMP_MANIF0]], i64 1, i64 0), i8* [[GEP]] ([24 x i8], [24 x i8]* [[OMP_BIN0]], i64 0, i64 0), i8* [[GEP]] ([24 x i8], [24 x i8]* [[OMP_BIN0]], i64 1, i64 0), [[ENTRYTY]]* [[OMP_ENTRIESB]], [[ENTRYTY]]* [[OMP_ENTRIESE]] }] |
40 | 89 |
|
41 |
| -// CHECK-IR: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[IMAGETY]]] [{{.+}} { i8* getelementptr inbounds ([[BINTY]], [[BINTY]]* [[BIN]], i64 0, i64 0), i8* getelementptr inbounds ([[BINTY]], [[BINTY]]* [[BIN]], i64 1, i64 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }] |
| 90 | +// CHECK-IR: [[OMP_DESC:@.+]] = internal constant [[DESCTY]] { i16 1, i16 1, [[IMGTY]]* [[GEP]] ([1 x [[IMGTY]]], [1 x [[IMGTY]]]* [[OMP_IMGS]], i64 0, i64 0), [[ENTRYTY]]* [[OMP_ENTRIESB]], [[ENTRYTY]]* [[OMP_ENTRIESE]] } |
42 | 91 |
|
43 |
| -// CHECK-IR: [[DESC:@.+]] = internal constant [[DESCTY]] { i32 1, [[IMAGETY]]* getelementptr inbounds ([1 x [[IMAGETY]]], [1 x [[IMAGETY]]]* [[IMAGES]], i64 0, i64 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] } |
| 92 | +// CHECK-IR: [[SYCL_TGT0:@.+]] = internal unnamed_addr constant [4 x i8] c"tg1\00" |
| 93 | +// CHECK-IR: [[SYCL_OPTS0:@.+]] = internal unnamed_addr constant [3 x i8] c"-g\00" |
| 94 | +// CHECK-IR: [[SYCL_BIN0:@.+]] = internal unnamed_addr constant [24 x i8] c"Content of device file1\0A" |
44 | 95 |
|
45 |
| -// CHECK-IR: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* [[REGFN:@.+]], i8* null }] |
46 |
| -// CHECK-IR: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* [[UNREGFN:@.+]], i8* null }] |
| 96 | +// CHECK-IR: [[SYCL_TGT1:@.+]] = internal unnamed_addr constant [4 x i8] c"tg2\00" |
| 97 | +// CHECK-IR: [[SYCL_OPTS1:@.+]] = internal unnamed_addr constant [1 x i8] zeroinitializer |
| 98 | +// CHECK-IR: [[SYCL_BIN1:@.+]] = internal unnamed_addr constant [24 x i8] c"Content of device file2\0A" |
47 | 99 |
|
48 |
| -// CHECK-IR: define internal void [[REGFN]]() |
49 |
| -// CHECK-IR: call void @__tgt_register_lib([[DESCTY]]* [[DESC]]) |
50 |
| -// CHECK-IR: ret void |
| 100 | +// CHECK-IR: [[SYCL_IMGS:@.+]] = internal unnamed_addr constant [2 x [[IMGTY]]] [{{.+}} { i16 1, i8 4, i8 2, i8* [[GEP]] ([4 x i8], [4 x i8]* [[SYCL_TGT0]], i64 0, i64 0), i8* [[GEP]] ([3 x i8], [3 x i8]* [[SYCL_OPTS0]], i64 0, i64 0), i8* null, i8* null, i8* [[GEP]] ([24 x i8], [24 x i8]* [[SYCL_BIN0]], i64 0, i64 0), i8* [[GEP]] ([24 x i8], [24 x i8]* [[SYCL_BIN0]], i64 1, i64 0), [[ENTRYTY]]* null, [[ENTRYTY]]* null }, [[IMGTY]] { i16 1, i8 4, i8 1, i8* [[GEP]] ([4 x i8], [4 x i8]* [[SYCL_TGT1]], i64 0, i64 0), i8* [[GEP]] ([1 x i8], [1 x i8]* [[SYCL_OPTS1]], i64 0, i64 0), i8* null, i8* null, i8* [[GEP]] ([24 x i8], [24 x i8]* [[SYCL_BIN1]], i64 0, i64 0), i8* [[GEP]] ([24 x i8], [24 x i8]* [[SYCL_BIN1]], i64 1, i64 0), [[ENTRYTY]]* null, [[ENTRYTY]]* null }] |
51 | 101 |
|
52 |
| -// CHECK-IR: declare void @__tgt_register_lib([[DESCTY]]*) |
| 102 | +// CHECK-IR: [[SYCL_DESC:@.+]] = internal constant [[DESCTY]] { i16 1, i16 2, [[IMGTY]]* [[GEP]] ([2 x [[IMGTY]]], [2 x [[IMGTY]]]* [[SYCL_IMGS]], i64 0, i64 0), [[ENTRYTY]]* null, [[ENTRYTY]]* null } |
53 | 103 |
|
54 |
| -// CHECK-IR: define internal void [[UNREGFN]]() |
55 |
| -// CHECK-IR: call void @__tgt_unregister_lib([[DESCTY]]* [[DESC]]) |
56 |
| -// CHECK-IR: ret void |
| 104 | +// CHECK-IR: @llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* [[OMP_REGF:@.+]], i8* null }, { i32, void ()*, i8* } { i32 0, void ()* @.sycl_offloading.descriptor_reg, i8* null }] |
| 105 | + |
| 106 | +// CHECK-IR: @llvm.global_dtors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* [[OMP_UNREGF:@.+]], i8* null }, { i32, void ()*, i8* } { i32 0, void ()* @.sycl_offloading.descriptor_unreg, i8* null }] |
57 | 107 |
|
| 108 | +// CHECK-IR: define internal void [[OMP_REGF]]() section ".text.startup" { |
| 109 | +// CHECK-IR: entry: |
| 110 | +// CHECK-IR: call void @__tgt_register_lib([[DESCTY]]* [[OMP_DESC]]) |
| 111 | +// CHECK-IR: ret void |
| 112 | +// CHECK-IR: } |
| 113 | +// CHECK-IR: declare void @__tgt_register_lib([[DESCTY]]*) |
| 114 | +// CHECK-IR: define internal void [[OMP_UNREGF]]() section ".text.startup" { |
| 115 | +// CHECK-IR: entry: |
| 116 | +// CHECK-IR: call void @__tgt_unregister_lib([[DESCTY]]* [[OMP_DESC]]) |
| 117 | +// CHECK-IR: ret void |
| 118 | +// CHECK-IR: } |
58 | 119 | // CHECK-IR: declare void @__tgt_unregister_lib([[DESCTY]]*)
|
| 120 | +// CHECK-IR: define internal void @.sycl_offloading.descriptor_reg() section ".text.startup" { |
| 121 | +// CHECK-IR: entry: |
| 122 | +// CHECK-IR: call void @__tgt_register_lib([[DESCTY]]* [[SYCL_DESC]]) |
| 123 | +// CHECK-IR: ret void |
| 124 | +// CHECK-IR: } |
| 125 | +// CHECK-IR: define internal void @.sycl_offloading.descriptor_unreg() section ".text.startup" { |
| 126 | +// CHECK-IR: entry: |
| 127 | +// CHECK-IR: call void @__tgt_unregister_lib([[DESCTY]]* [[SYCL_DESC]]) |
| 128 | +// CHECK-IR: ret void |
| 129 | +// CHECK-IR: } |
59 | 130 |
|
60 | 131 | // -------
|
61 |
| -// Check options' effects: -emit-reg-funcs, -emit-entry-table=0, -desc-name |
| 132 | +// Check options' effects: -emit-reg-funcs, -desc-name |
| 133 | +// |
| 134 | +// RUN: echo 'Content of device file' > %t.tgt |
62 | 135 | //
|
63 |
| -// RUN: clang-offload-wrapper -target=sycl-x86_64-pc-linux-gnu -emit-reg-funcs=0 -emit-entry-table=0 -desc-name=lalala -o - %t.tgt | llvm-dis | FileCheck %s --check-prefix CHECK-IR1 |
| 136 | +// RUN: clang-offload-wrapper -kind sycl -host=x86_64-pc-linux-gnu -emit-reg-funcs=0 -desc-name=lalala -o - %t.tgt | llvm-dis | FileCheck %s --check-prefix CHECK-IR1 |
64 | 137 | // CHECK-IR1: source_filename = "offload.wrapper.object"
|
65 |
| -// CHECK-IR1: [[IMAGETY:%.+]] = type { i8*, i8* } |
66 |
| -// CHECK-IR1: [[DESCTY:%.+]] = type { i32, [[IMAGETY]]* } |
| 138 | +// CHECK-IR1: [[IMAGETY:%.+]] = type { i16, i8, i8, i8*, i8*, i8*, i8*, i8*, i8*, %__tgt_offload_entry*, %__tgt_offload_entry* } |
| 139 | +// CHECK-IR1: [[ENTTY:%.+]] = type { i8*, i8*, i64, i32, i32 } |
| 140 | +// CHECK-IR1: [[DESCTY:%.+]] = type { i16, i16, [[IMAGETY]]*, [[ENTTY]]*, [[ENTTY]]* } |
67 | 141 | // CHECK-IR1-NOT: @llvm.global_ctors
|
68 | 142 | // CHECK-IR1-NOT: @llvm.global_dtors
|
69 |
| -// CHECK-IR1: @.sycl_offloading.lalala = constant [[DESCTY]] { i32 1, [[IMAGETY]]* getelementptr inbounds ([1 x [[IMAGETY]]], [1 x [[IMAGETY]]]* @.sycl_offloading.device_images, i64 0, i64 0) } |
| 143 | +// CHECK-IR1: @.sycl_offloading.lalala = constant [[DESCTY]] { i16 1, i16 1, [[IMAGETY]]* getelementptr inbounds ([1 x [[IMAGETY]]], [1 x [[IMAGETY]]]* @.sycl_offloading.device_images, i64 0, i64 0), [[ENTTY]]* null, [[ENTTY]]* null } |
70 | 144 |
|
71 | 145 | // -------
|
72 | 146 | // Check options' effects: -reg-func-name, -unreg-func-name
|
73 | 147 | //
|
74 |
| -// RUN: clang-offload-wrapper -target=sycl-x86_64-pc-linux-gnu -reg-func-name=__REGFUNC__ -unreg-func-name=__UNREGFUNC__ -o - %t.tgt | llvm-dis | FileCheck %s --check-prefix CHECK-IR2 |
| 148 | +// RUN: clang-offload-wrapper -kind sycl -host=x86_64-pc-linux-gnu -reg-func-name=__REGFUNC__ -unreg-func-name=__UNREGFUNC__ -o - %t.tgt | llvm-dis | FileCheck %s --check-prefix CHECK-IR2 |
75 | 149 | // CHECK-IR2: source_filename = "offload.wrapper.object"
|
76 | 150 | // CHECK-IR2: define internal void {{.+}}()
|
77 | 151 | // CHECK-IR2: call void @__REGFUNC__
|
|
0 commit comments