Skip to content
Draft
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions clang/test/Driver/Inputs/libsycl.ll
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's put new files to clang/test/Driver/Inputs/SYCL/* directory.

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
; ModuleID = 'libsycl.cpp'
source_filename = "libsycl.cpp"
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1"
target triple = "spirv64"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
; ModuleID = 'libsycl.cpp'
source_filename = "libsycl.cpp"
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1"
target triple = "spirv64"
target triple = "spirv64"

Please, remove from the tests as well.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done as part of upcoming commit. Thanks


; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none)
define spir_func noundef range(i32 -2147483643, -2147483648) i32 @_Z9lib_func1i(i32 noundef %a) local_unnamed_addr #0 {
entry:
%add = add nsw i32 %a, 5
ret i32 %add
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to have simpler code for the library (and tests):

  1. Unmingled names.
  2. No unnecessary attributes.
  3. Less code. Do we need 4 library functions? I would leave just one:
define spir_func i32 addFive(i32 %x) {
  %res = add i32 %x, 5
  ret i32 %res
}

It's easier to maintain and read.


; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none)
define spir_func noundef i32 @_Z9lib_func2i(i32 noundef %a) local_unnamed_addr #0 {
entry:
%mul = mul nsw i32 %a, 5
ret i32 %mul
}

; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none)
define spir_func noundef range(i32 -2147483648, 2147483643) i32 @_Z9lib_func3i(i32 noundef %a) local_unnamed_addr #0 {
entry:
%sub = add nsw i32 %a, -5
ret i32 %sub
}

; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none)
define spir_func noundef i32 @_Z9lib_func4i(i32 noundef %a) local_unnamed_addr #0 {
entry:
%call = tail call spir_func noundef i32 @_Z9lib_func1i(i32 noundef %a)
%call1 = tail call spir_func noundef i32 @_Z9lib_func2i(i32 noundef %a)
%mul = mul nsw i32 %call1, %call
ret i32 %mul
}

attributes #0 = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
28 changes: 28 additions & 0 deletions clang/test/Driver/Inputs/test1.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
; ModuleID = 'test1.cpp'
source_filename = "test1.cpp"
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1"
target triple = "spirv64"

; Function Attrs: mustprogress noinline
define spir_func noundef i32 @_Z9foo_func1ii(i32 noundef %a, i32 noundef %b) local_unnamed_addr #0 {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, use one notation for function prefixes and file names.
Either rename test1.ll to foo.ll and test2.ll to bar.ll or use test1_ and test2_ function name prefixes.

entry:
%call = tail call spir_func noundef i32 @_Z9lib_func4i(i32 noundef %b)
%call1 = tail call spir_func noundef i32 @_Z9bar_func1ii(i32 noundef %a, i32 noundef %call)
ret i32 %call1
}

declare spir_func noundef i32 @_Z9bar_func1ii(i32 noundef, i32 noundef) local_unnamed_addr #1

declare spir_func noundef i32 @_Z9lib_func4i(i32 noundef) local_unnamed_addr #1

; Function Attrs: mustprogress
define spir_func noundef i32 @_Z9foo_func2iii(i32 noundef %c, i32 noundef %d, i32 noundef %e) local_unnamed_addr #2 {
entry:
%call = tail call spir_func noundef i32 @_Z9foo_func1ii(i32 noundef %c, i32 noundef %d)
%mul = mul nsw i32 %call, %e
ret i32 %mul
}

attributes #0 = { mustprogress noinline "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
attributes #1 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
attributes #2 = { mustprogress "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
22 changes: 22 additions & 0 deletions clang/test/Driver/Inputs/test2.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
; ModuleID = 'test2.cpp'
source_filename = "test2.cpp"
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1"
target triple = "spirv64"

; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none)
define spir_func noundef i32 @_Z9bar_func1ii(i32 noundef %a, i32 noundef %b) local_unnamed_addr #0 {
entry:
%add = add nsw i32 %b, %a
ret i32 %add
}

; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
define spir_func noundef i32 @_Z9bar_func2iii(i32 noundef %c, i32 noundef %d, i32 noundef %e) local_unnamed_addr #1 {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove func2 and keep only one function in this test.

entry:
%call = tail call spir_func noundef i32 @_Z9bar_func1ii(i32 noundef %c, i32 noundef %d)
%add = add nsw i32 %call, %e
ret i32 %add
}

