1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
|
// RUN: %clang_cc1 -finclude-default-header -fnative-half-type -triple \
// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - | \
// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-DXIL
// RUN: %clang_cc1 -finclude-default-header -fnative-half-type -triple \
// RUN: spirv-pc-vulkan-compute %s -emit-llvm -o - | \
// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV
// Test basic lowering to runtime function call.
// CHECK-LABEL: define {{.*}}test_default_parameter_type
float test_default_parameter_type(half2 p1, half2 p2, float p3) {
// CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})
// CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float
// CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 4
// CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]
// CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])
// CHECK: ret float %[[RES]]
return dot2add(p1, p2, p3);
}
// CHECK-LABEL: define {{.*}}test_float_arg2_type
float test_float_arg2_type(half2 p1, float2 p2, float p3) {
// CHECK: %conv = fptrunc reassoc nnan ninf nsz arcp afn <2 x float> %{{.*}} to <2 x half>
// CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})
// CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float
// CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 4
// CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]
// CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])
// CHECK: ret float %[[RES]]
return dot2add(p1, p2, p3);
}
// CHECK-LABEL: define {{.*}}test_float_arg1_type
float test_float_arg1_type(float2 p1, half2 p2, float p3) {
// CHECK: %conv = fptrunc reassoc nnan ninf nsz arcp afn <2 x float> %{{.*}} to <2 x half>
// CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})
// CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float
// CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 4
// CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]
// CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])
// CHECK: ret float %[[RES]]
return dot2add(p1, p2, p3);
}
// CHECK-LABEL: define {{.*}}test_double_arg3_type
float test_double_arg3_type(half2 p1, half2 p2, double p3) {
// CHECK: %conv = fptrunc reassoc nnan ninf nsz arcp afn double %{{.*}} to float
// CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})
// CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float
// CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 4
// CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]
// CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])
// CHECK: ret float %[[RES]]
return dot2add(p1, p2, p3);
}
// CHECK-LABEL: define {{.*}}test_float_arg1_arg2_type
float test_float_arg1_arg2_type(float2 p1, float2 p2, float p3) {
// CHECK: %conv = fptrunc reassoc nnan ninf nsz arcp afn <2 x float> %{{.*}} to <2 x half>
// CHECK: %conv1 = fptrunc reassoc nnan ninf nsz arcp afn <2 x float> %{{.*}} to <2 x half>
// CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})
// CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float
// CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 4
// CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]
// CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])
// CHECK: ret float %[[RES]]
return dot2add(p1, p2, p3);
}
// CHECK-LABEL: define {{.*}}test_double_arg1_arg2_type
float test_double_arg1_arg2_type(double2 p1, double2 p2, float p3) {
// CHECK: %conv = fptrunc reassoc nnan ninf nsz arcp afn <2 x double> %{{.*}} to <2 x half>
// CHECK: %conv1 = fptrunc reassoc nnan ninf nsz arcp afn <2 x double> %{{.*}} to <2 x half>
// CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})
// CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float
// CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 4
// CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]
// CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])
// CHECK: ret float %[[RES]]
return dot2add(p1, p2, p3);
}
// CHECK-LABEL: define {{.*}}test_int16_arg1_arg2_type
float test_int16_arg1_arg2_type(int16_t2 p1, int16_t2 p2, float p3) {
// CHECK: %conv = sitofp <2 x i16> %{{.*}} to <2 x half>
// CHECK: %conv1 = sitofp <2 x i16> %{{.*}} to <2 x half>
// CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})
// CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float
// CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 4
// CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]
// CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])
// CHECK: ret float %[[RES]]
return dot2add(p1, p2, p3);
}
// CHECK-LABEL: define {{.*}}test_int32_arg1_arg2_type
float test_int32_arg1_arg2_type(int32_t2 p1, int32_t2 p2, float p3) {
// CHECK: %conv = sitofp <2 x i32> %{{.*}} to <2 x half>
// CHECK: %conv1 = sitofp <2 x i32> %{{.*}} to <2 x half>
// CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})
// CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float
// CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 4
// CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]
// CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])
// CHECK: ret float %[[RES]]
return dot2add(p1, p2, p3);
}
// CHECK-LABEL: define {{.*}}test_int64_arg1_arg2_type
float test_int64_arg1_arg2_type(int64_t2 p1, int64_t2 p2, float p3) {
// CHECK: %conv = sitofp <2 x i64> %{{.*}} to <2 x half>
// CHECK: %conv1 = sitofp <2 x i64> %{{.*}} to <2 x half>
// CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})
// CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float
// CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 4
// CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]
// CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])
// CHECK: ret float %[[RES]]
return dot2add(p1, p2, p3);
}
// CHECK-LABEL: define {{.*}}test_bool_arg1_arg2_type
float test_bool_arg1_arg2_type(bool2 p1, bool2 p2, float p3) {
// CHECK: %loadedv = trunc <2 x i32> %{{.*}} to <2 x i1>
// CHECK: %conv = uitofp <2 x i1> %loadedv to <2 x half>
// CHECK: %loadedv1 = trunc <2 x i32> %{{.*}} to <2 x i1>
// CHECK: %conv2 = uitofp <2 x i1> %loadedv1 to <2 x half>
// CHECK-SPIRV: %[[MUL:.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}})
// CHECK-SPIRV: %[[CONV:.*]] = fpext reassoc nnan ninf nsz arcp afn half %[[MUL]] to float
// CHECK-SPIRV: %[[C:.*]] = load float, ptr %c.addr.i, align 4
// CHECK-SPIRV: %[[RES:.*]] = fadd reassoc nnan ninf nsz arcp afn float %[[CONV]], %[[C]]
// CHECK-DXIL: %[[AX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[AY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[BX:.*]] = extractelement <2 x half> %{{.*}}, i32 0
// CHECK-DXIL: %[[BY:.*]] = extractelement <2 x half> %{{.*}}, i32 1
// CHECK-DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.dot2add(float %{{.*}}, half %[[AX]], half %[[AY]], half %[[BX]], half %[[BY]])
// CHECK: ret float %[[RES]]
return dot2add(p1, p2, p3);
}
|