diff --git a/test/OpGroupIAdd.spt b/test/OpGroupIAdd.spt new file mode 100644 index 0000000000..cb1deb1260 --- /dev/null +++ b/test/OpGroupIAdd.spt @@ -0,0 +1,38 @@ +119734787 65536 393230 13 0 +2 Capability Addresses +2 Capability Kernel +2 Capability Groups +5 ExtInstImport 1 "OpenCL.std" +3 MemoryModel 1 2 +10 EntryPoint 6 6 "testWorkGroupIAddUnsigned" +3 Source 3 200000 +3 Name 7 "a" +4 Decorate 8 FuncParamAttr 5 +4 TypeInt 3 32 0 +4 Constant 3 11 2 +2 TypeVoid 2 +4 TypePointer 4 5 3 +5 TypeFunction 5 2 3 4 + + +5 Function 2 6 0 5 +3 FunctionParameter 3 7 +3 FunctionParameter 4 8 + +2 Label 9 +6 GroupIAdd 3 10 11 0 7 +5 Store 8 10 2 4 +1 Return + +1 FunctionEnd + +; TODO: This currently maps to _Z21work_group_reduce_addi, but should map +; to _Z21work_group_reduce_addj, instead. Remove this test and update +; test/transcoding/group_ops.cl when fixing this. +; XFAIL: * +; RUN: llvm-spirv %s -to-binary -o %t.spv +; RUN: spirv-val %t.spv +; RUN: llvm-spirv -r %t.spv -o %t.bc +; RUN: llvm-dis < %t.bc | FileCheck %s + +; CHECK: call spir_func i32 @_Z21work_group_reduce_addj(i32 %a) diff --git a/test/transcoding/DivRem.cl b/test/transcoding/DivRem.cl new file mode 100644 index 0000000000..dfb67f7c2c --- /dev/null +++ b/test/transcoding/DivRem.cl @@ -0,0 +1,76 @@ +// RUN: %clang_cc1 -triple spir-unknown-unknown -O1 -cl-std=CL2.0 -finclude-default-header -emit-llvm-bc %s -o %t.bc +// RUN: llvm-spirv %t.bc -spirv-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV +// RUN: llvm-spirv %t.bc -o %t.spv +// RUN: spirv-val %t.spv +// RUN: llvm-spirv -r %t.spv -o %t.rev.bc +// RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM + +// CHECK-SPIRV-DAG: TypeInt [[int:[0-9]+]] 32 0 +// CHECK-SPIRV-DAG: TypeVector [[int2:[0-9]+]] [[int]] 2 +// CHECK-SPIRV-DAG: TypeFloat [[float:[0-9]+]] 32 +// CHECK-SPIRV-DAG: TypeVector [[float2:[0-9]+]] [[float]] 2 + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +// CHECK-SPIRV: SDiv [[int2]] {{[0-9]+}} [[A]] [[B]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testSDiv +// CHECK-LLVM: sdiv <2 x i32> %a, %b + +kernel void testSDiv(int2 a, int2 b, global int2 *res) { + res[0] = a / b; +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +// CHECK-SPIRV: UDiv [[int2]] {{[0-9]+}} [[A]] [[B]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testUDiv +// CHECK-LLVM: udiv <2 x i32> %a, %b + +kernel void testUDiv(uint2 a, uint2 b, global uint2 *res) { + res[0] = a / b; +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +// CHECK-SPIRV: FDiv [[float2]] {{[0-9]+}} [[A]] [[B]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testFDiv +// CHECK-LLVM: fdiv <2 x float> %a, %b + +kernel void testFDiv(float2 a, float2 b, global float2 *res) { + res[0] = a / b; +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +// CHECK-SPIRV: SRem [[int2]] {{[0-9]+}} [[A]] [[B]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testSRem +// CHECK-LLVM: srem <2 x i32> %a, %b + +kernel void testSRem(int2 a, int2 b, global int2 *res) { + res[0] = a % b; +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +// CHECK-SPIRV: UMod [[int2]] {{[0-9]+}} [[A]] [[B]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testUMod +// CHECK-LLVM: urem <2 x i32> %a, %b + +kernel void testUMod(uint2 a, uint2 b, global uint2 *res) { + res[0] = a % b; +} diff --git a/test/transcoding/RelationalOperators.cl b/test/transcoding/RelationalOperators.cl new file mode 100644 index 0000000000..7823b2e478 --- /dev/null +++ b/test/transcoding/RelationalOperators.cl @@ -0,0 +1,191 @@ +// RUN: %clang_cc1 -triple spir-unknown-unknown -O1 -cl-std=CL2.0 -finclude-default-header -emit-llvm-bc %s -o %t.bc +// RUN: llvm-spirv %t.bc -spirv-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV +// RUN: llvm-spirv %t.bc -o %t.spv +// RUN: spirv-val %t.spv +// RUN: llvm-spirv -r %t.spv -o %t.rev.bc +// RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM + +// CHECK-SPIRV: TypeBool [[bool:[0-9]+]] +// CHECK-SPIRV: TypeVector [[bool2:[0-9]+]] [[bool]] 2 + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +// CHECK-SPIRV: UGreaterThan [[bool2]] {{[0-9]+}} [[A]] [[B]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testUGreaterThan +// CHECK-LLVM: icmp ugt <2 x i32> %a, %b + +kernel void testUGreaterThan(uint2 a, uint2 b, global int2 *res) { + res[0] = a > b; +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +// CHECK-SPIRV: SGreaterThan [[bool2]] {{[0-9]+}} [[A]] [[B]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testSGreaterThan +// CHECK-LLVM: icmp sgt <2 x i32> %a, %b + +kernel void testSGreaterThan(int2 a, int2 b, global int2 *res) { + res[0] = a > b; +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +// CHECK-SPIRV: UGreaterThanEqual [[bool2]] {{[0-9]+}} [[A]] [[B]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testUGreaterThanEqual +// CHECK-LLVM: icmp uge <2 x i32> %a, %b + +kernel void testUGreaterThanEqual(uint2 a, uint2 b, global int2 *res) { + res[0] = a >= b; +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +// CHECK-SPIRV: SGreaterThanEqual [[bool2]] {{[0-9]+}} [[A]] [[B]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testSGreaterThanEqual +// CHECK-LLVM: icmp sge <2 x i32> %a, %b + +kernel void testSGreaterThanEqual(int2 a, int2 b, global int2 *res) { + res[0] = a >= b; +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +// CHECK-SPIRV: ULessThan [[bool2]] {{[0-9]+}} [[A]] [[B]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testULessThan +// CHECK-LLVM: icmp ult <2 x i32> %a, %b + +kernel void testULessThan(uint2 a, uint2 b, global int2 *res) { + res[0] = a < b; +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +// CHECK-SPIRV: SLessThan [[bool2]] {{[0-9]+}} [[A]] [[B]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testSLessThan +// CHECK-LLVM: icmp slt <2 x i32> %a, %b + +kernel void testSLessThan(int2 a, int2 b, global int2 *res) { + res[0] = a < b; +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +// CHECK-SPIRV: ULessThanEqual [[bool2]] {{[0-9]+}} [[A]] [[B]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testULessThanEqual +// CHECK-LLVM: icmp ule <2 x i32> %a, %b + +kernel void testULessThanEqual(uint2 a, uint2 b, global int2 *res) { + res[0] = a <= b; +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +// CHECK-SPIRV: SLessThanEqual [[bool2]] {{[0-9]+}} [[A]] [[B]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testSLessThanEqual +// CHECK-LLVM: icmp sle <2 x i32> %a, %b + +kernel void testSLessThanEqual(int2 a, int2 b, global int2 *res) { + res[0] = a <= b; +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +// CHECK-SPIRV: FOrdEqual [[bool2]] {{[0-9]+}} [[A]] [[B]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testFOrdEqual +// CHECK-LLVM: fcmp oeq <2 x float> %a, %b + +kernel void testFOrdEqual(float2 a, float2 b, global int2 *res) { + res[0] = a == b; +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +// CHECK-SPIRV: FUnordNotEqual [[bool2]] {{[0-9]+}} [[A]] [[B]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testFUnordNotEqual +// CHECK-LLVM: fcmp une <2 x float> %a, %b + +kernel void testFUnordNotEqual(float2 a, float2 b, global int2 *res) { + res[0] = a != b; +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +// CHECK-SPIRV: FOrdGreaterThan [[bool2]] {{[0-9]+}} [[A]] [[B]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testFOrdGreaterThan +// CHECK-LLVM: fcmp ogt <2 x float> %a, %b + +kernel void testFOrdGreaterThan(float2 a, float2 b, global int2 *res) { + res[0] = a > b; +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +// CHECK-SPIRV: FOrdGreaterThanEqual [[bool2]] {{[0-9]+}} [[A]] [[B]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testFOrdGreaterThanEqual +// CHECK-LLVM: fcmp oge <2 x float> %a, %b + +kernel void testFOrdGreaterThanEqual(float2 a, float2 b, global int2 *res) { + res[0] = a >= b; +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +// CHECK-SPIRV: FOrdLessThan [[bool2]] {{[0-9]+}} [[A]] [[B]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testFOrdLessThan +// CHECK-LLVM: fcmp olt <2 x float> %a, %b + +kernel void testFOrdLessThan(float2 a, float2 b, global int2 *res) { + res[0] = a < b; +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +// CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +// CHECK-SPIRV: FOrdLessThanEqual [[bool2]] {{[0-9]+}} [[A]] [[B]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testFOrdLessThanEqual +// CHECK-LLVM: fcmp ole <2 x float> %a, %b + +kernel void testFOrdLessThanEqual(float2 a, float2 b, global int2 *res) { + res[0] = a <= b; +} diff --git a/test/transcoding/RelationalOperatorsFOrd.ll b/test/transcoding/RelationalOperatorsFOrd.ll new file mode 100644 index 0000000000..cced9fd01f --- /dev/null +++ b/test/transcoding/RelationalOperatorsFOrd.ll @@ -0,0 +1,43 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv %t.bc -spirv-text -o %t.txt +; RUN: FileCheck < %t.txt %s --check-prefix=CHECK-SPIRV +; RUN: llvm-spirv %t.bc -o %t.spv +; RUN: llvm-spirv -r %t.spv -o %t.rev.bc +; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM + +; CHECK-SPIRV: TypeBool [[bool:[0-9]+]] +; CHECK-SPIRV: TypeVector [[bool2:[0-9]+]] [[bool]] 2 + +target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024" +target triple = "spir-unknown-unknown" + +; CHECK-SPIRV-LABEL: 5 Function +; CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +; CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +; CHECK-SPIRV: 5 FOrdNotEqual [[bool2]] {{[0-9]+}} [[A]] [[B]] +; CHECK-SPIRV: FunctionEnd + +; CHECK-LLVM-LABEL: @testFOrdNotEqual +; CHECK-LLVM: fcmp one <2 x float> %a, %b + +; Function Attrs: nounwind +define spir_kernel void @testFOrdNotEqual(<2 x float> %a, <2 x float> %b) #0 !kernel_arg_addr_space !2 !kernel_arg_access_qual !3 !kernel_arg_type !4 !kernel_arg_type_qual !5 !kernel_arg_base_type !4 { +entry: + %0 = fcmp one <2 x float> %a, %b + ret void +} + +attributes #0 = { nounwind } + +!opencl.enable.FP_CONTRACT = !{} +!opencl.spir.version = !{!0} +!opencl.ocl.version = !{!0} +!opencl.used.extensions = !{!1} +!opencl.used.optional.core.features = !{!1} + +!0 = !{i32 2, i32 0} +!1 = !{} +!2 = !{i32 0, i32 0} +!3 = !{!"none", !"none"} +!4 = !{!"float2", !"float2"} +!5 = !{!"", !""} diff --git a/test/transcoding/RelationalOperatorsFUnord.ll b/test/transcoding/RelationalOperatorsFUnord.ll new file mode 100644 index 0000000000..8dd1801bf5 --- /dev/null +++ b/test/transcoding/RelationalOperatorsFUnord.ll @@ -0,0 +1,107 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv %t.bc -spirv-text -o %t.txt +; RUN: FileCheck < %t.txt %s --check-prefix=CHECK-SPIRV +; RUN: llvm-spirv %t.bc -o %t.spv +; RUN: llvm-spirv -r %t.spv -o %t.rev.bc +; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM + +; CHECK-SPIRV: TypeBool [[bool:[0-9]+]] +; CHECK-SPIRV: TypeVector [[bool2:[0-9]+]] [[bool]] 2 + +target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024" +target triple = "spir-unknown-unknown" + +; CHECK-SPIRV-LABEL: 5 Function +; CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +; CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +; CHECK-SPIRV: 5 FUnordEqual [[bool2]] {{[0-9]+}} [[A]] [[B]] +; CHECK-SPIRV: FunctionEnd + +; CHECK-LLVM-LABEL: @testFUnordEqual +; CHECK-LLVM: fcmp ueq <2 x float> %a, %b + +; Function Attrs: nounwind +define spir_kernel void @testFUnordEqual(<2 x float> %a, <2 x float> %b) #0 !kernel_arg_addr_space !2 !kernel_arg_access_qual !3 !kernel_arg_type !4 !kernel_arg_type_qual !5 !kernel_arg_base_type !4 { +entry: + %0 = fcmp ueq <2 x float> %a, %b + ret void +} + +; CHECK-SPIRV-LABEL: 5 Function +; CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +; CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +; CHECK-SPIRV: 5 FUnordGreaterThan [[bool2]] {{[0-9]+}} [[A]] [[B]] +; CHECK-SPIRV: FunctionEnd + +; CHECK-LLVM-LABEL: @testFUnordGreaterThan +; CHECK-LLVM: fcmp ugt <2 x float> %a, %b + +; Function Attrs: nounwind +define spir_kernel void @testFUnordGreaterThan(<2 x float> %a, <2 x float> %b) #0 !kernel_arg_addr_space !2 !kernel_arg_access_qual !3 !kernel_arg_type !4 !kernel_arg_type_qual !5 !kernel_arg_base_type !4 { +entry: + %0 = fcmp ugt <2 x float> %a, %b + ret void +} + +; CHECK-SPIRV-LABEL: 5 Function +; CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +; CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +; CHECK-SPIRV: 5 FUnordGreaterThanEqual [[bool2]] {{[0-9]+}} [[A]] [[B]] +; CHECK-SPIRV: FunctionEnd + +; CHECK-LLVM-LABEL: @testFUnordGreaterThanEqual +; CHECK-LLVM: fcmp uge <2 x float> %a, %b + +; Function Attrs: nounwind +define spir_kernel void @testFUnordGreaterThanEqual(<2 x float> %a, <2 x float> %b) #0 !kernel_arg_addr_space !2 !kernel_arg_access_qual !3 !kernel_arg_type !4 !kernel_arg_type_qual !5 !kernel_arg_base_type !4 { +entry: + %0 = fcmp uge <2 x float> %a, %b + ret void +} + +; CHECK-SPIRV-LABEL: 5 Function +; CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +; CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +; CHECK-SPIRV: 5 FUnordLessThan [[bool2]] {{[0-9]+}} [[A]] [[B]] +; CHECK-SPIRV: FunctionEnd + +; CHECK-LLVM-LABEL: @testFUnordLessThan +; CHECK-LLVM: fcmp ult <2 x float> %a, %b + +; Function Attrs: nounwind +define spir_kernel void @testFUnordLessThan(<2 x float> %a, <2 x float> %b) #0 !kernel_arg_addr_space !2 !kernel_arg_access_qual !3 !kernel_arg_type !4 !kernel_arg_type_qual !5 !kernel_arg_base_type !4 { +entry: + %0 = fcmp ult <2 x float> %a, %b + ret void +} + +; CHECK-SPIRV-LABEL: 5 Function +; CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[A:[0-9]+]] +; CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[B:[0-9]+]] +; CHECK-SPIRV: 5 FUnordLessThanEqual [[bool2]] {{[0-9]+}} [[A]] [[B]] +; CHECK-SPIRV: FunctionEnd + +; CHECK-LLVM-LABEL: @testFUnordLessThanEqual +; CHECK-LLVM: fcmp ule <2 x float> %a, %b + +; Function Attrs: nounwind +define spir_kernel void @testFUnordLessThanEqual(<2 x float> %a, <2 x float> %b) #0 !kernel_arg_addr_space !2 !kernel_arg_access_qual !3 !kernel_arg_type !4 !kernel_arg_type_qual !5 !kernel_arg_base_type !4 { +entry: + %0 = fcmp ule <2 x float> %a, %b + ret void +} + +attributes #0 = { nounwind } + +!opencl.enable.FP_CONTRACT = !{} +!opencl.spir.version = !{!0} +!opencl.ocl.version = !{!0} +!opencl.used.extensions = !{!1} +!opencl.used.optional.core.features = !{!1} + +!0 = !{i32 2, i32 0} +!1 = !{} +!2 = !{i32 0, i32 0} +!3 = !{!"none", !"none"} +!4 = !{!"float2", !"float2"} +!5 = !{!"", !""} diff --git a/test/transcoding/group_ops.cl b/test/transcoding/group_ops.cl new file mode 100644 index 0000000000..b90aba7eae --- /dev/null +++ b/test/transcoding/group_ops.cl @@ -0,0 +1,182 @@ +// RUN: %clang_cc1 -triple spir-unknown-unknown -O1 -cl-std=CL2.0 -finclude-default-header -emit-llvm-bc %s -o %t.bc +// RUN: llvm-spirv %t.bc -spirv-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV +// RUN: llvm-spirv %t.bc -o %t.spv +// RUN: spirv-val %t.spv +// RUN: llvm-spirv -r %t.spv -o %t.rev.bc +// RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM + +// CHECK-SPIRV-DAG: TypeInt [[int:[0-9]+]] 32 0 +// CHECK-SPIRV-DAG: TypeFloat [[float:[0-9]+]] 32 +// CHECK-SPIRV-DAG: Constant [[int]] [[ScopeWorkgroup:[0-9]+]] 2 +// CHECK-SPIRV-DAG: Constant [[int]] [[ScopeSubgroup:[0-9]+]] 3 + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV: GroupFMax [[float]] {{[0-9]+}} [[ScopeWorkgroup]] 0 +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testWorkGroupFMax +// CHECK-LLVM: call spir_func float @_Z21work_group_reduce_maxf(float %a) + +kernel void testWorkGroupFMax(float a, global float *res) { + res[0] = work_group_reduce_max(a); +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV: GroupFMin [[float]] {{[0-9]+}} [[ScopeWorkgroup]] 0 +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testWorkGroupFMin +// CHECK-LLVM: call spir_func float @_Z21work_group_reduce_minf(float %a) + +kernel void testWorkGroupFMin(float a, global float *res) { + res[0] = work_group_reduce_min(a); +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV: GroupFAdd [[float]] {{[0-9]+}} [[ScopeWorkgroup]] 0 +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testWorkGroupFAdd +// CHECK-LLVM: call spir_func float @_Z21work_group_reduce_addf(float %a) + +kernel void testWorkGroupFAdd(float a, global float *res) { + res[0] = work_group_reduce_add(a); +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV: GroupFMax [[float]] {{[0-9]+}} [[ScopeWorkgroup]] 1 +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testWorkGroupScanInclusiveFMax +// CHECK-LLVM: call spir_func float @_Z29work_group_scan_inclusive_maxf(float %a) + +kernel void testWorkGroupScanInclusiveFMax(float a, global float *res) { + res[0] = work_group_scan_inclusive_max(a); +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV: GroupFMax [[float]] {{[0-9]+}} [[ScopeWorkgroup]] 2 +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testWorkGroupScanExclusiveFMax +// CHECK-LLVM: call spir_func float @_Z29work_group_scan_exclusive_maxf(float %a) + +kernel void testWorkGroupScanExclusiveFMax(float a, global float *res) { + res[0] = work_group_scan_exclusive_max(a); +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV: GroupSMax [[int]] {{[0-9]+}} [[ScopeWorkgroup]] 0 +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testWorkGroupSMax +// CHECK-LLVM: call spir_func i32 @_Z21work_group_reduce_maxi(i32 %a) + +kernel void testWorkGroupSMax(int a, global int *res) { + res[0] = work_group_reduce_max(a); +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV: GroupSMin [[int]] {{[0-9]+}} [[ScopeWorkgroup]] 0 +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testWorkGroupSMin +// CHECK-LLVM: call spir_func i32 @_Z21work_group_reduce_mini(i32 %a) + +kernel void testWorkGroupSMin(int a, global int *res) { + res[0] = work_group_reduce_min(a); +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV: GroupIAdd [[int]] {{[0-9]+}} [[ScopeWorkgroup]] 0 +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testWorkGroupIAddSigned +// TODO: This should map to _Z21work_group_reduce_addj, instead. +// Update this test and remove OpGroupIAdd.spt when fixing this. +// CHECK-LLVM: call spir_func i32 @_Z21work_group_reduce_addi(i32 %a) + +kernel void testWorkGroupIAddSigned(int a, global int *res) { + res[0] = work_group_reduce_add(a); +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV: GroupIAdd [[int]] {{[0-9]+}} [[ScopeWorkgroup]] 0 +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testWorkGroupIAddUnsigned +// TODO: This should map to _Z21work_group_reduce_addj, instead. +// Update this test and remove OpGroupIAdd.spt when fixing this. +// CHECK-LLVM: call spir_func i32 @_Z21work_group_reduce_addi(i32 %a) + +kernel void testWorkGroupIAddUnsigned(uint a, global uint *res) { + res[0] = work_group_reduce_add(a); +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV: GroupUMax [[int]] {{[0-9]+}} [[ScopeWorkgroup]] 0 +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testWorkGroupUMax +// CHECK-LLVM: call spir_func i32 @_Z21work_group_reduce_maxj(i32 %a) + +kernel void testWorkGroupUMax(uint a, global uint *res) { + res[0] = work_group_reduce_max(a); +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV: GroupUMax [[int]] {{[0-9]+}} [[ScopeSubgroup]] 0 +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testSubGroupUMax +// CHECK-LLVM: call spir_func i32 @_Z20sub_group_reduce_maxj(i32 %a) + +#pragma OPENCL EXTENSION cl_khr_subgroups: enable +kernel void testSubGroupUMax(uint a, global uint *res) { + res[0] = sub_group_reduce_max(a); +} +#pragma OPENCL EXTENSION cl_khr_subgroups: disable + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV: GroupUMax [[int]] {{[0-9]+}} [[ScopeWorkgroup]] 1 +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testWorkGroupScanInclusiveUMax +// CHECK-LLVM: call spir_func i32 @_Z29work_group_scan_inclusive_maxj(i32 %a) + +kernel void testWorkGroupScanInclusiveUMax(uint a, global uint *res) { + res[0] = work_group_scan_inclusive_max(a); +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV: GroupUMax [[int]] {{[0-9]+}} [[ScopeWorkgroup]] 2 +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testWorkGroupScanExclusiveUMax +// CHECK-LLVM: call spir_func i32 @_Z29work_group_scan_exclusive_maxj(i32 %a) + +kernel void testWorkGroupScanExclusiveUMax(uint a, global uint *res) { + res[0] = work_group_scan_exclusive_max(a); +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV: GroupUMin [[int]] {{[0-9]+}} [[ScopeWorkgroup]] 0 +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testWorkGroupUMin +// CHECK-LLVM: call spir_func i32 @_Z21work_group_reduce_minj(i32 %a) + +kernel void testWorkGroupUMin(uint a, global uint *res) { + res[0] = work_group_reduce_min(a); +} + +// CHECK-SPIRV-LABEL: 5 Function +// CHECK-SPIRV: GroupBroadcast [[int]] {{[0-9]+}} [[ScopeWorkgroup]] +// CHECK-SPIRV: FunctionEnd + +// CHECK-LLVM-LABEL: @testWorkGroupBroadcast +// CHECK-LLVM: call spir_func i32 @_Z20work_group_broadcast{{[ji]}}{{[jm]}}(i32 %a, i32 %0) + +kernel void testWorkGroupBroadcast(uint a, global size_t *id, global int *res) { + res[0] = work_group_broadcast(a, *id); +}