This PR contains a series of fixes which are to improve type inference and instruction selection. Namely, it includes: * fix OpSelect to support operands of a pointer type, according to the SPIR-V specification (previously only integer/float/vectors of integer or float were supported) -- a new test case is added and existing test case is updated; * fix TableGen typo's in definition of register classes and introduce a new reg class that is a vector of pointers; * fix usage of a machine function context when there is a need to switch between different machine functions to infer/validate correct types; * add usage of TypedPointerType instead of PointerType so that later stages of type inference are able to distinguish pointer types by their element types, effectively supporting hierarchy of pointer/pointee types and avoiding more complicated recursive type matching on level of machine instructions in favor of direct pointer comparison using LLVM's `Type *` values; * extracting detailed information about operand types using known type rules for some llvm instructions (for instance, by deducing PHI's operand pointee types if PHI's results type was deducted on previous stages of type inference), and adding correspondent `Intrinsic::spv_assign_ptr_type` to keep type info along consequent passes, * ensure that OpConstantComposite reuses a constant when it's already created and available in the same machine function -- otherwise there is a crash while building a dependency graph, the corresponding test case is attached, * implement deduction of function's return type for opaque pointers, a new test case is attached, * make 'emit intrinsics' a module pass to resolve function return types over the module -- first types for all functions of the module must be calculated, and only after that it's feasible to deduct function return types on this earlier stage of translation.
27 lines
1.0 KiB
LLVM
27 lines
1.0 KiB
LLVM
; This test is to ensure that OpConstantComposite reuses a constant when it's
|
|
; already created and available in the same machine function. In this test case
|
|
; it's `1` that is passed implicitly as a part of the `foo` function argument
|
|
; and also takes part in a composite constant creation.
|
|
|
|
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
|
|
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
|
|
|
|
; CHECK-SPIRV: %[[#type_int32:]] = OpTypeInt 32 0
|
|
; CHECK-SPIRV: %[[#const1:]] = OpConstant %[[#type_int32]] 1
|
|
; CHECK-SPIRV: OpTypeArray %[[#]] %[[#const1:]]
|
|
; CHECK-SPIRV: %[[#const0:]] = OpConstant %[[#type_int32]] 0
|
|
; CHECK-SPIRV: OpConstantComposite %[[#]] %[[#const0]] %[[#const1]]
|
|
|
|
%struct = type { [1 x i64] }
|
|
|
|
define spir_kernel void @foo(ptr noundef byval(%struct) %arg) {
|
|
entry:
|
|
call spir_func void @bar(<2 x i32> noundef <i32 0, i32 1>)
|
|
ret void
|
|
}
|
|
|
|
define spir_func void @bar(<2 x i32> noundef) {
|
|
entry:
|
|
ret void
|
|
}
|