attributes #0 = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
attributes #1 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
23 changes: 23 additions & 0 deletions clang/test/Driver/Inputs/test3.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
; ModuleID = 'test3.cpp'
source_filename = "test3.cpp"
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1"
target triple = "spirv64"

; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none)
define spir_func noundef i32 @_Z9bar_func1ii(i32 noundef %a, i32 noundef %b) local_unnamed_addr #0 {
entry:
%mul = shl nsw i32 %a, 1
%add = add nsw i32 %mul, %b
ret i32 %add
}

; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
define spir_func noundef i32 @_Z9baz_func1i(i32 noundef %a) local_unnamed_addr #1 {
entry:
%add = add nsw i32 %a, 5
%call = tail call spir_func noundef i32 @_Z9bar_func1ii(i32 noundef %a, i32 noundef %add)
ret i32 %call
}

attributes #0 = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
attributes #1 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
39 changes: 16 additions & 23 deletions clang/test/Driver/clang-sycl-linker-test.cpp
Original file line number Diff line number Diff line change
@@ -1,31 +1,24 @@
// Tests the clang-sycl-linker tool.
//
// Test a simple case without arguments.
// RUN: %clangxx -emit-llvm -c %s -o %t_1.bc
// RUN: %clangxx -emit-llvm -c %s -o %t_2.bc
// RUN: clang-sycl-linker --dry-run -triple spirv64 %t_1.bc %t_2.bc -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=SIMPLE
// SIMPLE: "{{.*}}llvm-link{{.*}}" {{.*}}.bc {{.*}}.bc -o [[FIRSTLLVMLINKOUT:.*]].bc --suppress-warnings
// SIMPLE-NEXT: "{{.*}}llvm-spirv{{.*}}" {{.*}}-o a.spv [[FIRSTLLVMLINKOUT]].bc
// Test the dry run of a simple case to link two input files.
// RUN: touch %t_1.bc
// RUN: touch %t_2.bc
// RUN: clang-sycl-linker --dry-run -v -triple spirv64 %t_1.bc %t_2.bc -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=SIMPLE-FO
// SIMPLE-FO: sycl-device-link: inputs: {{.*}}.bc, {{.*}}.bc libfiles: output: [[LLVMLINKOUT:.*]].bc
// SIMPLE-FO-NEXT: "{{.*}}llvm-spirv{{.*}}" {{.*}}-o a.spv [[LLVMLINKOUT]].bc
//
// Test that llvm-link is not called when only one input is present.
// RUN: clang-sycl-linker --dry-run -triple spirv64 %t_1.bc -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=SIMPLE-NO-LINK
// SIMPLE-NO-LINK: "{{.*}}llvm-spirv{{.*}}" {{.*}}-o a.spv {{.*}}.bc
//
// Test a simple case with device library files specified.
// Test the dry run of a simple case with device library files specified.
// RUN: touch %T/lib1.bc
// RUN: touch %T/lib2.bc
// RUN: clang-sycl-linker --dry-run -triple spirv64 %t_1.bc %t_2.bc --library-path=%T --device-libs=lib1.bc,lib2.bc -o a.spv 2>&1 \
// RUN: clang-sycl-linker --dry-run -v -triple spirv64 %t_1.bc %t_2.bc --library-path=%T --device-libs=lib1.bc,lib2.bc -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=DEVLIBS
// DEVLIBS: "{{.*}}llvm-link{{.*}}" {{.*}}.bc {{.*}}.bc -o [[FIRSTLLVMLINKOUT:.*]].bc --suppress-warnings
// DEVLIBS-NEXT: "{{.*}}llvm-link{{.*}}" -only-needed [[FIRSTLLVMLINKOUT]].bc {{.*}}lib1.bc {{.*}}lib2.bc -o [[SECONDLLVMLINKOUT:.*]].bc --suppress-warnings
// DEVLIBS-NEXT: "{{.*}}llvm-spirv{{.*}}" {{.*}}-o a.spv [[SECONDLLVMLINKOUT]].bc
// DEVLIBS: sycl-device-link: inputs: {{.*}}.bc libfiles: {{.*}}lib1.bc, {{.*}}lib2.bc output: [[LLVMLINKOUT:.*]].bc
// DEVLIBS-NEXT: "{{.*}}llvm-spirv{{.*}}" {{.*}}-o a.spv [[LLVMLINKOUT]].bc
//
// Test a simple case with .o (fat object) as input.
// TODO: Remove this test once fat object support is added.
// RUN: %clangxx -c %s -o %t.o
// RUN: not clang-sycl-linker --dry-run -triple spirv64 %t.o -o a.spv 2>&1 \
// Test a simple case with a random file (not bitcode) as input.
// RUN: touch %t.o
// RUN: not clang-sycl-linker -triple spirv64 %t.o -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=FILETYPEERROR
// FILETYPEERROR: Unsupported file type
//
Expand All @@ -38,11 +31,11 @@
// DEVLIBSERR2: '{{.*}}lib3.bc' SYCL device library file is not found
//
// Test if correct set of llvm-spirv options are emitted for windows environment.
// RUN: clang-sycl-linker --dry-run -triple spirv64 --is-windows-msvc-env %t_1.bc %t_2.bc -o a.spv 2>&1 \
// RUN: clang-sycl-linker --dry-run -v -triple spirv64 --is-windows-msvc-env %t_1.bc %t_2.bc -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=LLVMOPTSWIN
// LLVMOPTSWIN: -spirv-debug-info-version=ocl-100 -spirv-allow-extra-diexpressions -spirv-allow-unknown-intrinsics=llvm.genx. -spirv-ext=
//
// Test if correct set of llvm-spirv options are emitted for linux environment.
// RUN: clang-sycl-linker --dry-run -triple spirv64 %t_1.bc %t_2.bc -o a.spv 2>&1 \
// RUN: clang-sycl-linker --dry-run -v -triple spirv64 %t_1.bc %t_2.bc -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=LLVMOPTSLIN
// LLVMOPTSLIN: -spirv-debug-info-version=nonsemantic-shader-200 -spirv-allow-unknown-intrinsics=llvm.genx. -spirv-ext=
22 changes: 22 additions & 0 deletions clang/test/Driver/link-device-code.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# RUN: llvm-as %S/Inputs/test1.ll -o %t.test1.bc
# RUN: llvm-as %S/Inputs/test2.ll -o %t.test2.bc
# RUN: llvm-as %S/Inputs/test3.ll -o %t.test3.bc
# RUN: llvm-as %S/Inputs/libsycl.ll -o %t.libsycl.bc
# RUN: clang-sycl-linker %t.test1.bc %t.test2.bc -triple spirv64 -o test.spv --print-linked-module 2>&1 | FileCheck %s --check-prefix=CHECK-SIMPLE

