176 lines · plain
1// RUN: %clang_cc1 -finclude-default-header -fnative-half-type -fnative-int16-type -triple \2// RUN: dxil-pc-shadermodel6.4-compute %s -emit-llvm -o - | \3// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-DXIL4// RUN: %clang_cc1 -finclude-default-header -fnative-half-type -fnative-int16-type -triple \5// RUN: spirv-pc-vulkan-compute %s -emit-llvm -o - | \6// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV7 8// Test basic lowering to runtime function call.9 10// CHECK-LABEL: define {{.*}}test_default_parameter_type11float test_default_parameter_type(half2 p1, half2 p2, float p3) {12 // CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})13 // CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float14 // CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 415 // CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]16 // CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 017 // CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 118 // CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 019 // CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 120 // CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])21 // CHECK: ret float %[[RES]]22 return dot2add(p1, p2, p3);23}24 25// CHECK-LABEL: define {{.*}}test_float_arg2_type26float test_float_arg2_type(half2 p1, float2 p2, float p3) {27 // CHECK: %conv = fptrunc reassoc nnan ninf nsz arcp afn <2 x float> %{{.*}} to <2 x half>28 // CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})29 // CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float30 // CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 431 // CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]32 // CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 033 // CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 134 // CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 035 // CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 136 // CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])37 // CHECK: ret float %[[RES]]38 return dot2add(p1, p2, p3);39}40 41// CHECK-LABEL: define {{.*}}test_float_arg1_type42float test_float_arg1_type(float2 p1, half2 p2, float p3) {43 // CHECK: %conv = fptrunc reassoc nnan ninf nsz arcp afn <2 x float> %{{.*}} to <2 x half>44 // CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})45 // CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float46 // CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 447 // CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]48 // CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 049 // CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 150 // CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 051 // CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 152 // CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])53 // CHECK: ret float %[[RES]]54 return dot2add(p1, p2, p3);55}56 57// CHECK-LABEL: define {{.*}}test_double_arg3_type58float test_double_arg3_type(half2 p1, half2 p2, double p3) {59 // CHECK: %conv = fptrunc reassoc nnan ninf nsz arcp afn double %{{.*}} to float60 // CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})61 // CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float62 // CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 463 // CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]64 // CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 065 // CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 166 // CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 067 // CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 168 // CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])69 // CHECK: ret float %[[RES]]70 return dot2add(p1, p2, p3);71}72 73// CHECK-LABEL: define {{.*}}test_float_arg1_arg2_type74float test_float_arg1_arg2_type(float2 p1, float2 p2, float p3) {75 // CHECK: %conv = fptrunc reassoc nnan ninf nsz arcp afn <2 x float> %{{.*}} to <2 x half>76 // CHECK: %conv1 = fptrunc reassoc nnan ninf nsz arcp afn <2 x float> %{{.*}} to <2 x half>77 // CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})78 // CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float79 // CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 480 // CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]81 // CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 082 // CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 183 // CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 084 // CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 185 // CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])86 // CHECK: ret float %[[RES]]87 return dot2add(p1, p2, p3);88}89 90// CHECK-LABEL: define {{.*}}test_double_arg1_arg2_type91float test_double_arg1_arg2_type(double2 p1, double2 p2, float p3) {92 // CHECK: %conv = fptrunc reassoc nnan ninf nsz arcp afn <2 x double> %{{.*}} to <2 x half>93 // CHECK: %conv1 = fptrunc reassoc nnan ninf nsz arcp afn <2 x double> %{{.*}} to <2 x half>94 // CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})95 // CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float96 // CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 497 // CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]98 // CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 099 // CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 1100 // CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 0101 // CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 1102 // CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])103 // CHECK: ret float %[[RES]]104 return dot2add(p1, p2, p3);105}106 107// CHECK-LABEL: define {{.*}}test_int16_arg1_arg2_type108float test_int16_arg1_arg2_type(int16_t2 p1, int16_t2 p2, float p3) {109 // CHECK: %conv = sitofp <2 x i16> %{{.*}} to <2 x half>110 // CHECK: %conv1 = sitofp <2 x i16> %{{.*}} to <2 x half>111 // CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})112 // CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float113 // CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 4114 // CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]115 // CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 0116 // CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 1117 // CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 0118 // CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 1119 // CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])120 // CHECK: ret float %[[RES]]121 return dot2add(p1, p2, p3);122}123 124// CHECK-LABEL: define {{.*}}test_int32_arg1_arg2_type125float test_int32_arg1_arg2_type(int32_t2 p1, int32_t2 p2, float p3) {126 // CHECK: %conv = sitofp <2 x i32> %{{.*}} to <2 x half>127 // CHECK: %conv1 = sitofp <2 x i32> %{{.*}} to <2 x half>128 // CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})129 // CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float130 // CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 4131 // CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]132 // CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 0133 // CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 1134 // CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 0135 // CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 1136 // CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])137 // CHECK: ret float %[[RES]]138 return dot2add(p1, p2, p3);139}140 141// CHECK-LABEL: define {{.*}}test_int64_arg1_arg2_type142float test_int64_arg1_arg2_type(int64_t2 p1, int64_t2 p2, float p3) {143 // CHECK: %conv = sitofp <2 x i64> %{{.*}} to <2 x half>144 // CHECK: %conv1 = sitofp <2 x i64> %{{.*}} to <2 x half>145 // CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})146 // CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float147 // CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 4148 // CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]149 // CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 0150 // CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 1151 // CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 0152 // CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 1153 // CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])154 // CHECK: ret float %[[RES]]155 return dot2add(p1, p2, p3);156}157 158// CHECK-LABEL: define {{.*}}test_bool_arg1_arg2_type159float test_bool_arg1_arg2_type(bool2 p1, bool2 p2, float p3) {160 // CHECK: %loadedv = trunc <2 x i32> %{{.*}} to <2 x i1>161 // CHECK: %conv = uitofp <2 x i1> %loadedv to <2 x half>162 // CHECK: %loadedv1 = trunc <2 x i32> %{{.*}} to <2 x i1>163 // CHECK: %conv2 = uitofp <2 x i1> %loadedv1 to <2 x half>164 // CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})165 // CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float166 // CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 4167 // CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]168 // CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 0169 // CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 1170 // CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 0171 // CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 1172 // CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])173 // CHECK: ret float %[[RES]]174 return dot2add(p1, p2, p3);175}176