| ; A `select` whose arms are composite (aggregate) constants used to crash in | |
| ; SPIRVEmitIntrinsics: preprocessCompositeConstants() rewrites the composite | |
| ; constant operands into i32 value-ids, which left the select with an aggregate | |
| ; result type but i32 operands -- an invalid state rejected by the verifier with | |
| ; "Select values must have same type as select instruction". Check that such a | |
| ; select is now lowered to a valid OpSelect over the composite type. | |
| ; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s | |
| ; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} | |
| ; CHECK-DAG: %[[#Float:]] = OpTypeFloat 32 | |
| ; CHECK-DAG: %[[#Int:]] = OpTypeInt 32 0 | |
| ; CHECK-DAG: %[[#Two:]] = OpConstant %[[#Int]] 2 | |
| ; CHECK-DAG: %[[#Array:]] = OpTypeArray %[[#Float]] %[[#Two]] | |
| ; CHECK-DAG: %[[#Struct:]] = OpTypeStruct %[[#Float]] %[[#Float]] | |
| ; The selects must be lowered to OpSelect over the composite type (not i32). | |
| ; CHECK-DAG: %[[#ArrSel:]] = OpSelect %[[#Array]] %[[#]] %[[#]] %[[#]] | |
| ; CHECK-DAG: %[[#StructSel:]] = OpSelect %[[#Struct]] %[[#]] %[[#]] %[[#]] | |
| ; CHECK-DAG: OpCompositeExtract %[[#Float]] %[[#ArrSel]] 0 | |
| ; CHECK-DAG: OpCompositeExtract %[[#Float]] %[[#ArrSel]] 1 | |
| ; CHECK-DAG: OpCompositeExtract %[[#Float]] %[[#StructSel]] 0 | |
| ; Array-typed composite constant (e.g. a Julia Complex{Float32}). | |
| define spir_kernel void @select_array_constant(ptr addrspace(1) %out, i1 %c) { | |
| %v = select i1 %c, [2 x float] [float 1.000000e+00, float 0.000000e+00], [2 x float] zeroinitializer | |
| %e0 = extractvalue [2 x float] %v, 0 | |
| %e1 = extractvalue [2 x float] %v, 1 | |
| store float %e0, ptr addrspace(1) %out | |
| %p1 = getelementptr float, ptr addrspace(1) %out, i64 1 | |
| store float %e1, ptr addrspace(1) %p1 | |
| ret void | |
| } | |
| ; Struct-typed composite constant (e.g. a C _Complex float). | |
| define spir_kernel void @select_struct_constant(ptr addrspace(1) %out, i1 %c) { | |
| %v = select i1 %c, { float, float } { float 1.000000e+00, float 2.000000e+00 }, { float, float } zeroinitializer | |
| %e0 = extractvalue { float, float } %v, 0 | |
| store float %e0, ptr addrspace(1) %out | |
| ret void | |
| } |