This PR is to fix a way how SPIR-V Backend describes legality of OpBitcast instruction and how it is validated on a step of instruction selection. Instead of checking a size of virtual registers (that makes no sense due to lack of guarantee of direct relations between size of virtual register and bit width associated with the type size), this PR allows to legalize OpBitcast without size check and postpones validation to the instruction selection step. As an example, let's consider the next example that was copied as is from a bigger test suite: ``` %355:id(s16) = G_BITCAST %301:id(s32) %303:id(s16) = ASSIGN_TYPE %355:id(s16), %349:type(s32) %644:fid(s32) = G_FMUL %645:fid, %646:fid %301:id(s32) = ASSIGN_TYPE %644:fid(s32), %40:type(s32) ``` Without the PR this leads to a crash with complains to an illegal bitcast, because %355 is s16 and %301 is s32. However, we must check not virtual registers in this case, but types of %355 and %301, i.e., %349:type(s32) and %40:type(s32), which are perfectly well compatible in a sense of OpBitcast in this case. In a test case that is a part of this PR OpBitcast is legal, being applied for `OpTypeInt 16` and `OpTypeFloat 16`, but would not be legalized without this PR due to virtual registers defined as having size 16 and 32.
22 lines
945 B
LLVM
22 lines
945 B
LLVM
; 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-DAG: %[[#TyInt32:]] = OpTypeInt 32 0
|
|
; CHECK-SPIRV-DAG: %[[#TyInt16:]] = OpTypeInt 16 0
|
|
; CHECK-SPIRV-DAG: %[[#TyHalf:]] = OpTypeFloat 16
|
|
; CHECK-SPIRV-DAG: %[[#Arg32:]] = OpFunctionParameter %[[#TyInt32]]
|
|
; CHECK-SPIRV-DAG: %[[#Arg16:]] = OpUConvert %[[#TyInt16]] %[[#Arg32]]
|
|
; CHECK-SPIRV-DAG: %[[#ValHalf:]] = OpBitcast %[[#TyHalf]] %8
|
|
; CHECK-SPIRV-DAG: %[[#ValHalf2:]] = OpFMul %[[#TyHalf]] %[[#ValHalf]] %[[#ValHalf]]
|
|
; CHECK-SPIRV-DAG: %[[#Res16:]] = OpBitcast %[[#TyInt16]] %[[#ValHalf2]]
|
|
; CHECK-SPIRV-DAG: OpReturnValue %[[#Res16]]
|
|
|
|
define i16 @foo(i32 %arg) {
|
|
entry:
|
|
%op16 = trunc i32 %arg to i16
|
|
%val = bitcast i16 %op16 to half
|
|
%val2 = fmul half %val, %val
|
|
%res = bitcast half %val2 to i16
|
|
ret i16 %res
|
|
}
|