1; RUN: opt -S -dxil-intrinsic-expansion -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s --check-prefixes=CHECK,EXPCHECK 2; RUN: opt -S -dxil-intrinsic-expansion -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s --check-prefixes=CHECK,DOPCHECK 3 4; Make sure dxil operation function calls for dot are generated for float type vectors. 5 6; CHECK-LABEL: dot_half2 7define noundef half @dot_half2(<2 x half> noundef %a, <2 x half> noundef %b) { 8entry: 9; DOPCHECK: extractelement <2 x half> %a, i32 0 10; DOPCHECK: extractelement <2 x half> %a, i32 1 11; DOPCHECK: extractelement <2 x half> %b, i32 0 12; DOPCHECK: extractelement <2 x half> %b, i32 1 13; DOPCHECK: call half @dx.op.dot2.f16(i32 54, half %{{.*}}, half %{{.*}}, half %{{.*}}, half %{{.*}}) #[[#ATTR:]] 14; EXPCHECK: call half @llvm.dx.dot2.v2f16(<2 x half> %a, <2 x half> %b) 15 %dx.dot = call half @llvm.dx.fdot.v2f16(<2 x half> %a, <2 x half> %b) 16 ret half %dx.dot 17} 18 19; CHECK-LABEL: dot_half3 20define noundef half @dot_half3(<3 x half> noundef %a, <3 x half> noundef %b) { 21entry: 22; DOPCHECK: extractelement <3 x half> %a, i32 0 23; DOPCHECK: extractelement <3 x half> %a, i32 1 24; DOPCHECK: extractelement <3 x half> %a, i32 2 25; DOPCHECK: extractelement <3 x half> %b, i32 0 26; DOPCHECK: extractelement <3 x half> %b, i32 1 27; DOPCHECK: extractelement <3 x half> %b, i32 2 28; DOPCHECK: call half @dx.op.dot3.f16(i32 55, half %{{.*}}, half %{{.*}}, half %{{.*}}, half %{{.*}}, half %{{.*}}, half %{{.*}}) #[[#ATTR]] 29; EXPCHECK: call half @llvm.dx.dot3.v3f16(<3 x half> %a, <3 x half> %b) 30 %dx.dot = call half @llvm.dx.fdot.v3f16(<3 x half> %a, <3 x half> %b) 31 ret half %dx.dot 32} 33 34; CHECK-LABEL: dot_half4 35define noundef half @dot_half4(<4 x half> noundef %a, <4 x half> noundef %b) { 36entry: 37; DOPCHECK: extractelement <4 x half> %a, i32 0 38; DOPCHECK: extractelement <4 x half> %a, i32 1 39; DOPCHECK: extractelement <4 x half> %a, i32 2 40; DOPCHECK: extractelement <4 x half> %a, i32 3 41; DOPCHECK: extractelement <4 x half> %b, i32 0 42; DOPCHECK: extractelement <4 x half> %b, i32 1 43; DOPCHECK: extractelement <4 x half> %b, i32 2 44; DOPCHECK: extractelement <4 x half> %b, i32 3 45; DOPCHECK: call half @dx.op.dot4.f16(i32 56, half %{{.*}}, half %{{.*}}, half %{{.*}}, half %{{.*}}, half %{{.*}}, half %{{.*}}, half %{{.*}}, half %{{.*}}) #[[#ATTR]] 46; EXPCHECK: call half @llvm.dx.dot4.v4f16(<4 x half> %a, <4 x half> %b) 47 %dx.dot = call half @llvm.dx.fdot.v4f16(<4 x half> %a, <4 x half> %b) 48 ret half %dx.dot 49} 50 51; CHECK-LABEL: dot_float2 52define noundef float @dot_float2(<2 x float> noundef %a, <2 x float> noundef %b) { 53entry: 54; DOPCHECK: extractelement <2 x float> %a, i32 0 55; DOPCHECK: extractelement <2 x float> %a, i32 1 56; DOPCHECK: extractelement <2 x float> %b, i32 0 57; DOPCHECK: extractelement <2 x float> %b, i32 1 58; DOPCHECK: call float @dx.op.dot2.f32(i32 54, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}) #[[#ATTR]] 59; EXPCHECK: call float @llvm.dx.dot2.v2f32(<2 x float> %a, <2 x float> %b) 60 %dx.dot = call float @llvm.dx.fdot.v2f32(<2 x float> %a, <2 x float> %b) 61 ret float %dx.dot 62} 63 64; CHECK-LABEL: dot_float3 65define noundef float @dot_float3(<3 x float> noundef %a, <3 x float> noundef %b) { 66entry: 67; DOPCHECK: extractelement <3 x float> %a, i32 0 68; DOPCHECK: extractelement <3 x float> %a, i32 1 69; DOPCHECK: extractelement <3 x float> %a, i32 2 70; DOPCHECK: extractelement <3 x float> %b, i32 0 71; DOPCHECK: extractelement <3 x float> %b, i32 1 72; DOPCHECK: extractelement <3 x float> %b, i32 2 73; DOPCHECK: call float @dx.op.dot3.f32(i32 55, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}) #[[#ATTR]] 74; EXPCHECK: call float @llvm.dx.dot3.v3f32(<3 x float> %a, <3 x float> %b) 75 %dx.dot = call float @llvm.dx.fdot.v3f32(<3 x float> %a, <3 x float> %b) 76 ret float %dx.dot 77} 78 79; CHECK-LABEL: dot_float4 80define noundef float @dot_float4(<4 x float> noundef %a, <4 x float> noundef %b) { 81entry: 82; DOPCHECK: extractelement <4 x float> %a, i32 0 83; DOPCHECK: extractelement <4 x float> %a, i32 1 84; DOPCHECK: extractelement <4 x float> %a, i32 2 85; DOPCHECK: extractelement <4 x float> %a, i32 3 86; DOPCHECK: extractelement <4 x float> %b, i32 0 87; DOPCHECK: extractelement <4 x float> %b, i32 1 88; DOPCHECK: extractelement <4 x float> %b, i32 2 89; DOPCHECK: extractelement <4 x float> %b, i32 3 90; DOPCHECK: call float @dx.op.dot4.f32(i32 56, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}) #[[#ATTR]] 91; EXPCHECK: call float @llvm.dx.dot4.v4f32(<4 x float> %a, <4 x float> %b) 92 %dx.dot = call float @llvm.dx.fdot.v4f32(<4 x float> %a, <4 x float> %b) 93 ret float %dx.dot 94} 95 96; DOPCHECK: attributes #[[#ATTR]] = {{{.*}} memory(none) {{.*}}} 97 98declare half @llvm.dx.fdot.v2f16(<2 x half> , <2 x half> ) 99declare half @llvm.dx.fdot.v3f16(<3 x half> , <3 x half> ) 100declare half @llvm.dx.fdot.v4f16(<4 x half> , <4 x half> ) 101declare float @llvm.dx.fdot.v2f32(<2 x float>, <2 x float>) 102declare float @llvm.dx.fdot.v3f32(<3 x float>, <3 x float>) 103declare float @llvm.dx.fdot.v4f32(<4 x float>, <4 x float>) 104