ac/nir: support vector types in the type suffix of overloaded intrinsics
[mesa.git] / src / amd / llvm / ac_llvm_build.c
index e826811eefc4db2fa18f46ec5ac165e9363aeb88..6b8e2a98b5889ab777215815adf3d2e4f62721ad 100644 (file)
@@ -89,6 +89,9 @@ ac_llvm_context_init(struct ac_llvm_context *ctx,
        ctx->f32 = LLVMFloatTypeInContext(ctx->context);
        ctx->f64 = LLVMDoubleTypeInContext(ctx->context);
        ctx->v2i16 = LLVMVectorType(ctx->i16, 2);
+       ctx->v4i16 = LLVMVectorType(ctx->i16, 4);
+       ctx->v2f16 = LLVMVectorType(ctx->f16, 2);
+       ctx->v4f16 = LLVMVectorType(ctx->f16, 4);
        ctx->v2i32 = LLVMVectorType(ctx->i32, 2);
        ctx->v3i32 = LLVMVectorType(ctx->i32, 3);
        ctx->v4i32 = LLVMVectorType(ctx->i32, 4);
@@ -144,7 +147,7 @@ int
 ac_get_llvm_num_components(LLVMValueRef value)
 {
        LLVMTypeRef type = LLVMTypeOf(value);
-       unsigned num_components = LLVMGetTypeKind(type) == LLVMFixedVectorTypeKind
+       unsigned num_components = LLVMGetTypeKind(type) == LLVMVectorTypeKind
                                      ? LLVMGetVectorSize(type)
                                      : 1;
        return num_components;
@@ -155,7 +158,7 @@ ac_llvm_extract_elem(struct ac_llvm_context *ac,
                     LLVMValueRef value,
                     int index)
 {
-       if (LLVMGetTypeKind(LLVMTypeOf(value)) != LLVMFixedVectorTypeKind) {
+       if (LLVMGetTypeKind(LLVMTypeOf(value)) != LLVMVectorTypeKind) {
                assert(index == 0);
                return value;
        }
@@ -167,7 +170,7 @@ ac_llvm_extract_elem(struct ac_llvm_context *ac,
 int
 ac_get_elem_bits(struct ac_llvm_context *ctx, LLVMTypeRef type)
 {
-       if (LLVMGetTypeKind(type) == LLVMFixedVectorTypeKind)
+       if (LLVMGetTypeKind(type) == LLVMVectorTypeKind)
                type = LLVMGetElementType(type);
 
        if (LLVMGetTypeKind(type) == LLVMIntegerTypeKind)
@@ -206,7 +209,7 @@ ac_get_type_size(LLVMTypeRef type)
                if (LLVMGetPointerAddressSpace(type) == AC_ADDR_SPACE_CONST_32BIT)
                        return 4;
                return 8;
-       case LLVMFixedVectorTypeKind:
+       case LLVMVectorTypeKind:
                return LLVMGetVectorSize(type) *
                       ac_get_type_size(LLVMGetElementType(type));
        case LLVMArrayTypeKind:
@@ -235,7 +238,7 @@ static LLVMTypeRef to_integer_type_scalar(struct ac_llvm_context *ctx, LLVMTypeR
 LLVMTypeRef
 ac_to_integer_type(struct ac_llvm_context *ctx, LLVMTypeRef t)
 {
-       if (LLVMGetTypeKind(t) == LLVMFixedVectorTypeKind) {
+       if (LLVMGetTypeKind(t) == LLVMVectorTypeKind) {
                LLVMTypeRef elem_type = LLVMGetElementType(t);
                return LLVMVectorType(to_integer_type_scalar(ctx, elem_type),
                                      LLVMGetVectorSize(t));
@@ -290,7 +293,7 @@ static LLVMTypeRef to_float_type_scalar(struct ac_llvm_context *ctx, LLVMTypeRef
 LLVMTypeRef
 ac_to_float_type(struct ac_llvm_context *ctx, LLVMTypeRef t)
 {
-       if (LLVMGetTypeKind(t) == LLVMFixedVectorTypeKind) {
+       if (LLVMGetTypeKind(t) == LLVMVectorTypeKind) {
                LLVMTypeRef elem_type = LLVMGetElementType(t);
                return LLVMVectorType(to_float_type_scalar(ctx, elem_type),
                                      LLVMGetVectorSize(t));
@@ -352,7 +355,7 @@ void ac_build_type_name_for_intr(LLVMTypeRef type, char *buf, unsigned bufsize)
 
        assert(bufsize >= 8);
 
-       if (LLVMGetTypeKind(type) == LLVMFixedVectorTypeKind) {
+       if (LLVMGetTypeKind(type) == LLVMVectorTypeKind) {
                int ret = snprintf(buf, bufsize, "v%u",
                                        LLVMGetVectorSize(type));
                if (ret < 0) {
@@ -457,11 +460,10 @@ ac_build_optimization_barrier(struct ac_llvm_context *ctx,
 }
 
 LLVMValueRef
-ac_build_shader_clock(struct ac_llvm_context *ctx)
+ac_build_shader_clock(struct ac_llvm_context *ctx, nir_scope scope)
 {
-       const char *intr = LLVM_VERSION_MAJOR >= 9 && ctx->chip_class >= GFX8 ?
-                               "llvm.amdgcn.s.memrealtime" : "llvm.readcyclecounter";
-       LLVMValueRef tmp = ac_build_intrinsic(ctx, intr, ctx->i64, NULL, 0, 0);
+       const char *name = scope == NIR_SCOPE_DEVICE ? "llvm.amdgcn.s.memrealtime" : "llvm.amdgcn.s.memtime";
+       LLVMValueRef tmp = ac_build_intrinsic(ctx, name, ctx->i64, NULL, 0, 0);
        return LLVMBuildBitCast(ctx->builder, tmp, ctx->v2i32, "");
 }
 
@@ -627,7 +629,7 @@ ac_build_expand(struct ac_llvm_context *ctx,
        LLVMTypeRef elemtype;
        LLVMValueRef chan[dst_channels];
 
-       if (LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMFixedVectorTypeKind) {
+       if (LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMVectorTypeKind) {
                unsigned vec_size = LLVMGetVectorSize(LLVMTypeOf(value));
 
                if (src_channels == dst_channels && vec_size == dst_channels)
@@ -2190,8 +2192,10 @@ ac_build_umsb(struct ac_llvm_context *ctx,
 LLVMValueRef ac_build_fmin(struct ac_llvm_context *ctx, LLVMValueRef a,
                           LLVMValueRef b)
 {
-       char name[64];
-       snprintf(name, sizeof(name), "llvm.minnum.f%d", ac_get_elem_bits(ctx, LLVMTypeOf(a)));
+       char name[64], type[64];
+
+       ac_build_type_name_for_intr(LLVMTypeOf(a), type, sizeof(type));
+       snprintf(name, sizeof(name), "llvm.minnum.%s", type);
        LLVMValueRef args[2] = {a, b};
        return ac_build_intrinsic(ctx, name, LLVMTypeOf(a), args, 2,
                                  AC_FUNC_ATTR_READNONE);
@@ -2200,8 +2204,10 @@ LLVMValueRef ac_build_fmin(struct ac_llvm_context *ctx, LLVMValueRef a,
 LLVMValueRef ac_build_fmax(struct ac_llvm_context *ctx, LLVMValueRef a,
                           LLVMValueRef b)
 {
-       char name[64];
-       snprintf(name, sizeof(name), "llvm.maxnum.f%d", ac_get_elem_bits(ctx, LLVMTypeOf(a)));
+       char name[64], type[64];
+
+       ac_build_type_name_for_intr(LLVMTypeOf(a), type, sizeof(type));
+       snprintf(name, sizeof(name), "llvm.maxnum.%s", type);
        LLVMValueRef args[2] = {a, b};
        return ac_build_intrinsic(ctx, name, LLVMTypeOf(a), args, 2,
                                  AC_FUNC_ATTR_READNONE);
@@ -2250,13 +2256,10 @@ void ac_build_export(struct ac_llvm_context *ctx, struct ac_export_args *a)
        args[1] = LLVMConstInt(ctx->i32, a->enabled_channels, 0);
 
        if (a->compr) {
-               LLVMTypeRef i16 = LLVMInt16TypeInContext(ctx->context);
-               LLVMTypeRef v2i16 = LLVMVectorType(i16, 2);
-
                args[2] = LLVMBuildBitCast(ctx->builder, a->out[0],
-                               v2i16, "");
+                               ctx->v2i16, "");
                args[3] = LLVMBuildBitCast(ctx->builder, a->out[1],
-                               v2i16, "");
+                               ctx->v2i16, "");
                args[4] = LLVMConstInt(ctx->i1, a->done, 0);
                args[5] = LLVMConstInt(ctx->i1, a->valid_mask, 0);
 
@@ -2373,6 +2376,9 @@ LLVMValueRef ac_build_image_opcode(struct ac_llvm_context *ctx,
               (a->lod ? 1 : 0) +
               (a->level_zero ? 1 : 0) +
               (a->derivs[0] ? 1 : 0) <= 1);
+       assert((a->min_lod ? 1 : 0) +
+              (a->lod ? 1 : 0) +
+              (a->level_zero ? 1 : 0) <= 1);
 
        if (a->opcode == ac_image_get_lod) {
                switch (dim) {
@@ -2428,6 +2434,9 @@ LLVMValueRef ac_build_image_opcode(struct ac_llvm_context *ctx,
                args[num_args++] = LLVMBuildBitCast(ctx->builder, a->coords[i], coord_type, "");
        if (a->lod)
                args[num_args++] = LLVMBuildBitCast(ctx->builder, a->lod, coord_type, "");
+       if (a->min_lod)
+               args[num_args++] = LLVMBuildBitCast(ctx->builder, a->min_lod, coord_type, "");
+
        overload[num_overloads++] = sample ? ".f32" : ".i32";
 
        args[num_args++] = a->resource;
@@ -2481,7 +2490,7 @@ LLVMValueRef ac_build_image_opcode(struct ac_llvm_context *ctx,
        char intr_name[96];
        snprintf(intr_name, sizeof(intr_name),
                 "llvm.amdgcn.image.%s%s" /* base name */
-                "%s%s%s" /* sample/gather modifiers */
+                "%s%s%s%s" /* sample/gather modifiers */
                 ".%s.%s%s%s%s", /* dimension and type overloads */
                 name, atomic_subop,
                 a->compare ? ".c" : "",
@@ -2489,6 +2498,7 @@ LLVMValueRef ac_build_image_opcode(struct ac_llvm_context *ctx,
                 lod_suffix ? ".l" :
                 a->derivs[0] ? ".d" :
                 a->level_zero ? ".lz" : "",
+                a->min_lod ? ".cl" : "",
                 a->offset ? ".o" : "",
                 dimname,
                 atomic ? "i32" : "v4f32",
@@ -2534,10 +2544,7 @@ LLVMValueRef ac_build_image_get_sample_count(struct ac_llvm_context *ctx,
 LLVMValueRef ac_build_cvt_pkrtz_f16(struct ac_llvm_context *ctx,
                                    LLVMValueRef args[2])
 {
-       LLVMTypeRef v2f16 =
-               LLVMVectorType(LLVMHalfTypeInContext(ctx->context), 2);
-
-       return ac_build_intrinsic(ctx, "llvm.amdgcn.cvt.pkrtz", v2f16,
+       return ac_build_intrinsic(ctx, "llvm.amdgcn.cvt.pkrtz", ctx->v2f16,
                                  args, 2, AC_FUNC_ATTR_READNONE);
 }
 
@@ -3125,9 +3132,6 @@ void ac_optimize_vs_outputs(struct ac_llvm_context *ctx,
 
                        target -= V_008DFC_SQ_EXP_PARAM;
 
-                       if ((1u << target) & skip_output_mask)
-                               continue;
-
                        /* Parse the instruction. */
                        memset(&exp, 0, sizeof(exp));
                        exp.offset = target;
@@ -3151,12 +3155,13 @@ void ac_optimize_vs_outputs(struct ac_llvm_context *ctx,
                        }
 
                        /* Eliminate constant and duplicated PARAM exports. */
-                       if (ac_eliminate_const_output(vs_output_param_offset,
-                                                     num_outputs, &exp) ||
-                           ac_eliminate_duplicated_output(ctx,
-                                                          vs_output_param_offset,
-                                                          num_outputs, &exports,
-                                                          &exp)) {
+                       if (!((1u << target) & skip_output_mask) &&
+                            (ac_eliminate_const_output(vs_output_param_offset,
+                                                      num_outputs, &exp) ||
+                            ac_eliminate_duplicated_output(ctx,
+                                                           vs_output_param_offset,
+                                                           num_outputs, &exports,
+                                                           &exp))) {
                                removed_any = true;
                        } else {
                                exports.exp[exports.num++] = exp;
@@ -3708,9 +3713,7 @@ ac_build_mbcnt(struct ac_llvm_context *ctx, LLVMValueRef mask)
                                          (LLVMValueRef []) { mask, ctx->i32_0 },
                                          2, AC_FUNC_ATTR_READNONE);
        }
-       LLVMValueRef mask_vec = LLVMBuildBitCast(ctx->builder, mask,
-                                                LLVMVectorType(ctx->i32, 2),
-                                                "");
+       LLVMValueRef mask_vec = LLVMBuildBitCast(ctx->builder, mask, ctx->v2i32, "");
        LLVMValueRef mask_lo = LLVMBuildExtractElement(ctx->builder, mask_vec,
                                                       ctx->i32_0, "");
        LLVMValueRef mask_hi = LLVMBuildExtractElement(ctx->builder, mask_vec,