1; RUN: llc -O0 -mtriple=spirv1.5-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-EXP 2; RUN: llc -O0 -mtriple=spirv1.6-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-DOT 3; RUN: llc -O0 -mtriple=spirv1.5-unknown-unknown -spirv-ext=+SPV_KHR_integer_dot_product %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-DOT,CHECK-EXT 4; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-unknown-unknown %s -o - -filetype=obj | spirv-val %} 5; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.6-unknown-unknown %s -o - -filetype=obj | spirv-val %} 6; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-unknown-unknown -spirv-ext=+SPV_KHR_integer_dot_product %s -o - -filetype=obj | spirv-val %} 7 8; Make sure dxil operation function calls for dot are generated for int/uint vectors. 9 10; CHECK-DAG: OpCapability Int8 11; CHECK-DOT-DAG: OpCapability DotProduct 12; CHECK-DOT-DAG: OpCapability DotProductInputAll 13; CHECK-DOT-DAG: OpCapability DotProductInput4x8Bit 14; CHECK-EXT-DAG: OpExtension "SPV_KHR_integer_dot_product" 15 16; CHECK-DAG: %[[#int_8:]] = OpTypeInt 8 17; CHECK-DAG: %[[#vec4_int_8:]] = OpTypeVector %[[#int_8]] 4 18; CHECK-DAG: %[[#int_16:]] = OpTypeInt 16 19; CHECK-DAG: %[[#vec2_int_16:]] = OpTypeVector %[[#int_16]] 2 20; CHECK-DAG: %[[#vec3_int_16:]] = OpTypeVector %[[#int_16]] 3 21; CHECK-DAG: %[[#int_32:]] = OpTypeInt 32 22; CHECK-DAG: %[[#vec4_int_32:]] = OpTypeVector %[[#int_32]] 4 23; CHECK-DAG: %[[#int_64:]] = OpTypeInt 64 24; CHECK-DAG: %[[#vec2_int_64:]] = OpTypeVector %[[#int_64]] 2 25 26define noundef i8 @dot_int8_t4(<4 x i8> noundef %a, <4 x i8> noundef %b) { 27entry: 28; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_int_8]] 29; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec4_int_8]] 30 31; CHECK-DOT: %[[#dot:]] = OpSDot %[[#int_8]] %[[#arg0]] %[[#arg1]] 32 33; CHECK-EXP: %[[#mul_vec:]] = OpIMul %[[#vec4_int_8]] %[[#arg0]] %[[#arg1]] 34; CHECK-EXP: %[[#elt0:]] = OpCompositeExtract %[[#int_8]] %[[#mul_vec]] 0 35; CHECK-EXP: %[[#elt1:]] = OpCompositeExtract %[[#int_8]] %[[#mul_vec]] 1 36; CHECK-EXP: %[[#sum:]] = OpIAdd %[[#int_8]] %[[#elt0]] %[[#elt1]] 37 %dot = call i8 @llvm.spv.sdot.v4i8(<4 x i8> %a, <4 x i8> %b) 38 ret i8 %dot 39} 40 41define noundef i16 @dot_int16_t2(<2 x i16> noundef %a, <2 x i16> noundef %b) { 42entry: 43; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec2_int_16]] 44; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec2_int_16]] 45 46; CHECK-DOT: %[[#dot:]] = OpSDot %[[#int_16]] %[[#arg0]] %[[#arg1]] 47 48; CHECK-EXP: %[[#mul_vec:]] = OpIMul %[[#vec2_int_16]] %[[#arg0]] %[[#arg1]] 49; CHECK-EXP: %[[#elt0:]] = OpCompositeExtract %[[#int_16]] %[[#mul_vec]] 0 50; CHECK-EXP: %[[#elt1:]] = OpCompositeExtract %[[#int_16]] %[[#mul_vec]] 1 51; CHECK-EXP: %[[#sum:]] = OpIAdd %[[#int_16]] %[[#elt0]] %[[#elt1]] 52 %dot = call i16 @llvm.spv.sdot.v3i16(<2 x i16> %a, <2 x i16> %b) 53 ret i16 %dot 54} 55 56define noundef i32 @dot_int4(<4 x i32> noundef %a, <4 x i32> noundef %b) { 57entry: 58; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_int_32]] 59; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec4_int_32]] 60 61; CHECK-DOT: %[[#dot:]] = OpSDot %[[#int_32]] %[[#arg0]] %[[#arg1]] 62 63; CHECK-EXP: %[[#mul_vec:]] = OpIMul %[[#vec4_int_32]] %[[#arg0]] %[[#arg1]] 64; CHECK-EXP: %[[#elt0:]] = OpCompositeExtract %[[#int_32]] %[[#mul_vec]] 0 65; CHECK-EXP: %[[#elt1:]] = OpCompositeExtract %[[#int_32]] %[[#mul_vec]] 1 66; CHECK-EXP: %[[#sum0:]] = OpIAdd %[[#int_32]] %[[#elt0]] %[[#elt1]] 67; CHECK-EXP: %[[#elt2:]] = OpCompositeExtract %[[#int_32]] %[[#mul_vec]] 2 68; CHECK-EXP: %[[#sum1:]] = OpIAdd %[[#int_32]] %[[#sum0]] %[[#elt2]] 69; CHECK-EXP: %[[#elt3:]] = OpCompositeExtract %[[#int_32]] %[[#mul_vec]] 3 70; CHECK-EXP: %[[#sum2:]] = OpIAdd %[[#int_32]] %[[#sum1]] %[[#elt3]] 71 %dot = call i32 @llvm.spv.sdot.v4i32(<4 x i32> %a, <4 x i32> %b) 72 ret i32 %dot 73} 74 75define noundef i8 @dot_uint8_t4(<4 x i8> noundef %a, <4 x i8> noundef %b) { 76entry: 77; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_int_8]] 78; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec4_int_8]] 79 80; CHECK-DOT: %[[#dot:]] = OpUDot %[[#int_8]] %[[#arg0]] %[[#arg1]] 81 82; CHECK-EXP: %[[#mul_vec:]] = OpIMul %[[#vec4_int_8]] %[[#arg0]] %[[#arg1]] 83; CHECK-EXP: %[[#elt0:]] = OpCompositeExtract %[[#int_8]] %[[#mul_vec]] 0 84; CHECK-EXP: %[[#elt1:]] = OpCompositeExtract %[[#int_8]] %[[#mul_vec]] 1 85; CHECK-EXP: %[[#sum:]] = OpIAdd %[[#int_8]] %[[#elt0]] %[[#elt1]] 86 %dot = call i8 @llvm.spv.udot.v4i8(<4 x i8> %a, <4 x i8> %b) 87 ret i8 %dot 88} 89 90define noundef i16 @dot_uint16_t3(<3 x i16> noundef %a, <3 x i16> noundef %b) { 91entry: 92; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec3_int_16]] 93; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec3_int_16]] 94 95; CHECK-DOT: %[[#dot:]] = OpUDot %[[#int_16]] %[[#arg0]] %[[#arg1]] 96 97; CHECK-EXP: %[[#mul_vec:]] = OpIMul %[[#vec3_int_16]] %[[#arg0]] %[[#arg1]] 98; CHECK-EXP: %[[#elt0:]] = OpCompositeExtract %[[#int_16]] %[[#mul_vec]] 0 99; CHECK-EXP: %[[#elt1:]] = OpCompositeExtract %[[#int_16]] %[[#mul_vec]] 1 100; CHECK-EXP: %[[#sum0:]] = OpIAdd %[[#int_16]] %[[#elt0]] %[[#elt1]] 101; CHECK-EXP: %[[#elt2:]] = OpCompositeExtract %[[#int_16]] %[[#mul_vec]] 2 102; CHECK-EXP: %[[#sum1:]] = OpIAdd %[[#int_16]] %[[#sum0]] %[[#elt2]] 103 %dot = call i16 @llvm.spv.udot.v3i16(<3 x i16> %a, <3 x i16> %b) 104 ret i16 %dot 105} 106 107define noundef i32 @dot_uint4(<4 x i32> noundef %a, <4 x i32> noundef %b) { 108entry: 109; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_int_32]] 110; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec4_int_32]] 111 112; CHECK-DOT: %[[#dot:]] = OpUDot %[[#int_32]] %[[#arg0]] %[[#arg1]] 113 114; CHECK-EXP: %[[#mul_vec:]] = OpIMul %[[#vec4_int_32]] %[[#arg0]] %[[#arg1]] 115; CHECK-EXP: %[[#elt0:]] = OpCompositeExtract %[[#int_32]] %[[#mul_vec]] 0 116; CHECK-EXP: %[[#elt1:]] = OpCompositeExtract %[[#int_32]] %[[#mul_vec]] 1 117; CHECK-EXP: %[[#sum0:]] = OpIAdd %[[#int_32]] %[[#elt0]] %[[#elt1]] 118; CHECK-EXP: %[[#elt2:]] = OpCompositeExtract %[[#int_32]] %[[#mul_vec]] 2 119; CHECK-EXP: %[[#sum1:]] = OpIAdd %[[#int_32]] %[[#sum0]] %[[#elt2]] 120; CHECK-EXP: %[[#elt3:]] = OpCompositeExtract %[[#int_32]] %[[#mul_vec]] 3 121; CHECK-EXP: %[[#sum2:]] = OpIAdd %[[#int_32]] %[[#sum1]] %[[#elt3]] 122 %dot = call i32 @llvm.spv.udot.v4i32(<4 x i32> %a, <4 x i32> %b) 123 ret i32 %dot 124} 125 126define noundef i64 @dot_uint64_t4(<2 x i64> noundef %a, <2 x i64> noundef %b) { 127entry: 128; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec2_int_64]] 129; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#vec2_int_64]] 130 131; CHECK-DOT: %[[#dot:]] = OpUDot %[[#int_64]] %[[#arg0]] %[[#arg1]] 132 133; CHECK-EXP: %[[#mul_vec:]] = OpIMul %[[#vec2_int_64]] %[[#arg0]] %[[#arg1]] 134; CHECK-EXP: %[[#elt0:]] = OpCompositeExtract %[[#int_64]] %[[#mul_vec]] 0 135; CHECK-EXP: %[[#elt1:]] = OpCompositeExtract %[[#int_64]] %[[#mul_vec]] 1 136; CHECK-EXP: %[[#sum0:]] = OpIAdd %[[#int_64]] %[[#elt0]] %[[#elt1]] 137 %dot = call i64 @llvm.spv.udot.v2i64(<2 x i64> %a, <2 x i64> %b) 138 ret i64 %dot 139} 140 141declare i8 @llvm.spv.sdot.v4i8(<4 x i8>, <4 x i8>) 142declare i16 @llvm.spv.sdot.v2i16(<2 x i16>, <2 x i16>) 143declare i32 @llvm.spv.sdot.v4i32(<4 x i32>, <4 x i32>) 144declare i8 @llvm.spv.udot.v4i8(<4 x i8>, <4 x i8>) 145declare i16 @llvm.spv.udot.v3i32(<3 x i16>, <3 x i16>) 146declare i32 @llvm.spv.udot.v4i32(<4 x i32>, <4 x i32>) 147declare i64 @llvm.spv.udot.v2i64(<2 x i64>, <2 x i64>) 148