The patch adds SPIRVPrepareFunctions pass, which modifies function signatures containing aggregate arguments and/or return values before IR translation. Information about the original signatures is stored in metadata. It is used during call lowering to restore correct SPIR-V types of function arguments and return values. This pass also substitutes some llvm intrinsic calls to function calls, generating the necessary functions in the module, as the SPIRV translator does. The patch also includes changes in other modules, fixing errors and enabling many SPIR-V features that were omitted earlier. And 15 LIT tests are also added to demonstrate the new functionality. Differential Revision: https://reviews.llvm.org/D129730 Co-authored-by: Aleksandr Bezzubikov <zuban32s@gmail.com> Co-authored-by: Michal Paszkowski <michal.paszkowski@outlook.com> Co-authored-by: Andrey Tretyakov <andrey1.tretyakov@intel.com> Co-authored-by: Konrad Trifunovic <konrad.trifunovic@intel.com>
92 lines
2.6 KiB
LLVM
92 lines
2.6 KiB
LLVM
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
|
|
|
|
; CHECK-DAG: OpName [[SCALAR_ADD:%.+]] "scalar_add"
|
|
; CHECK-DAG: OpName [[SCALAR_SUB:%.+]] "scalar_sub"
|
|
; CHECK-DAG: OpName [[SCALAR_MUL:%.+]] "scalar_mul"
|
|
; CHECK-DAG: OpName [[SCALAR_UDIV:%.+]] "scalar_udiv"
|
|
; CHECK-DAG: OpName [[SCALAR_SDIV:%.+]] "scalar_sdiv"
|
|
; TODO: add tests for urem + srem
|
|
; TODO: add test for OpSNegate
|
|
|
|
; CHECK-NOT: DAG-FENCE
|
|
|
|
; CHECK-DAG: [[SCALAR:%.+]] = OpTypeInt 32
|
|
; CHECK-DAG: [[SCALAR_FN:%.+]] = OpTypeFunction [[SCALAR]] [[SCALAR]] [[SCALAR]]
|
|
|
|
; CHECK-NOT: DAG-FENCE
|
|
|
|
|
|
; Test add on scalar:
|
|
define i32 @scalar_add(i32 %a, i32 %b) {
|
|
%c = add i32 %a, %b
|
|
ret i32 %c
|
|
}
|
|
|
|
; CHECK: [[SCALAR_ADD]] = OpFunction [[SCALAR]] None [[SCALAR_FN]]
|
|
; CHECK-NEXT: [[A:%.+]] = OpFunctionParameter [[SCALAR]]
|
|
; CHECK-NEXT: [[B:%.+]] = OpFunctionParameter [[SCALAR]]
|
|
; CHECK: OpLabel
|
|
; CHECK: [[C:%.+]] = OpIAdd [[SCALAR]] [[A]] [[B]]
|
|
; CHECK: OpReturnValue [[C]]
|
|
; CHECK-NEXT: OpFunctionEnd
|
|
|
|
|
|
; Test sub on scalar:
|
|
define i32 @scalar_sub(i32 %a, i32 %b) {
|
|
%c = sub i32 %a, %b
|
|
ret i32 %c
|
|
}
|
|
|
|
; CHECK: [[SCALAR_SUB]] = OpFunction [[SCALAR]] None [[SCALAR_FN]]
|
|
; CHECK-NEXT: [[A:%.+]] = OpFunctionParameter [[SCALAR]]
|
|
; CHECK-NEXT: [[B:%.+]] = OpFunctionParameter [[SCALAR]]
|
|
; CHECK: OpLabel
|
|
; CHECK: [[C:%.+]] = OpISub [[SCALAR]] [[A]] [[B]]
|
|
; CHECK: OpReturnValue [[C]]
|
|
; CHECK-NEXT: OpFunctionEnd
|
|
|
|
|
|
; Test mul on scalar:
|
|
define i32 @scalar_mul(i32 %a, i32 %b) {
|
|
%c = mul i32 %a, %b
|
|
ret i32 %c
|
|
}
|
|
|
|
; CHECK: [[SCALAR_MUL]] = OpFunction [[SCALAR]] None [[SCALAR_FN]]
|
|
; CHECK-NEXT: [[A:%.+]] = OpFunctionParameter [[SCALAR]]
|
|
; CHECK-NEXT: [[B:%.+]] = OpFunctionParameter [[SCALAR]]
|
|
; CHECK: OpLabel
|
|
; CHECK: [[C:%.+]] = OpIMul [[SCALAR]] [[A]] [[B]]
|
|
; CHECK: OpReturnValue [[C]]
|
|
; CHECK-NEXT: OpFunctionEnd
|
|
|
|
|
|
; Test udiv on scalar:
|
|
define i32 @scalar_udiv(i32 %a, i32 %b) {
|
|
%c = udiv i32 %a, %b
|
|
ret i32 %c
|
|
}
|
|
|
|
; CHECK: [[SCALAR_UDIV]] = OpFunction [[SCALAR]] None [[SCALAR_FN]]
|
|
; CHECK-NEXT: [[A:%.+]] = OpFunctionParameter [[SCALAR]]
|
|
; CHECK-NEXT: [[B:%.+]] = OpFunctionParameter [[SCALAR]]
|
|
; CHECK: OpLabel
|
|
; CHECK: [[C:%.+]] = OpUDiv [[SCALAR]] [[A]] [[B]]
|
|
; CHECK: OpReturnValue [[C]]
|
|
; CHECK-NEXT: OpFunctionEnd
|
|
|
|
|
|
; Test sdiv on scalar:
|
|
define i32 @scalar_sdiv(i32 %a, i32 %b) {
|
|
%c = sdiv i32 %a, %b
|
|
ret i32 %c
|
|
}
|
|
|
|
; CHECK: [[SCALAR_SDIV]] = OpFunction [[SCALAR]] None [[SCALAR_FN]]
|
|
; CHECK-NEXT: [[A:%.+]] = OpFunctionParameter [[SCALAR]]
|
|
; CHECK-NEXT: [[B:%.+]] = OpFunctionParameter [[SCALAR]]
|
|
; CHECK: OpLabel
|
|
; CHECK: [[C:%.+]] = OpSDiv [[SCALAR]] [[A]] [[B]]
|
|
; CHECK: OpReturnValue [[C]]
|
|
; CHECK-NEXT: OpFunctionEnd
|