# RUN: not clang-sycl-linker %t.test2.bc %t.test3.bc -triple spirv64 -o test.spv --print-linked-module 2>&1 | FileCheck %s --check-prefix=CHECK-MULTIPLE-DEFS

# RUN: clang-sycl-linker %t.test1.bc %t.test2.bc -device-libs=%t.libsycl.bc -library-path= -triple spirv64 -o test.spv --print-linked-module 2>&1 | FileCheck %s --check-prefix=CHECK-DEVICE-LIB

; CHECK-SIMPLE: define {{.*}}foo_func1{{.*}}
; CHECK-SIMPLE: define {{.*}}foo_func2{{.*}}
; CHECK-SIMPLE: define {{.*}}bar_func1{{.*}}
; CHECK-SIMPLE: define {{.*}}bar_func2{{.*}}

;CHECK-MULTIPLE-DEFS: error: Linking globals named {{.*}}bar_func1{{.*}} symbol multiply defined!

; CHECK-DEVICE-LIB: define {{.*}}foo_func1{{.*}}
; CHECK-DEVICE-LIB: define {{.*}}foo_func2{{.*}}
; CHECK-DEVICE-LIB: define {{.*}}bar_func1{{.*}}
; CHECK-DEVICE-LIB: define {{.*}}bar_func2{{.*}}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CHECK-DEVICE-LIB doesn't check that device libraries are linked.
I would also check that CHECK-SIMPLE doesn't define library functions.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updating the tests now.
Thanks


4 changes: 4 additions & 0 deletions clang/tools/clang-sycl-linker/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
set(LLVM_LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
BinaryFormat
BitWriter
Core
IRReader
Linker
Option
Object
TargetParser
Expand Down
Loading