amd/rtld: layout and relocate LDS symbols
[mesa.git] / src / gallium / drivers / radeonsi / si_shader.c
index 29523474735a392c37e57367389a89f878e9cf9f..ab97cd872738f59d71c8b3237345ec88642641d2 100644 (file)
 #include "util/u_memory.h"
 #include "util/u_string.h"
 #include "tgsi/tgsi_build.h"
+#include "tgsi/tgsi_strings.h"
 #include "tgsi/tgsi_util.h"
 #include "tgsi/tgsi_dump.h"
 
+#include "ac_binary.h"
 #include "ac_exp_param.h"
 #include "ac_shader_util.h"
+#include "ac_rtld.h"
 #include "ac_llvm_util.h"
 #include "si_shader_internal.h"
 #include "si_pipe.h"
 
 #include "compiler/nir/nir.h"
 
-static const char *scratch_rsrc_dword0_symbol =
+static const char scratch_rsrc_dword0_symbol[] =
        "SCRATCH_RSRC_DWORD0";
 
-static const char *scratch_rsrc_dword1_symbol =
+static const char scratch_rsrc_dword1_symbol[] =
        "SCRATCH_RSRC_DWORD1";
 
 struct si_shader_output_values
@@ -51,22 +54,6 @@ struct si_shader_output_values
        ubyte vertex_stream[4];
 };
 
-/**
- * Used to collect types and other info about arguments of the LLVM function
- * before the function is created.
- */
-struct si_function_info {
-       LLVMTypeRef types[100];
-       LLVMValueRef *assign[100];
-       unsigned num_sgpr_params;
-       unsigned num_params;
-};
-
-enum si_arg_regfile {
-       ARG_SGPR,
-       ARG_VGPR
-};
-
 static void si_init_shader_ctx(struct si_shader_context *ctx,
                               struct si_screen *sscreen,
                               struct ac_llvm_compiler *compiler);
@@ -86,6 +73,8 @@ static void si_build_ps_prolog_function(struct si_shader_context *ctx,
                                        union si_shader_part_key *key);
 static void si_build_ps_epilog_function(struct si_shader_context *ctx,
                                        union si_shader_part_key *key);
+static void si_fix_resource_usage(struct si_screen *sscreen,
+                                 struct si_shader *shader);
 
 /* Ideally pass the sample mask input to the PS epilog as v14, which
  * is its usual location, so that the shader doesn't have to add v_mov.
@@ -103,7 +92,7 @@ static bool llvm_type_is_64bit(struct si_shader_context *ctx,
 
 static bool is_merged_shader(struct si_shader_context *ctx)
 {
-       if (ctx->screen->info.chip_class <= VI)
+       if (ctx->screen->info.chip_class <= GFX8)
                return false;
 
        return ctx->shader->key.as_ls ||
@@ -112,13 +101,13 @@ static bool is_merged_shader(struct si_shader_context *ctx)
               ctx->type == PIPE_SHADER_GEOMETRY;
 }
 
-static void si_init_function_info(struct si_function_info *fninfo)
+void si_init_function_info(struct si_function_info *fninfo)
 {
        fninfo->num_params = 0;
        fninfo->num_sgpr_params = 0;
 }
 
-static unsigned add_arg_assign(struct si_function_info *fninfo,
+unsigned add_arg_assign(struct si_function_info *fninfo,
                        enum si_arg_regfile regfile, LLVMTypeRef type,
                        LLVMValueRef *assign)
 {
@@ -378,10 +367,7 @@ get_tcs_out_current_patch_offset(struct si_shader_context *ctx)
        LLVMValueRef patch_stride = get_tcs_out_patch_stride(ctx);
        LLVMValueRef rel_patch_id = get_rel_patch_id(ctx);
 
-       return LLVMBuildAdd(ctx->ac.builder, patch0_offset,
-                           LLVMBuildMul(ctx->ac.builder, patch_stride,
-                                        rel_patch_id, ""),
-                           "");
+       return ac_build_imad(&ctx->ac, patch_stride, rel_patch_id, patch0_offset);
 }
 
 static LLVMValueRef
@@ -392,10 +378,7 @@ get_tcs_out_current_patch_data_offset(struct si_shader_context *ctx)
        LLVMValueRef patch_stride = get_tcs_out_patch_stride(ctx);
        LLVMValueRef rel_patch_id = get_rel_patch_id(ctx);
 
-       return LLVMBuildAdd(ctx->ac.builder, patch0_patch_data_offset,
-                           LLVMBuildMul(ctx->ac.builder, patch_stride,
-                                        rel_patch_id, ""),
-                           "");
+       return ac_build_imad(&ctx->ac, patch_stride, rel_patch_id, patch0_patch_data_offset);
 }
 
 static LLVMValueRef get_num_tcs_out_vertices(struct si_shader_context *ctx)
@@ -434,35 +417,6 @@ static LLVMValueRef get_tcs_in_vertex_dw_stride(struct si_shader_context *ctx)
        }
 }
 
-static LLVMValueRef get_instance_index_for_fetch(
-       struct si_shader_context *ctx,
-       unsigned param_start_instance, LLVMValueRef divisor)
-{
-       LLVMValueRef result = ctx->abi.instance_id;
-
-       /* The division must be done before START_INSTANCE is added. */
-       if (divisor != ctx->i32_1)
-               result = LLVMBuildUDiv(ctx->ac.builder, result, divisor, "");
-
-       return LLVMBuildAdd(ctx->ac.builder, result,
-                           LLVMGetParam(ctx->main_fn, param_start_instance), "");
-}
-
-/* Bitcast <4 x float> to <2 x double>, extract the component, and convert
- * to float. */
-static LLVMValueRef extract_double_to_float(struct si_shader_context *ctx,
-                                           LLVMValueRef vec4,
-                                           unsigned double_index)
-{
-       LLVMBuilderRef builder = ctx->ac.builder;
-       LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx->ac.context);
-       LLVMValueRef dvec2 = LLVMBuildBitCast(builder, vec4,
-                                             LLVMVectorType(f64, 2), "");
-       LLVMValueRef index = LLVMConstInt(ctx->i32, double_index, 0);
-       LLVMValueRef value = LLVMBuildExtractElement(builder, dvec2, index, "");
-       return LLVMBuildFPTrunc(builder, value, ctx->f32, "");
-}
-
 static LLVMValueRef unpack_sint16(struct si_shader_context *ctx,
                                 LLVMValueRef i32, unsigned index)
 {
@@ -554,17 +508,12 @@ void si_llvm_load_input_vs(
                return;
        }
 
-       unsigned chan;
-       unsigned fix_fetch;
-       unsigned num_fetches;
-       unsigned fetch_stride;
-       unsigned num_channels;
-
+       union si_vs_fix_fetch fix_fetch;
        LLVMValueRef t_list_ptr;
        LLVMValueRef t_offset;
        LLVMValueRef t_list;
        LLVMValueRef vertex_index;
-       LLVMValueRef input[3];
+       LLVMValueRef tmp;
 
        /* Load the T list */
        t_list_ptr = LLVMGetParam(ctx->main_fn, ctx->param_vertex_buffers);
@@ -577,66 +526,84 @@ void si_llvm_load_input_vs(
                                    ctx->param_vertex_index0 +
                                    input_index);
 
-       fix_fetch = ctx->shader->key.mono.vs_fix_fetch[input_index];
+       /* Use the open-coded implementation for all loads of doubles and
+        * of dword-sized data that needs fixups. We need to insert conversion
+        * code anyway, and the amd/common code does it for us.
+        *
+        * Note: On LLVM <= 8, we can only open-code formats with
+        * channel size >= 4 bytes.
+        */
+       bool opencode = ctx->shader->key.mono.vs_fetch_opencode & (1 << input_index);
+       fix_fetch.bits = ctx->shader->key.mono.vs_fix_fetch[input_index].bits;
+       if (opencode ||
+           (fix_fetch.u.log_size == 3 && fix_fetch.u.format == AC_FETCH_FORMAT_FLOAT) ||
+           (fix_fetch.u.log_size == 2)) {
+               tmp = ac_build_opencoded_load_format(
+                               &ctx->ac, fix_fetch.u.log_size, fix_fetch.u.num_channels_m1 + 1,
+                               fix_fetch.u.format, fix_fetch.u.reverse, !opencode,
+                               t_list, vertex_index, ctx->ac.i32_0, ctx->ac.i32_0,
+                               false, false, true);
+               for (unsigned i = 0; i < 4; ++i)
+                       out[i] = LLVMBuildExtractElement(ctx->ac.builder, tmp, LLVMConstInt(ctx->i32, i, false), "");
+               return;
+       }
 
        /* Do multiple loads for special formats. */
-       switch (fix_fetch) {
-       case SI_FIX_FETCH_RGB_64_FLOAT:
-               num_fetches = 3; /* 3 2-dword loads */
-               fetch_stride = 8;
-               num_channels = 2;
-               break;
-       case SI_FIX_FETCH_RGBA_64_FLOAT:
-               num_fetches = 2; /* 2 4-dword loads */
-               fetch_stride = 16;
-               num_channels = 4;
-               break;
-       case SI_FIX_FETCH_RGB_8:
-       case SI_FIX_FETCH_RGB_8_INT:
-               num_fetches = 3;
-               fetch_stride = 1;
-               num_channels = 1;
-               break;
-       case SI_FIX_FETCH_RGB_16:
-       case SI_FIX_FETCH_RGB_16_INT:
-               num_fetches = 3;
-               fetch_stride = 2;
-               num_channels = 1;
-               break;
-       default:
+       unsigned required_channels = util_last_bit(info->input_usage_mask[input_index]);
+       LLVMValueRef fetches[4];
+       unsigned num_fetches;
+       unsigned fetch_stride;
+       unsigned channels_per_fetch;
+
+       if (fix_fetch.u.log_size <= 1 && fix_fetch.u.num_channels_m1 == 2) {
+               num_fetches = MIN2(required_channels, 3);
+               fetch_stride = 1 << fix_fetch.u.log_size;
+               channels_per_fetch = 1;
+       } else {
                num_fetches = 1;
                fetch_stride = 0;
-               num_channels = util_last_bit(info->input_usage_mask[input_index]);
+               channels_per_fetch = required_channels;
        }
 
-       for (unsigned i = 0; i < num_fetches; i++) {
+       for (unsigned i = 0; i < num_fetches; ++i) {
                LLVMValueRef voffset = LLVMConstInt(ctx->i32, fetch_stride * i, 0);
-
-               input[i] = ac_build_buffer_load_format(&ctx->ac, t_list,
-                                                      vertex_index, voffset,
-                                                      num_channels, false, true);
-               input[i] = ac_build_expand_to_vec4(&ctx->ac, input[i], num_channels);
+               fetches[i] = ac_build_buffer_load_format(&ctx->ac, t_list, vertex_index, voffset,
+                                                        channels_per_fetch, false, true);
        }
 
-       /* Break up the vec4 into individual components */
-       for (chan = 0; chan < 4; chan++) {
-               LLVMValueRef llvm_chan = LLVMConstInt(ctx->i32, chan, 0);
-               out[chan] = LLVMBuildExtractElement(ctx->ac.builder,
-                                                   input[0], llvm_chan, "");
+       if (num_fetches == 1 && channels_per_fetch > 1) {
+               LLVMValueRef fetch = fetches[0];
+               for (unsigned i = 0; i < channels_per_fetch; ++i) {
+                       tmp = LLVMConstInt(ctx->i32, i, false);
+                       fetches[i] = LLVMBuildExtractElement(
+                               ctx->ac.builder, fetch, tmp, "");
+               }
+               num_fetches = channels_per_fetch;
+               channels_per_fetch = 1;
        }
 
-       switch (fix_fetch) {
-       case SI_FIX_FETCH_A2_SNORM:
-       case SI_FIX_FETCH_A2_SSCALED:
-       case SI_FIX_FETCH_A2_SINT: {
-               /* The hardware returns an unsigned value; convert it to a
-                * signed one.
+       for (unsigned i = num_fetches; i < 4; ++i)
+               fetches[i] = LLVMGetUndef(ctx->f32);
+
+       if (fix_fetch.u.log_size <= 1 && fix_fetch.u.num_channels_m1 == 2 &&
+           required_channels == 4) {
+               if (fix_fetch.u.format == AC_FETCH_FORMAT_UINT || fix_fetch.u.format == AC_FETCH_FORMAT_SINT)
+                       fetches[3] = ctx->ac.i32_1;
+               else
+                       fetches[3] = ctx->ac.f32_1;
+       } else if (fix_fetch.u.log_size == 3 &&
+                  (fix_fetch.u.format == AC_FETCH_FORMAT_SNORM ||
+                   fix_fetch.u.format == AC_FETCH_FORMAT_SSCALED ||
+                   fix_fetch.u.format == AC_FETCH_FORMAT_SINT) &&
+                  required_channels == 4) {
+               /* For 2_10_10_10, the hardware returns an unsigned value;
+                * convert it to a signed one.
                 */
-               LLVMValueRef tmp = out[3];
+               LLVMValueRef tmp = fetches[3];
                LLVMValueRef c30 = LLVMConstInt(ctx->i32, 30, 0);
 
                /* First, recover the sign-extended signed integer value. */
-               if (fix_fetch == SI_FIX_FETCH_A2_SSCALED)
+               if (fix_fetch.u.format == AC_FETCH_FORMAT_SSCALED)
                        tmp = LLVMBuildFPToUI(ctx->ac.builder, tmp, ctx->i32, "");
                else
                        tmp = ac_to_integer(&ctx->ac, tmp);
@@ -648,110 +615,26 @@ void si_llvm_load_input_vs(
                 * exponent.
                 */
                tmp = LLVMBuildShl(ctx->ac.builder, tmp,
-                                  fix_fetch == SI_FIX_FETCH_A2_SNORM ?
+                                  fix_fetch.u.format == AC_FETCH_FORMAT_SNORM ?
                                   LLVMConstInt(ctx->i32, 7, 0) : c30, "");
                tmp = LLVMBuildAShr(ctx->ac.builder, tmp, c30, "");
 
                /* Convert back to the right type. */
-               if (fix_fetch == SI_FIX_FETCH_A2_SNORM) {
+               if (fix_fetch.u.format == AC_FETCH_FORMAT_SNORM) {
                        LLVMValueRef clamp;
                        LLVMValueRef neg_one = LLVMConstReal(ctx->f32, -1.0);
                        tmp = LLVMBuildSIToFP(ctx->ac.builder, tmp, ctx->f32, "");
                        clamp = LLVMBuildFCmp(ctx->ac.builder, LLVMRealULT, tmp, neg_one, "");
                        tmp = LLVMBuildSelect(ctx->ac.builder, clamp, neg_one, tmp, "");
-               } else if (fix_fetch == SI_FIX_FETCH_A2_SSCALED) {
+               } else if (fix_fetch.u.format == AC_FETCH_FORMAT_SSCALED) {
                        tmp = LLVMBuildSIToFP(ctx->ac.builder, tmp, ctx->f32, "");
                }
 
-               out[3] = tmp;
-               break;
-       }
-       case SI_FIX_FETCH_RGBA_32_UNORM:
-       case SI_FIX_FETCH_RGBX_32_UNORM:
-               for (chan = 0; chan < 4; chan++) {
-                       out[chan] = ac_to_integer(&ctx->ac, out[chan]);
-                       out[chan] = LLVMBuildUIToFP(ctx->ac.builder,
-                                                   out[chan], ctx->f32, "");
-                       out[chan] = LLVMBuildFMul(ctx->ac.builder, out[chan],
-                                                 LLVMConstReal(ctx->f32, 1.0 / UINT_MAX), "");
-               }
-               /* RGBX UINT returns 1 in alpha, which would be rounded to 0 by normalizing. */
-               if (fix_fetch == SI_FIX_FETCH_RGBX_32_UNORM)
-                       out[3] = LLVMConstReal(ctx->f32, 1);
-               break;
-       case SI_FIX_FETCH_RGBA_32_SNORM:
-       case SI_FIX_FETCH_RGBX_32_SNORM:
-       case SI_FIX_FETCH_RGBA_32_FIXED:
-       case SI_FIX_FETCH_RGBX_32_FIXED: {
-               double scale;
-               if (fix_fetch >= SI_FIX_FETCH_RGBA_32_FIXED)
-                       scale = 1.0 / 0x10000;
-               else
-                       scale = 1.0 / INT_MAX;
-
-               for (chan = 0; chan < 4; chan++) {
-                       out[chan] = ac_to_integer(&ctx->ac, out[chan]);
-                       out[chan] = LLVMBuildSIToFP(ctx->ac.builder,
-                                                   out[chan], ctx->f32, "");
-                       out[chan] = LLVMBuildFMul(ctx->ac.builder, out[chan],
-                                                 LLVMConstReal(ctx->f32, scale), "");
-               }
-               /* RGBX SINT returns 1 in alpha, which would be rounded to 0 by normalizing. */
-               if (fix_fetch == SI_FIX_FETCH_RGBX_32_SNORM ||
-                   fix_fetch == SI_FIX_FETCH_RGBX_32_FIXED)
-                       out[3] = LLVMConstReal(ctx->f32, 1);
-               break;
+               fetches[3] = tmp;
        }
-       case SI_FIX_FETCH_RGBA_32_USCALED:
-               for (chan = 0; chan < 4; chan++) {
-                       out[chan] = ac_to_integer(&ctx->ac, out[chan]);
-                       out[chan] = LLVMBuildUIToFP(ctx->ac.builder,
-                                                   out[chan], ctx->f32, "");
-               }
-               break;
-       case SI_FIX_FETCH_RGBA_32_SSCALED:
-               for (chan = 0; chan < 4; chan++) {
-                       out[chan] = ac_to_integer(&ctx->ac, out[chan]);
-                       out[chan] = LLVMBuildSIToFP(ctx->ac.builder,
-                                                   out[chan], ctx->f32, "");
-               }
-               break;
-       case SI_FIX_FETCH_RG_64_FLOAT:
-               for (chan = 0; chan < 2; chan++)
-                       out[chan] = extract_double_to_float(ctx, input[0], chan);
-
-               out[2] = LLVMConstReal(ctx->f32, 0);
-               out[3] = LLVMConstReal(ctx->f32, 1);
-               break;
-       case SI_FIX_FETCH_RGB_64_FLOAT:
-               for (chan = 0; chan < 3; chan++)
-                       out[chan] = extract_double_to_float(ctx, input[chan], 0);
 
-               out[3] = LLVMConstReal(ctx->f32, 1);
-               break;
-       case SI_FIX_FETCH_RGBA_64_FLOAT:
-               for (chan = 0; chan < 4; chan++) {
-                       out[chan] = extract_double_to_float(ctx, input[chan / 2],
-                                                           chan % 2);
-               }
-               break;
-       case SI_FIX_FETCH_RGB_8:
-       case SI_FIX_FETCH_RGB_8_INT:
-       case SI_FIX_FETCH_RGB_16:
-       case SI_FIX_FETCH_RGB_16_INT:
-               for (chan = 0; chan < 3; chan++) {
-                       out[chan] = LLVMBuildExtractElement(ctx->ac.builder,
-                                                           input[chan],
-                                                           ctx->i32_0, "");
-               }
-               if (fix_fetch == SI_FIX_FETCH_RGB_8 ||
-                   fix_fetch == SI_FIX_FETCH_RGB_16) {
-                       out[3] = LLVMConstReal(ctx->f32, 1);
-               } else {
-                       out[3] = ac_to_float(&ctx->ac, ctx->i32_1);
-               }
-               break;
-       }
+       for (unsigned i = 0; i < 4; ++i)
+               out[i] = ac_to_float(&ctx->ac, fetches[i]);
 }
 
 static void declare_input_vs(
@@ -815,12 +698,8 @@ LLVMValueRef si_get_indirect_index(struct si_shader_context *ctx,
                result = ac_to_integer(&ctx->ac, result);
        }
 
-       if (addr_mul != 1)
-               result = LLVMBuildMul(ctx->ac.builder, result,
-                                     LLVMConstInt(ctx->i32, addr_mul, 0), "");
-       result = LLVMBuildAdd(ctx->ac.builder, result,
-                             LLVMConstInt(ctx->i32, rel_index, 0), "");
-       return result;
+       return ac_build_imad(&ctx->ac, result, LLVMConstInt(ctx->i32, addr_mul, 0),
+                            LLVMConstInt(ctx->i32, rel_index, 0));
 }
 
 /**
@@ -847,15 +726,13 @@ static LLVMValueRef get_dw_address_from_generic_indices(struct si_shader_context
                                                        bool is_patch)
 {
        if (vertex_dw_stride) {
-               base_addr = LLVMBuildAdd(ctx->ac.builder, base_addr,
-                                        LLVMBuildMul(ctx->ac.builder, vertex_index,
-                                                     vertex_dw_stride, ""), "");
+               base_addr = ac_build_imad(&ctx->ac, vertex_index,
+                                         vertex_dw_stride, base_addr);
        }
 
        if (param_index) {
-               base_addr = LLVMBuildAdd(ctx->ac.builder, base_addr,
-                                        LLVMBuildMul(ctx->ac.builder, param_index,
-                                                     LLVMConstInt(ctx->i32, 4, 0), ""), "");
+               base_addr = ac_build_imad(&ctx->ac, param_index,
+                                         LLVMConstInt(ctx->i32, 4, 0), base_addr);
        }
 
        int param = is_patch ?
@@ -975,22 +852,15 @@ static LLVMValueRef get_tcs_tes_buffer_address(struct si_shader_context *ctx,
 
        constant16 = LLVMConstInt(ctx->i32, 16, 0);
        if (vertex_index) {
-               base_addr = LLVMBuildMul(ctx->ac.builder, rel_patch_id,
-                                        vertices_per_patch, "");
-
-               base_addr = LLVMBuildAdd(ctx->ac.builder, base_addr,
-                                        vertex_index, "");
-
+               base_addr = ac_build_imad(&ctx->ac, rel_patch_id,
+                                         vertices_per_patch, vertex_index);
                param_stride = total_vertices;
        } else {
                base_addr = rel_patch_id;
                param_stride = num_patches;
        }
 
-       base_addr = LLVMBuildAdd(ctx->ac.builder, base_addr,
-                                LLVMBuildMul(ctx->ac.builder, param_index,
-                                             param_stride, ""), "");
-
+       base_addr = ac_build_imad(&ctx->ac, param_index, param_stride, base_addr);
        base_addr = LLVMBuildMul(ctx->ac.builder, base_addr, constant16, "");
 
        if (!vertex_index) {
@@ -1223,11 +1093,11 @@ static LLVMValueRef get_tess_ring_descriptor(struct si_shader_context *ctx,
 static LLVMValueRef fetch_input_tcs(
        struct lp_build_tgsi_context *bld_base,
        const struct tgsi_full_src_register *reg,
-       enum tgsi_opcode_type type, unsigned swizzle)
+       enum tgsi_opcode_type type, unsigned swizzle_in)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
        LLVMValueRef dw_addr, stride;
-
+       unsigned swizzle = swizzle_in & 0xffff;
        stride = get_tcs_in_vertex_dw_stride(ctx);
        dw_addr = get_tcs_in_current_patch_offset(ctx);
        dw_addr = get_dw_address(ctx, NULL, reg, stride, dw_addr);
@@ -1308,10 +1178,11 @@ static LLVMValueRef si_nir_load_tcs_varyings(struct ac_shader_abi *abi,
 static LLVMValueRef fetch_output_tcs(
                struct lp_build_tgsi_context *bld_base,
                const struct tgsi_full_src_register *reg,
-               enum tgsi_opcode_type type, unsigned swizzle)
+               enum tgsi_opcode_type type, unsigned swizzle_in)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
        LLVMValueRef dw_addr, stride;
+       unsigned swizzle = (swizzle_in & 0xffff);
 
        if (reg->Register.Dimension) {
                stride = get_tcs_out_vertex_dw_stride(ctx);
@@ -1328,10 +1199,11 @@ static LLVMValueRef fetch_output_tcs(
 static LLVMValueRef fetch_input_tes(
        struct lp_build_tgsi_context *bld_base,
        const struct tgsi_full_src_register *reg,
-       enum tgsi_opcode_type type, unsigned swizzle)
+       enum tgsi_opcode_type type, unsigned swizzle_in)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
        LLVMValueRef base, addr;
+       unsigned swizzle = (swizzle_in & 0xffff);
 
        base = LLVMGetParam(ctx->main_fn, ctx->param_tcs_offchip_offset);
        addr = get_tcs_tes_buffer_address_from_reg(ctx, NULL, reg);
@@ -1383,8 +1255,20 @@ LLVMValueRef si_nir_load_input_tes(struct ac_shader_abi *abi,
        LLVMValueRef value[4];
        for (unsigned i = 0; i < num_components; i++) {
                unsigned offset = i;
-               if (llvm_type_is_64bit(ctx, type))
+               if (llvm_type_is_64bit(ctx, type)) {
                        offset *= 2;
+                       if (offset == 4) {
+                                addr = get_tcs_tes_buffer_address_from_generic_indices(ctx,
+                                                                                       vertex_index,
+                                                                                       param_index,
+                                                                                       driver_location + 1,
+                                                                                       info->input_semantic_name,
+                                                                                       info->input_semantic_index,
+                                                                                       is_patch);
+                       }
+
+                        offset = offset % 4;
+               }
 
                offset += component;
                value[i + component] = buffer_load(&ctx->bld_base, type, offset,
@@ -1506,7 +1390,7 @@ static void si_nir_store_output_tcs(struct ac_shader_abi *abi,
        unsigned driver_location = var->data.driver_location;
        LLVMValueRef dw_addr, stride;
        LLVMValueRef buffer, base, addr;
-       LLVMValueRef values[4];
+       LLVMValueRef values[8];
        bool skip_lds_store;
        bool is_tess_factor = false, is_tess_inner = false;
 
@@ -1568,11 +1452,22 @@ static void si_nir_store_output_tcs(struct ac_shader_abi *abi,
                                                               info->output_semantic_index,
                                                               is_patch);
 
-       for (unsigned chan = 0; chan < 4; chan++) {
+       for (unsigned chan = 0; chan < 8; chan++) {
                if (!(writemask & (1 << chan)))
                        continue;
                LLVMValueRef value = ac_llvm_extract_elem(&ctx->ac, src, chan - component);
 
+               unsigned buffer_store_offset = chan % 4;
+               if (chan == 4) {
+                        addr = get_tcs_tes_buffer_address_from_generic_indices(ctx,
+                                                                               vertex_index,
+                                                                               param_index,
+                                                                               driver_location + 1,
+                                                                               info->output_semantic_name,
+                                                                               info->output_semantic_index,
+                                                                               is_patch);
+               }
+
                /* Skip LDS stores if there is no LDS read of this output. */
                if (!skip_lds_store)
                        lds_store(ctx, chan, dw_addr, value);
@@ -1583,7 +1478,8 @@ static void si_nir_store_output_tcs(struct ac_shader_abi *abi,
                if (writemask != 0xF && !is_tess_factor) {
                        ac_build_buffer_store_dword(&ctx->ac, buffer, value, 1,
                                                    addr, base,
-                                                   4 * chan, 1, 0, true, false);
+                                                   4 * buffer_store_offset,
+                                                    1, 0, true, false);
                }
 
                /* Write tess factors into VGPRs for the epilog. */
@@ -1715,10 +1611,11 @@ static LLVMValueRef fetch_input_gs(
        struct lp_build_tgsi_context *bld_base,
        const struct tgsi_full_src_register *reg,
        enum tgsi_opcode_type type,
-       unsigned swizzle)
+       unsigned swizzle_in)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
        struct tgsi_shader_info *info = &ctx->shader->selector->info;
+       unsigned swizzle = swizzle_in & 0xffff;
 
        unsigned semantic_name = info->input_semantic_name[reg->Register.Index];
        if (swizzle != ~0 && semantic_name == TGSI_SEMANTIC_PRIMID)
@@ -2238,12 +2135,7 @@ void si_load_system_value(struct si_shader_context *ctx,
                break;
 
        case TGSI_SEMANTIC_HELPER_INVOCATION:
-               value = ac_build_intrinsic(&ctx->ac,
-                                          "llvm.amdgcn.ps.live",
-                                          ctx->i1, NULL, 0,
-                                          AC_FUNC_ATTR_READNONE);
-               value = LLVMBuildNot(ctx->ac.builder, value, "");
-               value = LLVMBuildSExt(ctx->ac.builder, value, ctx->i32, "");
+               value = ac_build_load_helper_invocation(&ctx->ac);
                break;
 
        case TGSI_SEMANTIC_SUBGROUP_SIZE:
@@ -2286,6 +2178,10 @@ void si_load_system_value(struct si_shader_context *ctx,
                break;
        }
 
+       case TGSI_SEMANTIC_CS_USER_DATA:
+               value = LLVMGetParam(ctx->main_fn, ctx->param_cs_user_data);
+               break;
+
        default:
                assert(!"unknown system value");
                return;
@@ -2299,7 +2195,7 @@ void si_declare_compute_memory(struct si_shader_context *ctx)
        struct si_shader_selector *sel = ctx->shader->selector;
        unsigned lds_size = sel->info.properties[TGSI_PROPERTY_CS_LOCAL_SIZE];
 
-       LLVMTypeRef i8p = LLVMPointerType(ctx->i8, AC_LOCAL_ADDR_SPACE);
+       LLVMTypeRef i8p = LLVMPointerType(ctx->i8, AC_ADDR_SPACE_LDS);
        LLVMValueRef var;
 
        assert(!ctx->ac.lds);
@@ -2307,7 +2203,7 @@ void si_declare_compute_memory(struct si_shader_context *ctx)
        var = LLVMAddGlobalInAddressSpace(ctx->ac.module,
                                          LLVMArrayType(ctx->i8, lds_size),
                                          "compute_lds",
-                                         AC_LOCAL_ADDR_SPACE);
+                                         AC_ADDR_SPACE_LDS);
        LLVMSetAlignment(var, 4);
 
        ctx->ac.lds = LLVMBuildBitCast(ctx->ac.builder, var, i8p, "");
@@ -2336,18 +2232,9 @@ static LLVMValueRef load_const_buffer_desc_fast_path(struct si_shader_context *c
        ptr = LLVMBuildPtrToInt(ctx->ac.builder, ptr, ctx->ac.intptr, "");
 
        LLVMValueRef desc0, desc1;
-       if (HAVE_32BIT_POINTERS) {
-               desc0 = ptr;
-               desc1 = LLVMConstInt(ctx->i32,
-                                    S_008F04_BASE_ADDRESS_HI(ctx->screen->info.address32_hi), 0);
-       } else {
-               ptr = LLVMBuildBitCast(ctx->ac.builder, ptr, ctx->v2i32, "");
-               desc0 = LLVMBuildExtractElement(ctx->ac.builder, ptr, ctx->i32_0, "");
-               desc1 = LLVMBuildExtractElement(ctx->ac.builder, ptr, ctx->i32_1, "");
-               /* Mask out all bits except BASE_ADDRESS_HI. */
-               desc1 = LLVMBuildAnd(ctx->ac.builder, desc1,
-                                    LLVMConstInt(ctx->i32, ~C_008F04_BASE_ADDRESS_HI, 0), "");
-       }
+       desc0 = ptr;
+       desc1 = LLVMConstInt(ctx->i32,
+                            S_008F04_BASE_ADDRESS_HI(ctx->screen->info.address32_hi), 0);
 
        LLVMValueRef desc_elems[] = {
                desc0,
@@ -2412,16 +2299,17 @@ static LLVMValueRef fetch_constant(
        struct lp_build_tgsi_context *bld_base,
        const struct tgsi_full_src_register *reg,
        enum tgsi_opcode_type type,
-       unsigned swizzle)
+       unsigned swizzle_in)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
        struct si_shader_selector *sel = ctx->shader->selector;
        const struct tgsi_ind_register *ireg = &reg->Indirect;
        unsigned buf, idx;
+       unsigned swizzle = swizzle_in & 0xffff;
 
        LLVMValueRef addr, bufp;
 
-       if (swizzle == LP_CHAN_ALL) {
+       if (swizzle_in == LP_CHAN_ALL) {
                unsigned chan;
                LLVMValueRef values[4];
                for (chan = 0; chan < TGSI_NUM_CHANNELS; ++chan)
@@ -2435,7 +2323,7 @@ static LLVMValueRef fetch_constant(
                LLVMValueRef lo, hi;
 
                lo = fetch_constant(bld_base, reg, TGSI_TYPE_UNSIGNED, swizzle);
-               hi = fetch_constant(bld_base, reg, TGSI_TYPE_UNSIGNED, swizzle + 1);
+               hi = fetch_constant(bld_base, reg, TGSI_TYPE_UNSIGNED, (swizzle_in >> 16));
                return si_llvm_emit_fetch_64bit(bld_base, tgsi2llvmtype(bld_base, type),
                                                lo, hi);
        }
@@ -2620,7 +2508,7 @@ static void si_alpha_test(struct lp_build_tgsi_context *bld_base,
                        LLVMBuildFCmp(ctx->ac.builder, cond, alpha, alpha_ref, "");
                ac_build_kill_if_false(&ctx->ac, alpha_pass);
        } else {
-               ac_build_kill_if_false(&ctx->ac, LLVMConstInt(ctx->i1, 0, 0));
+               ac_build_kill_if_false(&ctx->ac, ctx->i1false);
        }
 }
 
@@ -2678,10 +2566,8 @@ static void si_llvm_emit_clipvertex(struct si_shader_context *ctx,
                                                                const_chan) * 4, 0);
                                base_elt = buffer_load_const(ctx, const_resource,
                                                             addr);
-                               args->out[chan] =
-                                       LLVMBuildFAdd(ctx->ac.builder, args->out[chan],
-                                                     LLVMBuildFMul(ctx->ac.builder, base_elt,
-                                                                   out_elts[const_chan], ""), "");
+                               args->out[chan] = ac_build_fmad(&ctx->ac, base_elt,
+                                                               out_elts[const_chan], args->out[chan]);
                        }
                }
 
@@ -2744,13 +2630,16 @@ static void emit_streamout_output(struct si_shader_context *ctx,
                vdata = out[0];
                break;
        case 2: /* as v2i32 */
-       case 3: /* as v4i32 (aligned to 4) */
-       case 4: /* as v4i32 */
-               vdata = LLVMGetUndef(LLVMVectorType(ctx->i32, util_next_power_of_two(num_comps)));
-               for (int j = 0; j < num_comps; j++) {
-                       vdata = LLVMBuildInsertElement(ctx->ac.builder, vdata, out[j],
-                                                      LLVMConstInt(ctx->i32, j, 0), "");
+       case 3: /* as v3i32 */
+               if (ac_has_vec3_support(ctx->screen->info.chip_class, false)) {
+                       vdata = ac_build_gather_values(&ctx->ac, out, num_comps);
+                       break;
                }
+               /* as v4i32 (aligned to 4) */
+               out[3] = LLVMGetUndef(ctx->i32);
+               /* fall through */
+       case 4: /* as v4i32 */
+               vdata = ac_build_gather_values(&ctx->ac, out, util_next_power_of_two(num_comps));
                break;
        }
 
@@ -2823,9 +2712,9 @@ static void si_llvm_emit_streamout(struct si_shader_context *ctx,
                                                              ctx->param_streamout_offset[i]);
                        so_offset = LLVMBuildMul(builder, so_offset, LLVMConstInt(ctx->i32, 4, 0), "");
 
-                       so_write_offset[i] = LLVMBuildMul(builder, so_write_index,
-                                                         LLVMConstInt(ctx->i32, so->stride[i]*4, 0), "");
-                       so_write_offset[i] = LLVMBuildAdd(builder, so_write_offset[i], so_offset, "");
+                       so_write_offset[i] = ac_build_imad(&ctx->ac, so_write_index,
+                                                          LLVMConstInt(ctx->i32, so->stride[i]*4, 0),
+                                                          so_offset);
                }
 
                /* Write streamout data. */
@@ -2903,6 +2792,70 @@ static void si_build_param_exports(struct si_shader_context *ctx,
        shader->info.nr_param_exports = param_count;
 }
 
+/**
+ * Vertex color clamping.
+ *
+ * This uses a state constant loaded in a user data SGPR and
+ * an IF statement is added that clamps all colors if the constant
+ * is true.
+ */
+static void si_vertex_color_clamping(struct si_shader_context *ctx,
+                                    struct si_shader_output_values *outputs,
+                                    unsigned noutput)
+{
+       LLVMValueRef addr[SI_MAX_VS_OUTPUTS][4];
+       bool has_colors = false;
+
+       /* Store original colors to alloca variables. */
+       for (unsigned i = 0; i < noutput; i++) {
+               if (outputs[i].semantic_name != TGSI_SEMANTIC_COLOR &&
+                   outputs[i].semantic_name != TGSI_SEMANTIC_BCOLOR)
+                       continue;
+
+               for (unsigned j = 0; j < 4; j++) {
+                       addr[i][j] = ac_build_alloca_undef(&ctx->ac, ctx->f32, "");
+                       LLVMBuildStore(ctx->ac.builder, outputs[i].values[j], addr[i][j]);
+               }
+               has_colors = true;
+       }
+
+       if (!has_colors)
+               return;
+
+       /* The state is in the first bit of the user SGPR. */
+       LLVMValueRef cond = LLVMGetParam(ctx->main_fn, ctx->param_vs_state_bits);
+       cond = LLVMBuildTrunc(ctx->ac.builder, cond, ctx->i1, "");
+
+       struct lp_build_if_state if_ctx;
+       lp_build_if(&if_ctx, &ctx->gallivm, cond);
+
+       /* Store clamped colors to alloca variables within the conditional block. */
+       for (unsigned i = 0; i < noutput; i++) {
+               if (outputs[i].semantic_name != TGSI_SEMANTIC_COLOR &&
+                   outputs[i].semantic_name != TGSI_SEMANTIC_BCOLOR)
+                       continue;
+
+               for (unsigned j = 0; j < 4; j++) {
+                       LLVMBuildStore(ctx->ac.builder,
+                                      ac_build_clamp(&ctx->ac, outputs[i].values[j]),
+                                      addr[i][j]);
+               }
+       }
+       lp_build_endif(&if_ctx);
+
+       /* Load clamped colors */
+       for (unsigned i = 0; i < noutput; i++) {
+               if (outputs[i].semantic_name != TGSI_SEMANTIC_COLOR &&
+                   outputs[i].semantic_name != TGSI_SEMANTIC_BCOLOR)
+                       continue;
+
+               for (unsigned j = 0; j < 4; j++) {
+                       outputs[i].values[j] =
+                               LLVMBuildLoad(ctx->ac.builder, addr[i][j], "");
+               }
+       }
+}
+
 /* Generate export instructions for hardware VS shader stage */
 static void si_llvm_export_vs(struct si_shader_context *ctx,
                              struct si_shader_output_values *outputs,
@@ -2914,6 +2867,8 @@ static void si_llvm_export_vs(struct si_shader_context *ctx,
        unsigned pos_idx;
        int i;
 
+       si_vertex_color_clamping(ctx, outputs, noutput);
+
        /* Build position exports. */
        for (i = 0; i < noutput; i++) {
                switch (outputs[i].semantic_name) {
@@ -3058,7 +3013,7 @@ static void si_copy_tcs_inputs(struct lp_build_tgsi_context *bld_base)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
        LLVMValueRef invocation_id, buffer, buffer_offset;
-       LLVMValueRef lds_vertex_stride, lds_vertex_offset, lds_base;
+       LLVMValueRef lds_vertex_stride, lds_base;
        uint64_t inputs;
 
        invocation_id = unpack_llvm_param(ctx, ctx->abi.tcs_rel_ids, 8, 5);
@@ -3066,10 +3021,9 @@ static void si_copy_tcs_inputs(struct lp_build_tgsi_context *bld_base)
        buffer_offset = LLVMGetParam(ctx->main_fn, ctx->param_tcs_offchip_offset);
 
        lds_vertex_stride = get_tcs_in_vertex_dw_stride(ctx);
-       lds_vertex_offset = LLVMBuildMul(ctx->ac.builder, invocation_id,
-                                        lds_vertex_stride, "");
        lds_base = get_tcs_in_current_patch_offset(ctx);
-       lds_base = LLVMBuildAdd(ctx->ac.builder, lds_base, lds_vertex_offset, "");
+       lds_base = ac_build_imad(&ctx->ac, invocation_id, lds_vertex_stride,
+                                lds_base);
 
        inputs = ctx->shader->key.mono.u.ff_tcs_inputs_to_copy;
        while (inputs) {
@@ -3210,7 +3164,7 @@ static void si_write_tess_factors(struct lp_build_tgsi_context *bld_base,
 
        /* Store the dynamic HS control word. */
        offset = 0;
-       if (ctx->screen->info.chip_class <= VI) {
+       if (ctx->screen->info.chip_class <= GFX8) {
                ac_build_buffer_store_dword(&ctx->ac, buffer,
                                            LLVMConstInt(ctx->i32, 0x80000000, 0),
                                            1, ctx->i32_0, tf_base,
@@ -3244,8 +3198,10 @@ static void si_write_tess_factors(struct lp_build_tgsi_context *bld_base,
                tf_outer_offset = get_tcs_tes_buffer_address(ctx, rel_patch_id, NULL,
                                        LLVMConstInt(ctx->i32, param_outer, 0));
 
-               outer_vec = ac_build_gather_values(&ctx->ac, outer,
-                                                  util_next_power_of_two(outer_comps));
+               unsigned outer_vec_size =
+                       ac_has_vec3_support(ctx->screen->info.chip_class, false) ?
+                               outer_comps : util_next_power_of_two(outer_comps);
+               outer_vec = ac_build_gather_values(&ctx->ac, outer, outer_vec_size);
 
                ac_build_buffer_store_dword(&ctx->ac, buf, outer_vec,
                                            outer_comps, tf_outer_offset,
@@ -3293,21 +3249,9 @@ si_insert_input_ptr(struct si_shader_context *ctx, LLVMValueRef ret,
                    unsigned param, unsigned return_index)
 {
        LLVMBuilderRef builder = ctx->ac.builder;
-       LLVMValueRef ptr, lo, hi;
-
-       if (HAVE_32BIT_POINTERS) {
-               ptr = LLVMGetParam(ctx->main_fn, param);
-               ptr = LLVMBuildPtrToInt(builder, ptr, ctx->i32, "");
-               return LLVMBuildInsertValue(builder, ret, ptr, return_index, "");
-       }
-
-       ptr = LLVMGetParam(ctx->main_fn, param);
-       ptr = LLVMBuildPtrToInt(builder, ptr, ctx->i64, "");
-       ptr = LLVMBuildBitCast(builder, ptr, ctx->v2i32, "");
-       lo = LLVMBuildExtractElement(builder, ptr, ctx->i32_0, "");
-       hi = LLVMBuildExtractElement(builder, ptr, ctx->i32_1, "");
-       ret = LLVMBuildInsertValue(builder, ret, lo, return_index, "");
-       return LLVMBuildInsertValue(builder, ret, hi, return_index + 1, "");
+       LLVMValueRef ptr = LLVMGetParam(ctx->main_fn, param);
+       ptr = LLVMBuildPtrToInt(builder, ptr, ctx->i32, "");
+       return LLVMBuildInsertValue(builder, ret, ptr, return_index, "");
 }
 
 /* This only writes the tessellation factor levels. */
@@ -3408,8 +3352,7 @@ static void si_set_ls_return_value_for_tcs(struct si_shader_context *ctx)
        LLVMValueRef ret = ctx->return_value;
 
        ret = si_insert_input_ptr(ctx, ret, 0, 0);
-       if (HAVE_32BIT_POINTERS)
-               ret = si_insert_input_ptr(ctx, ret, 1, 1);
+       ret = si_insert_input_ptr(ctx, ret, 1, 1);
        ret = si_insert_input_ret(ctx, ret, ctx->param_tcs_offchip_offset, 2);
        ret = si_insert_input_ret(ctx, ret, ctx->param_merged_wave_info, 3);
        ret = si_insert_input_ret(ctx, ret, ctx->param_tcs_factor_offset, 4);
@@ -3424,11 +3367,6 @@ static void si_set_ls_return_value_for_tcs(struct si_shader_context *ctx)
        ret = si_insert_input_ret(ctx, ret, ctx->param_vs_state_bits,
                                  8 + SI_SGPR_VS_STATE_BITS);
 
-#if !HAVE_32BIT_POINTERS
-       ret = si_insert_input_ptr(ctx, ret, ctx->param_vs_state_bits + 4,
-                                 8 + GFX9_SGPR_2ND_SAMPLERS_AND_IMAGES);
-#endif
-
        ret = si_insert_input_ret(ctx, ret, ctx->param_tcs_offchip_layout,
                                  8 + GFX9_SGPR_TCS_OFFCHIP_LAYOUT);
        ret = si_insert_input_ret(ctx, ret, ctx->param_tcs_out_lds_offsets,
@@ -3452,8 +3390,7 @@ static void si_set_es_return_value_for_gs(struct si_shader_context *ctx)
        LLVMValueRef ret = ctx->return_value;
 
        ret = si_insert_input_ptr(ctx, ret, 0, 0);
-       if (HAVE_32BIT_POINTERS)
-               ret = si_insert_input_ptr(ctx, ret, 1, 1);
+       ret = si_insert_input_ptr(ctx, ret, 1, 1);
        ret = si_insert_input_ret(ctx, ret, ctx->param_gs2vs_offset, 2);
        ret = si_insert_input_ret(ctx, ret, ctx->param_merged_wave_info, 3);
        ret = si_insert_input_ret(ctx, ret, ctx->param_merged_scratch_offset, 5);
@@ -3464,11 +3401,6 @@ static void si_set_es_return_value_for_gs(struct si_shader_context *ctx)
                                  ctx->param_bindless_samplers_and_images,
                                  8 + SI_SGPR_BINDLESS_SAMPLERS_AND_IMAGES);
 
-#if !HAVE_32BIT_POINTERS
-       ret = si_insert_input_ptr(ctx, ret, ctx->param_vs_state_bits + 4,
-                                 8 + GFX9_SGPR_2ND_SAMPLERS_AND_IMAGES);
-#endif
-
        unsigned vgpr;
        if (ctx->type == PIPE_SHADER_VERTEX)
                vgpr = 8 + GFX9_VSGS_NUM_USER_SGPR;
@@ -3646,42 +3578,6 @@ static void si_llvm_emit_vs_epilogue(struct ac_shader_abi *abi,
 
        outputs = MALLOC((info->num_outputs + 1) * sizeof(outputs[0]));
 
-       /* Vertex color clamping.
-        *
-        * This uses a state constant loaded in a user data SGPR and
-        * an IF statement is added that clamps all colors if the constant
-        * is true.
-        */
-       struct lp_build_if_state if_ctx;
-       LLVMValueRef cond = NULL;
-       LLVMValueRef addr, val;
-
-       for (i = 0; i < info->num_outputs; i++) {
-               if (info->output_semantic_name[i] != TGSI_SEMANTIC_COLOR &&
-                   info->output_semantic_name[i] != TGSI_SEMANTIC_BCOLOR)
-                       continue;
-
-               /* We've found a color. */
-               if (!cond) {
-                       /* The state is in the first bit of the user SGPR. */
-                       cond = LLVMGetParam(ctx->main_fn,
-                                           ctx->param_vs_state_bits);
-                       cond = LLVMBuildTrunc(ctx->ac.builder, cond,
-                                             ctx->i1, "");
-                       lp_build_if(&if_ctx, &ctx->gallivm, cond);
-               }
-
-               for (j = 0; j < 4; j++) {
-                       addr = addrs[4 * i + j];
-                       val = LLVMBuildLoad(ctx->ac.builder, addr, "");
-                       val = ac_build_clamp(&ctx->ac, val);
-                       LLVMBuildStore(ctx->ac.builder, val, addr);
-               }
-       }
-
-       if (cond)
-               lp_build_endif(&if_ctx);
-
        for (i = 0; i < info->num_outputs; i++) {
                outputs[i].semantic_name = info->output_semantic_name[i];
                outputs[i].semantic_index = info->output_semantic_index[i];
@@ -3716,6 +3612,33 @@ static void si_llvm_emit_vs_epilogue(struct ac_shader_abi *abi,
        FREE(outputs);
 }
 
+static void si_llvm_emit_prim_discard_cs_epilogue(struct ac_shader_abi *abi,
+                                                 unsigned max_outputs,
+                                                 LLVMValueRef *addrs)
+{
+       struct si_shader_context *ctx = si_shader_context_from_abi(abi);
+       struct tgsi_shader_info *info = &ctx->shader->selector->info;
+       LLVMValueRef pos[4] = {};
+
+       assert(info->num_outputs <= max_outputs);
+
+       for (unsigned i = 0; i < info->num_outputs; i++) {
+               if (info->output_semantic_name[i] != TGSI_SEMANTIC_POSITION)
+                       continue;
+
+               for (unsigned chan = 0; chan < 4; chan++)
+                       pos[chan] = LLVMBuildLoad(ctx->ac.builder, addrs[4 * i + chan], "");
+               break;
+       }
+       assert(pos[0] != NULL);
+
+       /* Return the position output. */
+       LLVMValueRef ret = ctx->return_value;
+       for (unsigned chan = 0; chan < 4; chan++)
+               ret = LLVMBuildInsertValue(ctx->ac.builder, ret, pos[chan], chan, "");
+       ctx->return_value = ret;
+}
+
 static void si_tgsi_emit_epilogue(struct lp_build_tgsi_context *bld_base)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
@@ -3871,7 +3794,7 @@ static void si_llvm_return_fs_outputs(struct ac_shader_abi *abi,
                                                   addrs[4 * i + 0], "");
                        break;
                default:
-                       fprintf(stderr, "Warning: SI unhandled fs output type:%d\n",
+                       fprintf(stderr, "Warning: GFX6 unhandled fs output type:%d\n",
                                semantic_name);
                }
        }
@@ -3977,31 +3900,6 @@ static void si_llvm_emit_ddxy(
        emit_data->output[emit_data->chan] = val;
 }
 
-/*
- * this takes an I,J coordinate pair,
- * and works out the X and Y derivatives.
- * it returns DDX(I), DDX(J), DDY(I), DDY(J).
- */
-static LLVMValueRef si_llvm_emit_ddxy_interp(
-       struct lp_build_tgsi_context *bld_base,
-       LLVMValueRef interp_ij)
-{
-       struct si_shader_context *ctx = si_shader_context(bld_base);
-       LLVMValueRef result[4], a;
-       unsigned i;
-
-       for (i = 0; i < 2; i++) {
-               a = LLVMBuildExtractElement(ctx->ac.builder, interp_ij,
-                                           LLVMConstInt(ctx->i32, i, 0), "");
-               result[i] = ac_build_ddxy(&ctx->ac, AC_TID_MASK_TOP_LEFT, 1,
-                                         ac_to_integer(&ctx->ac, a)); /* DDX */
-               result[2+i] = ac_build_ddxy(&ctx->ac, AC_TID_MASK_TOP_LEFT, 2,
-                                           ac_to_integer(&ctx->ac, a)); /* DDY */
-       }
-
-       return ac_build_gather_values(&ctx->ac, result, 4);
-}
-
 static void build_interp_intrinsic(const struct lp_build_tgsi_action *action,
                                struct lp_build_tgsi_context *bld_base,
                                struct lp_build_emit_data *emit_data)
@@ -4115,7 +4013,7 @@ static void build_interp_intrinsic(const struct lp_build_tgsi_action *action,
        if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_OFFSET ||
            inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE) {
                LLVMValueRef ij_out[2];
-               LLVMValueRef ddxy_out = si_llvm_emit_ddxy_interp(bld_base, interp_param);
+               LLVMValueRef ddxy_out = ac_build_ddxy_interp(&ctx->ac, interp_param);
 
                /*
                 * take the I then J parameters, and the DDX/Y for it, and
@@ -4134,17 +4032,12 @@ static void build_interp_intrinsic(const struct lp_build_tgsi_action *action,
                                                                      ddxy_out, iy_ll, "");
                        LLVMValueRef interp_el = LLVMBuildExtractElement(ctx->ac.builder,
                                                                         interp_param, ix_ll, "");
-                       LLVMValueRef temp1, temp2;
+                       LLVMValueRef temp;
 
                        interp_el = ac_to_float(&ctx->ac, interp_el);
 
-                       temp1 = LLVMBuildFMul(ctx->ac.builder, ddx_el, offset_x, "");
-
-                       temp1 = LLVMBuildFAdd(ctx->ac.builder, temp1, interp_el, "");
-
-                       temp2 = LLVMBuildFMul(ctx->ac.builder, ddy_el, offset_y, "");
-
-                       ij_out[i] = LLVMBuildFAdd(ctx->ac.builder, temp2, temp1, "");
+                       temp = ac_build_fmad(&ctx->ac, ddx_el, offset_x, interp_el);
+                       ij_out[i] = ac_build_fmad(&ctx->ac, ddy_el, offset_y, temp);
                }
                interp_param = ac_build_gather_values(&ctx->ac, ij_out, 2);
        }
@@ -4347,9 +4240,12 @@ static void si_llvm_emit_vertex(struct ac_shader_abi *abi,
        gs_next_vertex = LLVMBuildAdd(ctx->ac.builder, gs_next_vertex, ctx->i32_1, "");
        LLVMBuildStore(ctx->ac.builder, gs_next_vertex, ctx->gs_next_vertex[stream]);
 
-       /* Signal vertex emission */
-       ac_build_sendmsg(&ctx->ac, AC_SENDMSG_GS_OP_EMIT | AC_SENDMSG_GS | (stream << 8),
-                        si_get_gs_wave_id(ctx));
+       /* Signal vertex emission if vertex data was written. */
+       if (offset) {
+               ac_build_sendmsg(&ctx->ac, AC_SENDMSG_GS_OP_EMIT | AC_SENDMSG_GS | (stream << 8),
+                                si_get_gs_wave_id(ctx));
+       }
+
        if (!use_kill)
                lp_build_endif(&if_state);
 }
@@ -4394,11 +4290,11 @@ static void si_llvm_emit_barrier(const struct lp_build_tgsi_action *action,
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
 
-       /* SI only (thanks to a hw bug workaround):
+       /* GFX6 only (thanks to a hw bug workaround):
         * The real barrier instruction isn’t needed, because an entire patch
         * always fits into a single wave.
         */
-       if (ctx->screen->info.chip_class == SI &&
+       if (ctx->screen->info.chip_class == GFX6 &&
            ctx->type == PIPE_SHADER_TESS_CTRL) {
                ac_build_waitcnt(&ctx->ac, LGKM_CNT & VM_CNT);
                return;
@@ -4407,11 +4303,11 @@ static void si_llvm_emit_barrier(const struct lp_build_tgsi_action *action,
        ac_build_s_barrier(&ctx->ac);
 }
 
-static void si_create_function(struct si_shader_context *ctx,
-                              const char *name,
-                              LLVMTypeRef *returns, unsigned num_returns,
-                              struct si_function_info *fninfo,
-                              unsigned max_workgroup_size)
+void si_create_function(struct si_shader_context *ctx,
+                       const char *name,
+                       LLVMTypeRef *returns, unsigned num_returns,
+                       struct si_function_info *fninfo,
+                       unsigned max_workgroup_size)
 {
        int i;
 
@@ -4450,11 +4346,8 @@ static void si_create_function(struct si_shader_context *ctx,
                                                     ctx->screen->info.address32_hi);
        }
 
-       if (max_workgroup_size) {
-               ac_llvm_add_target_dep_function_attr(ctx->main_fn,
-                                                    "amdgpu-max-work-group-size",
-                                                    max_workgroup_size);
-       }
+       ac_llvm_set_workgroup_size(ctx->main_fn, max_workgroup_size);
+
        LLVMAddTargetDependentFunctionAttr(ctx->main_fn,
                                           "no-signed-zeros-fp-math",
                                           "true");
@@ -4506,7 +4399,7 @@ static unsigned si_get_max_workgroup_size(const struct si_shader *shader)
        case PIPE_SHADER_TESS_CTRL:
                /* Return this so that LLVM doesn't remove s_barrier
                 * instructions on chips where we use s_barrier. */
-               return shader->selector->screen->info.chip_class >= CIK ? 128 : 64;
+               return shader->selector->screen->info.chip_class >= GFX7 ? 128 : 64;
 
        case PIPE_SHADER_GEOMETRY:
                return shader->selector->screen->info.chip_class >= GFX9 ? 128 : 64;
@@ -4616,6 +4509,30 @@ static void declare_vs_input_vgprs(struct si_shader_context *ctx,
        }
 }
 
+static void declare_vs_blit_inputs(struct si_shader_context *ctx,
+                                  struct si_function_info *fninfo,
+                                  unsigned vs_blit_property)
+{
+       ctx->param_vs_blit_inputs = fninfo->num_params;
+       add_arg(fninfo, ARG_SGPR, ctx->i32); /* i16 x1, y1 */
+       add_arg(fninfo, ARG_SGPR, ctx->i32); /* i16 x2, y2 */
+       add_arg(fninfo, ARG_SGPR, ctx->f32); /* depth */
+
+       if (vs_blit_property == SI_VS_BLIT_SGPRS_POS_COLOR) {
+               add_arg(fninfo, ARG_SGPR, ctx->f32); /* color0 */
+               add_arg(fninfo, ARG_SGPR, ctx->f32); /* color1 */
+               add_arg(fninfo, ARG_SGPR, ctx->f32); /* color2 */
+               add_arg(fninfo, ARG_SGPR, ctx->f32); /* color3 */
+       } else if (vs_blit_property == SI_VS_BLIT_SGPRS_POS_TEXCOORD) {
+               add_arg(fninfo, ARG_SGPR, ctx->f32); /* texcoord.x1 */
+               add_arg(fninfo, ARG_SGPR, ctx->f32); /* texcoord.y1 */
+               add_arg(fninfo, ARG_SGPR, ctx->f32); /* texcoord.x2 */
+               add_arg(fninfo, ARG_SGPR, ctx->f32); /* texcoord.y2 */
+               add_arg(fninfo, ARG_SGPR, ctx->f32); /* texcoord.z */
+               add_arg(fninfo, ARG_SGPR, ctx->f32); /* texcoord.w */
+       }
+}
+
 static void declare_tes_input_vgprs(struct si_shader_context *ctx,
                                    struct si_function_info *fninfo)
 {
@@ -4660,24 +4577,7 @@ static void create_function(struct si_shader_context *ctx)
                declare_global_desc_pointers(ctx, &fninfo);
 
                if (vs_blit_property) {
-                       ctx->param_vs_blit_inputs = fninfo.num_params;
-                       add_arg(&fninfo, ARG_SGPR, ctx->i32); /* i16 x1, y1 */
-                       add_arg(&fninfo, ARG_SGPR, ctx->i32); /* i16 x2, y2 */
-                       add_arg(&fninfo, ARG_SGPR, ctx->f32); /* depth */
-
-                       if (vs_blit_property == SI_VS_BLIT_SGPRS_POS_COLOR) {
-                               add_arg(&fninfo, ARG_SGPR, ctx->f32); /* color0 */
-                               add_arg(&fninfo, ARG_SGPR, ctx->f32); /* color1 */
-                               add_arg(&fninfo, ARG_SGPR, ctx->f32); /* color2 */
-                               add_arg(&fninfo, ARG_SGPR, ctx->f32); /* color3 */
-                       } else if (vs_blit_property == SI_VS_BLIT_SGPRS_POS_TEXCOORD) {
-                               add_arg(&fninfo, ARG_SGPR, ctx->f32); /* texcoord.x1 */
-                               add_arg(&fninfo, ARG_SGPR, ctx->f32); /* texcoord.y1 */
-                               add_arg(&fninfo, ARG_SGPR, ctx->f32); /* texcoord.x2 */
-                               add_arg(&fninfo, ARG_SGPR, ctx->f32); /* texcoord.y2 */
-                               add_arg(&fninfo, ARG_SGPR, ctx->f32); /* texcoord.z */
-                               add_arg(&fninfo, ARG_SGPR, ctx->f32); /* texcoord.w */
-                       }
+                       declare_vs_blit_inputs(ctx, &fninfo, vs_blit_property);
 
                        /* VGPRs */
                        declare_vs_input_vgprs(ctx, &fninfo, &num_prolog_vgprs);
@@ -4706,9 +4606,15 @@ static void create_function(struct si_shader_context *ctx)
 
                /* VGPRs */
                declare_vs_input_vgprs(ctx, &fninfo, &num_prolog_vgprs);
+
+               /* Return values */
+               if (shader->key.opt.vs_as_prim_discard_cs) {
+                       for (i = 0; i < 4; i++)
+                               returns[num_returns++] = ctx->f32; /* VGPRs */
+               }
                break;
 
-       case PIPE_SHADER_TESS_CTRL: /* SI-CI-VI */
+       case PIPE_SHADER_TESS_CTRL: /* GFX6-GFX8 */
                declare_global_desc_pointers(ctx, &fninfo);
                declare_per_stage_desc_pointers(ctx, &fninfo, true);
                ctx->param_tcs_offchip_layout = add_arg(&fninfo, ARG_SGPR, ctx->i32);
@@ -4734,13 +4640,8 @@ static void create_function(struct si_shader_context *ctx)
        case SI_SHADER_MERGED_VERTEX_TESSCTRL:
                /* Merged stages have 8 system SGPRs at the beginning. */
                /* SPI_SHADER_USER_DATA_ADDR_LO/HI_HS */
-               if (HAVE_32BIT_POINTERS) {
-                       declare_per_stage_desc_pointers(ctx, &fninfo,
-                                                       ctx->type == PIPE_SHADER_TESS_CTRL);
-               } else {
-                       declare_const_and_shader_buffers(ctx, &fninfo,
-                                                        ctx->type == PIPE_SHADER_TESS_CTRL);
-               }
+               declare_per_stage_desc_pointers(ctx, &fninfo,
+                                               ctx->type == PIPE_SHADER_TESS_CTRL);
                ctx->param_tcs_offchip_offset = add_arg(&fninfo, ARG_SGPR, ctx->i32);
                ctx->param_merged_wave_info = add_arg(&fninfo, ARG_SGPR, ctx->i32);
                ctx->param_tcs_factor_offset = add_arg(&fninfo, ARG_SGPR, ctx->i32);
@@ -4753,15 +4654,9 @@ static void create_function(struct si_shader_context *ctx)
                                                ctx->type == PIPE_SHADER_VERTEX);
                declare_vs_specific_input_sgprs(ctx, &fninfo);
 
-               if (!HAVE_32BIT_POINTERS) {
-                       declare_samplers_and_images(ctx, &fninfo,
-                                                   ctx->type == PIPE_SHADER_TESS_CTRL);
-               }
                ctx->param_tcs_offchip_layout = add_arg(&fninfo, ARG_SGPR, ctx->i32);
                ctx->param_tcs_out_lds_offsets = add_arg(&fninfo, ARG_SGPR, ctx->i32);
                ctx->param_tcs_out_lds_layout = add_arg(&fninfo, ARG_SGPR, ctx->i32);
-               if (!HAVE_32BIT_POINTERS) /* Align to 2 dwords. */
-                       add_arg(&fninfo, ARG_SGPR, ctx->i32); /* unused */
                ctx->param_vertex_buffers = add_arg(&fninfo, ARG_SGPR,
                        ac_array_in_const32_addr_space(ctx->v4i32));
 
@@ -4795,13 +4690,8 @@ static void create_function(struct si_shader_context *ctx)
        case SI_SHADER_MERGED_VERTEX_OR_TESSEVAL_GEOMETRY:
                /* Merged stages have 8 system SGPRs at the beginning. */
                /* SPI_SHADER_USER_DATA_ADDR_LO/HI_GS */
-               if (HAVE_32BIT_POINTERS) {
-                       declare_per_stage_desc_pointers(ctx, &fninfo,
-                                                       ctx->type == PIPE_SHADER_GEOMETRY);
-               } else {
-                       declare_const_and_shader_buffers(ctx, &fninfo,
-                                                        ctx->type == PIPE_SHADER_GEOMETRY);
-               }
+               declare_per_stage_desc_pointers(ctx, &fninfo,
+                                               ctx->type == PIPE_SHADER_GEOMETRY);
                ctx->param_gs2vs_offset = add_arg(&fninfo, ARG_SGPR, ctx->i32);
                ctx->param_merged_wave_info = add_arg(&fninfo, ARG_SGPR, ctx->i32);
                ctx->param_tcs_offchip_offset = add_arg(&fninfo, ARG_SGPR, ctx->i32);
@@ -4820,14 +4710,8 @@ static void create_function(struct si_shader_context *ctx)
                        ctx->param_tcs_offchip_layout = add_arg(&fninfo, ARG_SGPR, ctx->i32);
                        ctx->param_tes_offchip_addr = add_arg(&fninfo, ARG_SGPR, ctx->i32);
                        /* Declare as many input SGPRs as the VS has. */
-                       if (!HAVE_32BIT_POINTERS)
-                               add_arg(&fninfo, ARG_SGPR, ctx->i32); /* unused */
                }
 
-               if (!HAVE_32BIT_POINTERS) {
-                       declare_samplers_and_images(ctx, &fninfo,
-                                                   ctx->type == PIPE_SHADER_GEOMETRY);
-               }
                if (ctx->type == PIPE_SHADER_VERTEX) {
                        ctx->param_vertex_buffers = add_arg(&fninfo, ARG_SGPR,
                                ac_array_in_const32_addr_space(ctx->v4i32));
@@ -4977,6 +4861,13 @@ static void create_function(struct si_shader_context *ctx)
                    shader->selector->info.properties[TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH] == 0)
                        ctx->param_block_size = add_arg(&fninfo, ARG_SGPR, v3i32);
 
+               unsigned cs_user_data_dwords =
+                       shader->selector->info.properties[TGSI_PROPERTY_CS_USER_DATA_DWORDS];
+               if (cs_user_data_dwords) {
+                       ctx->param_cs_user_data = add_arg(&fninfo, ARG_SGPR,
+                                                         LLVMVectorType(ctx->i32, cs_user_data_dwords));
+               }
+
                for (i = 0; i < 3; i++) {
                        ctx->abi.workgroup_ids[i] = NULL;
                        if (shader->selector->info.uses_block_id[i])
@@ -5038,7 +4929,7 @@ static void preload_ring_buffers(struct si_shader_context *ctx)
        LLVMValueRef buf_ptr = LLVMGetParam(ctx->main_fn,
                                            ctx->param_rw_buffers);
 
-       if (ctx->screen->info.chip_class <= VI &&
+       if (ctx->screen->info.chip_class <= GFX8 &&
            (ctx->shader->key.as_es || ctx->type == PIPE_SHADER_GEOMETRY)) {
                unsigned ring =
                        ctx->type == PIPE_SHADER_GEOMETRY ? SI_GS_RING_ESGS
@@ -5084,7 +4975,7 @@ static void preload_ring_buffers(struct si_shader_context *ctx)
 
                        stride = 4 * num_components * sel->gs_max_out_vertices;
 
-                       /* Limit on the stride field for <= CIK. */
+                       /* Limit on the stride field for <= GFX7. */
                        assert(stride < (1 << 14));
 
                        num_records = 64;
@@ -5156,259 +5047,183 @@ static void si_llvm_emit_polygon_stipple(struct si_shader_context *ctx,
        ac_build_kill_if_false(&ctx->ac, bit);
 }
 
-void si_shader_binary_read_config(struct ac_shader_binary *binary,
-                                 struct si_shader_config *conf,
-                                 unsigned symbol_offset)
-{
-       unsigned i;
-       const unsigned char *config =
-               ac_shader_binary_config_start(binary, symbol_offset);
-       bool really_needs_scratch = false;
+/* For the UMR disassembler. */
+#define DEBUGGER_END_OF_CODE_MARKER    0xbf9f0000 /* invalid instruction */
+#define DEBUGGER_NUM_MARKERS           5
 
-       /* LLVM adds SGPR spills to the scratch size.
-        * Find out if we really need the scratch buffer.
-        */
-       for (i = 0; i < binary->reloc_count; i++) {
-               const struct ac_shader_reloc *reloc = &binary->relocs[i];
+static bool si_shader_binary_open(struct si_screen *screen,
+                                 struct si_shader *shader,
+                                 struct ac_rtld_binary *rtld)
+{
+       const char *part_elfs[5];
+       size_t part_sizes[5];
+       unsigned num_parts = 0;
 
-               if (!strcmp(scratch_rsrc_dword0_symbol, reloc->name) ||
-                   !strcmp(scratch_rsrc_dword1_symbol, reloc->name)) {
-                       really_needs_scratch = true;
-                       break;
-               }
+#define add_part(shader_or_part) \
+       if (shader_or_part) { \
+               part_elfs[num_parts] = (shader_or_part)->binary.elf_buffer; \
+               part_sizes[num_parts] = (shader_or_part)->binary.elf_size; \
+               num_parts++; \
        }
 
-       /* XXX: We may be able to emit some of these values directly rather than
-        * extracting fields to be emitted later.
-        */
+       add_part(shader->prolog);
+       add_part(shader->previous_stage);
+       add_part(shader->prolog2);
+       add_part(shader);
+       add_part(shader->epilog);
 
-       for (i = 0; i < binary->config_size_per_symbol; i+= 8) {
-               unsigned reg = util_le32_to_cpu(*(uint32_t*)(config + i));
-               unsigned value = util_le32_to_cpu(*(uint32_t*)(config + i + 4));
-               switch (reg) {
-               case R_00B028_SPI_SHADER_PGM_RSRC1_PS:
-               case R_00B128_SPI_SHADER_PGM_RSRC1_VS:
-               case R_00B228_SPI_SHADER_PGM_RSRC1_GS:
-               case R_00B428_SPI_SHADER_PGM_RSRC1_HS:
-               case R_00B848_COMPUTE_PGM_RSRC1:
-                       conf->num_sgprs = MAX2(conf->num_sgprs, (G_00B028_SGPRS(value) + 1) * 8);
-                       conf->num_vgprs = MAX2(conf->num_vgprs, (G_00B028_VGPRS(value) + 1) * 4);
-                       conf->float_mode =  G_00B028_FLOAT_MODE(value);
-                       conf->rsrc1 = value;
-                       break;
-               case R_00B02C_SPI_SHADER_PGM_RSRC2_PS:
-                       conf->lds_size = MAX2(conf->lds_size, G_00B02C_EXTRA_LDS_SIZE(value));
-                       break;
-               case R_00B84C_COMPUTE_PGM_RSRC2:
-                       conf->lds_size = MAX2(conf->lds_size, G_00B84C_LDS_SIZE(value));
-                       conf->rsrc2 = value;
-                       break;
-               case R_0286CC_SPI_PS_INPUT_ENA:
-                       conf->spi_ps_input_ena = value;
-                       break;
-               case R_0286D0_SPI_PS_INPUT_ADDR:
-                       conf->spi_ps_input_addr = value;
-                       break;
-               case R_0286E8_SPI_TMPRING_SIZE:
-               case R_00B860_COMPUTE_TMPRING_SIZE:
-                       /* WAVESIZE is in units of 256 dwords. */
-                       if (really_needs_scratch)
-                               conf->scratch_bytes_per_wave =
-                                       G_00B860_WAVESIZE(value) * 256 * 4;
-                       break;
-               case 0x4: /* SPILLED_SGPRS */
-                       conf->spilled_sgprs = value;
-                       break;
-               case 0x8: /* SPILLED_VGPRS */
-                       conf->spilled_vgprs = value;
-                       break;
-               default:
-                       {
-                               static bool printed;
+#undef add_part
 
-                               if (!printed) {
-                                       fprintf(stderr, "Warning: LLVM emitted unknown "
-                                               "config register: 0x%x\n", reg);
-                                       printed = true;
-                               }
-                       }
-                       break;
-               }
+       bool ok = ac_rtld_open(rtld, (struct ac_rtld_open_info){
+                       .info = &screen->info,
+                       .num_parts = num_parts,
+                       .elf_ptrs = part_elfs,
+                       .elf_sizes = part_sizes });
+
+       if (rtld->lds_size > 0) {
+               unsigned alloc_granularity = screen->info.chip_class >= GFX7 ? 512 : 256;
+               shader->config.lds_size =
+                       align(rtld->lds_size, alloc_granularity) / alloc_granularity;
        }
 
-       if (!conf->spi_ps_input_addr)
-               conf->spi_ps_input_addr = conf->spi_ps_input_ena;
+       return ok;
 }
 
-void si_shader_apply_scratch_relocs(struct si_shader *shader,
-                                   uint64_t scratch_va)
+static unsigned si_get_shader_binary_size(struct si_screen *screen, struct si_shader *shader)
 {
-       unsigned i;
-       uint32_t scratch_rsrc_dword0 = scratch_va;
-       uint32_t scratch_rsrc_dword1 =
-               S_008F04_BASE_ADDRESS_HI(scratch_va >> 32);
-
-       /* Enable scratch coalescing. */
-       scratch_rsrc_dword1 |= S_008F04_SWIZZLE_ENABLE(1);
-
-       for (i = 0 ; i < shader->binary.reloc_count; i++) {
-               const struct ac_shader_reloc *reloc =
-                                       &shader->binary.relocs[i];
-               if (!strcmp(scratch_rsrc_dword0_symbol, reloc->name)) {
-                       util_memcpy_cpu_to_le32(shader->binary.code + reloc->offset,
-                       &scratch_rsrc_dword0, 4);
-               } else if (!strcmp(scratch_rsrc_dword1_symbol, reloc->name)) {
-                       util_memcpy_cpu_to_le32(shader->binary.code + reloc->offset,
-                       &scratch_rsrc_dword1, 4);
+       struct ac_rtld_binary rtld;
+       si_shader_binary_open(screen, shader, &rtld);
+       return rtld.rx_size;
+}
+
+
+static bool si_get_external_symbol(void *data, const char *name, uint64_t *value)
+{
+       uint64_t *scratch_va = data;
+
+       if (!strcmp(scratch_rsrc_dword0_symbol, name)) {
+               *value = (uint32_t)*scratch_va;
+               return true;
+       }
+       if (!strcmp(scratch_rsrc_dword1_symbol, name)) {
+               /* Enable scratch coalescing. */
+               *value = S_008F04_BASE_ADDRESS_HI(*scratch_va >> 32) |
+                        S_008F04_SWIZZLE_ENABLE(1);
+               if (HAVE_LLVM < 0x0800) {
+                       /* Old LLVM created an R_ABS32_HI relocation for
+                        * this symbol. */
+                       *value <<= 32;
                }
+               return true;
        }
+
+       return false;
 }
 
-/* For the UMR disassembler. */
-#define DEBUGGER_END_OF_CODE_MARKER    0xbf9f0000 /* invalid instruction */
-#define DEBUGGER_NUM_MARKERS           5
+bool si_shader_binary_upload(struct si_screen *sscreen, struct si_shader *shader,
+                            uint64_t scratch_va)
+{
+       struct ac_rtld_binary binary;
+       if (!si_shader_binary_open(sscreen, shader, &binary))
+               return false;
 
-static unsigned si_get_shader_binary_size(const struct si_shader *shader)
-{
-       unsigned size = shader->binary.code_size;
-
-       if (shader->prolog)
-               size += shader->prolog->binary.code_size;
-       if (shader->previous_stage)
-               size += shader->previous_stage->binary.code_size;
-       if (shader->prolog2)
-               size += shader->prolog2->binary.code_size;
-       if (shader->epilog)
-               size += shader->epilog->binary.code_size;
-       return size + DEBUGGER_NUM_MARKERS * 4;
-}
-
-int si_shader_binary_upload(struct si_screen *sscreen, struct si_shader *shader)
-{
-       const struct ac_shader_binary *prolog =
-               shader->prolog ? &shader->prolog->binary : NULL;
-       const struct ac_shader_binary *previous_stage =
-               shader->previous_stage ? &shader->previous_stage->binary : NULL;
-       const struct ac_shader_binary *prolog2 =
-               shader->prolog2 ? &shader->prolog2->binary : NULL;
-       const struct ac_shader_binary *epilog =
-               shader->epilog ? &shader->epilog->binary : NULL;
-       const struct ac_shader_binary *mainb = &shader->binary;
-       unsigned bo_size = si_get_shader_binary_size(shader) +
-                          (!epilog ? mainb->rodata_size : 0);
-       unsigned char *ptr;
-
-       assert(!prolog || !prolog->rodata_size);
-       assert(!previous_stage || !previous_stage->rodata_size);
-       assert(!prolog2 || !prolog2->rodata_size);
-       assert((!prolog && !previous_stage && !prolog2 && !epilog) ||
-              !mainb->rodata_size);
-       assert(!epilog || !epilog->rodata_size);
-
-       r600_resource_reference(&shader->bo, NULL);
+       si_resource_reference(&shader->bo, NULL);
        shader->bo = si_aligned_buffer_create(&sscreen->b,
                                              sscreen->cpdma_prefetch_writes_memory ?
                                                0 : SI_RESOURCE_FLAG_READ_ONLY,
                                               PIPE_USAGE_IMMUTABLE,
-                                              align(bo_size, SI_CPDMA_ALIGNMENT),
+                                              align(binary.rx_size, SI_CPDMA_ALIGNMENT),
                                               256);
        if (!shader->bo)
-               return -ENOMEM;
+               return false;
 
        /* Upload. */
-       ptr = sscreen->ws->buffer_map(shader->bo->buf, NULL,
+       struct ac_rtld_upload_info u = {};
+       u.binary = &binary;
+       u.get_external_symbol = si_get_external_symbol;
+       u.cb_data = &scratch_va;
+       u.rx_va = shader->bo->gpu_address;
+       u.rx_ptr = sscreen->ws->buffer_map(shader->bo->buf, NULL,
                                        PIPE_TRANSFER_READ_WRITE |
-                                       PIPE_TRANSFER_UNSYNCHRONIZED);
-
-       /* Don't use util_memcpy_cpu_to_le32. LLVM binaries are
-        * endian-independent. */
-       if (prolog) {
-               memcpy(ptr, prolog->code, prolog->code_size);
-               ptr += prolog->code_size;
-       }
-       if (previous_stage) {
-               memcpy(ptr, previous_stage->code, previous_stage->code_size);
-               ptr += previous_stage->code_size;
-       }
-       if (prolog2) {
-               memcpy(ptr, prolog2->code, prolog2->code_size);
-               ptr += prolog2->code_size;
-       }
-
-       memcpy(ptr, mainb->code, mainb->code_size);
-       ptr += mainb->code_size;
-
-       if (epilog) {
-               memcpy(ptr, epilog->code, epilog->code_size);
-               ptr += epilog->code_size;
-       } else if (mainb->rodata_size > 0) {
-               memcpy(ptr, mainb->rodata, mainb->rodata_size);
-               ptr += mainb->rodata_size;
-       }
+                                       PIPE_TRANSFER_UNSYNCHRONIZED |
+                                       RADEON_TRANSFER_TEMPORARY);
+       if (!u.rx_ptr)
+               return false;
 
-       /* Add end-of-code markers for the UMR disassembler. */
-       uint32_t *ptr32 = (uint32_t*)ptr;
-       for (unsigned i = 0; i < DEBUGGER_NUM_MARKERS; i++)
-               ptr32[i] = DEBUGGER_END_OF_CODE_MARKER;
+       bool ok = ac_rtld_upload(&u);
 
        sscreen->ws->buffer_unmap(shader->bo->buf);
-       return 0;
+       ac_rtld_close(&binary);
+
+       return ok;
 }
 
-static void si_shader_dump_disassembly(const struct ac_shader_binary *binary,
+static void si_shader_dump_disassembly(struct si_screen *screen,
+                                      const struct si_shader_binary *binary,
                                       struct pipe_debug_callback *debug,
                                       const char *name, FILE *file)
 {
-       char *line, *p;
-       unsigned i, count;
+       struct ac_rtld_binary rtld_binary;
 
-       if (binary->disasm_string) {
-               fprintf(file, "Shader %s disassembly:\n", name);
-               fprintf(file, "%s", binary->disasm_string);
+       if (!ac_rtld_open(&rtld_binary, (struct ac_rtld_open_info){
+                       .info = &screen->info,
+                       .num_parts = 1,
+                       .elf_ptrs = &binary->elf_buffer,
+                       .elf_sizes = &binary->elf_size }))
+               return;
 
-               if (debug && debug->debug_message) {
-                       /* Very long debug messages are cut off, so send the
-                        * disassembly one line at a time. This causes more
-                        * overhead, but on the plus side it simplifies
-                        * parsing of resulting logs.
-                        */
-                       pipe_debug_message(debug, SHADER_INFO,
-                                          "Shader Disassembly Begin");
+       const char *disasm;
+       size_t nbytes;
 
-                       line = binary->disasm_string;
-                       while (*line) {
-                               p = util_strchrnul(line, '\n');
-                               count = p - line;
+       if (!ac_rtld_get_section_by_name(&rtld_binary, ".AMDGPU.disasm", &disasm, &nbytes))
+               goto out;
 
-                               if (count) {
-                                       pipe_debug_message(debug, SHADER_INFO,
-                                                          "%.*s", count, line);
-                               }
+       fprintf(file, "Shader %s disassembly:\n", name);
+       if (nbytes > INT_MAX) {
+               fprintf(file, "too long\n");
+               goto out;
+       }
 
-                               if (!*p)
-                                       break;
-                               line = p + 1;
+       fprintf(file, "%*s", (int)nbytes, disasm);
+
+       if (debug && debug->debug_message) {
+               /* Very long debug messages are cut off, so send the
+                * disassembly one line at a time. This causes more
+                * overhead, but on the plus side it simplifies
+                * parsing of resulting logs.
+                */
+               pipe_debug_message(debug, SHADER_INFO,
+                                  "Shader Disassembly Begin");
+
+               uint64_t line = 0;
+               while (line < nbytes) {
+                       int count = nbytes - line;
+                       const char *nl = memchr(disasm + line, '\n', nbytes - line);
+                       if (nl)
+                               count = nl - disasm;
+
+                       if (count) {
+                               pipe_debug_message(debug, SHADER_INFO,
+                                                  "%.*s", count, disasm + line);
                        }
 
-                       pipe_debug_message(debug, SHADER_INFO,
-                                          "Shader Disassembly End");
-               }
-       } else {
-               fprintf(file, "Shader %s binary:\n", name);
-               for (i = 0; i < binary->code_size; i += 4) {
-                       fprintf(file, "@0x%x: %02x%02x%02x%02x\n", i,
-                               binary->code[i + 3], binary->code[i + 2],
-                               binary->code[i + 1], binary->code[i]);
+                       line += count + 1;
                }
+
+               pipe_debug_message(debug, SHADER_INFO,
+                                  "Shader Disassembly End");
        }
+
+out:
+       ac_rtld_close(&rtld_binary);
 }
 
 static void si_calculate_max_simd_waves(struct si_shader *shader)
 {
        struct si_screen *sscreen = shader->selector->screen;
-       struct si_shader_config *conf = &shader->config;
+       struct ac_shader_config *conf = &shader->config;
        unsigned num_inputs = shader->selector->info.num_inputs;
-       unsigned lds_increment = sscreen->info.chip_class >= CIK ? 512 : 256;
+       unsigned lds_increment = sscreen->info.chip_class >= GFX7 ? 512 : 256;
        unsigned lds_per_wave = 0;
        unsigned max_simd_waves;
 
@@ -5442,10 +5257,9 @@ static void si_calculate_max_simd_waves(struct si_shader *shader)
 
        /* Compute the per-SIMD wave counts. */
        if (conf->num_sgprs) {
-               if (sscreen->info.chip_class >= VI)
-                       max_simd_waves = MIN2(max_simd_waves, 800 / conf->num_sgprs);
-               else
-                       max_simd_waves = MIN2(max_simd_waves, 512 / conf->num_sgprs);
+               max_simd_waves =
+                       MIN2(max_simd_waves,
+                            ac_get_num_physical_sgprs(sscreen->info.chip_class) / conf->num_sgprs);
        }
 
        if (conf->num_vgprs)
@@ -5456,32 +5270,33 @@ static void si_calculate_max_simd_waves(struct si_shader *shader)
        if (lds_per_wave)
                max_simd_waves = MIN2(max_simd_waves, 16384 / lds_per_wave);
 
-       conf->max_simd_waves = max_simd_waves;
+       shader->info.max_simd_waves = max_simd_waves;
 }
 
-void si_shader_dump_stats_for_shader_db(const struct si_shader *shader,
+void si_shader_dump_stats_for_shader_db(struct si_screen *screen,
+                                       struct si_shader *shader,
                                        struct pipe_debug_callback *debug)
 {
-       const struct si_shader_config *conf = &shader->config;
+       const struct ac_shader_config *conf = &shader->config;
 
        pipe_debug_message(debug, SHADER_INFO,
                           "Shader Stats: SGPRS: %d VGPRS: %d Code Size: %d "
                           "LDS: %d Scratch: %d Max Waves: %d Spilled SGPRs: %d "
                           "Spilled VGPRs: %d PrivMem VGPRs: %d",
                           conf->num_sgprs, conf->num_vgprs,
-                          si_get_shader_binary_size(shader),
+                          si_get_shader_binary_size(screen, shader),
                           conf->lds_size, conf->scratch_bytes_per_wave,
-                          conf->max_simd_waves, conf->spilled_sgprs,
-                          conf->spilled_vgprs, conf->private_mem_vgprs);
+                          shader->info.max_simd_waves, conf->spilled_sgprs,
+                          conf->spilled_vgprs, shader->info.private_mem_vgprs);
 }
 
 static void si_shader_dump_stats(struct si_screen *sscreen,
-                                const struct si_shader *shader,
+                                struct si_shader *shader,
                                 unsigned processor,
                                 FILE *file,
                                 bool check_debug_option)
 {
-       const struct si_shader_config *conf = &shader->config;
+       const struct ac_shader_config *conf = &shader->config;
 
        if (!check_debug_option ||
            si_can_dump_shader(sscreen, processor)) {
@@ -5505,10 +5320,10 @@ static void si_shader_dump_stats(struct si_screen *sscreen,
                        "********************\n\n\n",
                        conf->num_sgprs, conf->num_vgprs,
                        conf->spilled_sgprs, conf->spilled_vgprs,
-                       conf->private_mem_vgprs,
-                       si_get_shader_binary_size(shader),
+                       shader->info.private_mem_vgprs,
+                       si_get_shader_binary_size(sscreen, shader),
                        conf->lds_size, conf->scratch_bytes_per_wave,
-                       conf->max_simd_waves);
+                       shader->info.max_simd_waves);
        }
 }
 
@@ -5520,6 +5335,8 @@ const char *si_get_shader_name(const struct si_shader *shader, unsigned processo
                        return "Vertex Shader as ES";
                else if (shader->key.as_ls)
                        return "Vertex Shader as LS";
+               else if (shader->key.opt.vs_as_prim_discard_cs)
+                       return "Vertex Shader as Primitive Discard CS";
                else
                        return "Vertex Shader as VS";
        case PIPE_SHADER_TESS_CTRL:
@@ -5543,7 +5360,7 @@ const char *si_get_shader_name(const struct si_shader *shader, unsigned processo
        }
 }
 
-void si_shader_dump(struct si_screen *sscreen, const struct si_shader *shader,
+void si_shader_dump(struct si_screen *sscreen, struct si_shader *shader,
                    struct pipe_debug_callback *debug, unsigned processor,
                    FILE *file, bool check_debug_option)
 {
@@ -5570,19 +5387,19 @@ void si_shader_dump(struct si_screen *sscreen, const struct si_shader *shader,
                fprintf(file, "\n%s:\n", si_get_shader_name(shader, processor));
 
                if (shader->prolog)
-                       si_shader_dump_disassembly(&shader->prolog->binary,
+                       si_shader_dump_disassembly(sscreen, &shader->prolog->binary,
                                                   debug, "prolog", file);
                if (shader->previous_stage)
-                       si_shader_dump_disassembly(&shader->previous_stage->binary,
+                       si_shader_dump_disassembly(sscreen, &shader->previous_stage->binary,
                                                   debug, "previous stage", file);
                if (shader->prolog2)
-                       si_shader_dump_disassembly(&shader->prolog2->binary,
+                       si_shader_dump_disassembly(sscreen, &shader->prolog2->binary,
                                                   debug, "prolog2", file);
 
-               si_shader_dump_disassembly(&shader->binary, debug, "main", file);
+               si_shader_dump_disassembly(sscreen, &shader->binary, debug, "main", file);
 
                if (shader->epilog)
-                       si_shader_dump_disassembly(&shader->epilog->binary,
+                       si_shader_dump_disassembly(sscreen, &shader->epilog->binary,
                                                   debug, "epilog", file);
                fprintf(file, "\n");
        }
@@ -5592,8 +5409,8 @@ void si_shader_dump(struct si_screen *sscreen, const struct si_shader *shader,
 }
 
 static int si_compile_llvm(struct si_screen *sscreen,
-                          struct ac_shader_binary *binary,
-                          struct si_shader_config *conf,
+                          struct si_shader_binary *binary,
+                          struct ac_shader_config *conf,
                           struct ac_llvm_compiler *compiler,
                           LLVMModuleRef mod,
                           struct pipe_debug_callback *debug,
@@ -5601,7 +5418,6 @@ static int si_compile_llvm(struct si_screen *sscreen,
                           const char *name,
                           bool less_optimized)
 {
-       int r = 0;
        unsigned count = p_atomic_inc_return(&sscreen->num_compilations);
 
        if (si_can_dump_shader(sscreen, processor)) {
@@ -5621,13 +5437,24 @@ static int si_compile_llvm(struct si_screen *sscreen,
        }
 
        if (!si_replace_shader(count, binary)) {
-               r = si_llvm_compile(mod, binary, compiler, debug,
-                                   less_optimized);
+               unsigned r = si_llvm_compile(mod, binary, compiler, debug,
+                                            less_optimized);
                if (r)
                        return r;
        }
 
-       si_shader_binary_read_config(binary, conf, 0);
+       struct ac_rtld_binary rtld;
+       if (!ac_rtld_open(&rtld, (struct ac_rtld_open_info){
+                       .info = &sscreen->info,
+                       .num_parts = 1,
+                       .elf_ptrs = &binary->elf_buffer,
+                       .elf_sizes = &binary->elf_size }))
+               return -1;
+
+       bool ok = ac_rtld_read_config(&rtld, conf);
+       ac_rtld_close(&rtld);
+       if (!ok)
+               return -1;
 
        /* Enable 64-bit and 16-bit denormals, because there is no performance
         * cost.
@@ -5639,28 +5466,11 @@ static int si_compile_llvm(struct si_screen *sscreen,
         * - Floating-point output modifiers would be ignored by the hw.
         * - Some opcodes don't support denormals, such as v_mad_f32. We would
         *   have to stop using those.
-        * - SI & CI would be very slow.
+        * - GFX6 & GFX7 would be very slow.
         */
        conf->float_mode |= V_00B028_FP_64_DENORMS;
 
-       FREE(binary->config);
-       FREE(binary->global_symbol_offsets);
-       binary->config = NULL;
-       binary->global_symbol_offsets = NULL;
-
-       /* Some shaders can't have rodata because their binaries can be
-        * concatenated.
-        */
-       if (binary->rodata_size &&
-           (processor == PIPE_SHADER_VERTEX ||
-            processor == PIPE_SHADER_TESS_CTRL ||
-            processor == PIPE_SHADER_TESS_EVAL ||
-            processor == PIPE_SHADER_FRAGMENT)) {
-               fprintf(stderr, "radeonsi: The shader can't have rodata.");
-               return -EINVAL;
-       }
-
-       return r;
+       return 0;
 }
 
 static void si_llvm_build_ret(struct si_shader_context *ctx, LLVMValueRef ret)
@@ -5683,7 +5493,7 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
        LLVMBuilderRef builder;
        struct si_shader_output_values outputs[SI_MAX_VS_OUTPUTS];
        struct tgsi_shader_info *gsinfo = &gs_selector->info;
-       int i, r;
+       int i;
 
 
        shader = CALLOC_STRUCT(si_shader);
@@ -5779,51 +5589,8 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
                                               stream);
                }
 
-               if (stream == 0) {
-                       /* Vertex color clamping.
-                        *
-                        * This uses a state constant loaded in a user data SGPR and
-                        * an IF statement is added that clamps all colors if the constant
-                        * is true.
-                        */
-                       struct lp_build_if_state if_ctx;
-                       LLVMValueRef v[2], cond = NULL;
-                       LLVMBasicBlockRef blocks[2];
-
-                       for (unsigned i = 0; i < gsinfo->num_outputs; i++) {
-                               if (gsinfo->output_semantic_name[i] != TGSI_SEMANTIC_COLOR &&
-                                   gsinfo->output_semantic_name[i] != TGSI_SEMANTIC_BCOLOR)
-                                       continue;
-
-                               /* We've found a color. */
-                               if (!cond) {
-                                       /* The state is in the first bit of the user SGPR. */
-                                       cond = LLVMGetParam(ctx.main_fn,
-                                                           ctx.param_vs_state_bits);
-                                       cond = LLVMBuildTrunc(ctx.ac.builder, cond,
-                                                             ctx.i1, "");
-                                       lp_build_if(&if_ctx, &ctx.gallivm, cond);
-                                       /* Remember blocks for Phi. */
-                                       blocks[0] = if_ctx.true_block;
-                                       blocks[1] = if_ctx.entry_block;
-                               }
-
-                               for (unsigned j = 0; j < 4; j++) {
-                                       /* Insert clamp into the true block. */
-                                       v[0] = ac_build_clamp(&ctx.ac, outputs[i].values[j]);
-                                       v[1] = outputs[i].values[j];
-
-                                       /* Insert Phi into the endif block. */
-                                       LLVMPositionBuilderAtEnd(ctx.ac.builder, if_ctx.merge_block);
-                                       outputs[i].values[j] = ac_build_phi(&ctx.ac, ctx.f32, 2, v, blocks);
-                                       LLVMPositionBuilderAtEnd(ctx.ac.builder, if_ctx.true_block);
-                               }
-                       }
-                       if (cond)
-                               lp_build_endif(&if_ctx);
-
+               if (stream == 0)
                        si_llvm_export_vs(&ctx, outputs, gsinfo->num_outputs);
-               }
 
                LLVMBuildBr(builder, end_bb);
        }
@@ -5835,24 +5602,30 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
        ctx.type = PIPE_SHADER_GEOMETRY; /* override for shader dumping */
        si_llvm_optimize_module(&ctx);
 
-       r = si_compile_llvm(sscreen, &ctx.shader->binary,
+       bool ok = false;
+       if (si_compile_llvm(sscreen, &ctx.shader->binary,
                            &ctx.shader->config, ctx.compiler,
                            ctx.ac.module,
                            debug, PIPE_SHADER_GEOMETRY,
-                           "GS Copy Shader", false);
-       if (!r) {
+                           "GS Copy Shader", false) == 0) {
                if (si_can_dump_shader(sscreen, PIPE_SHADER_GEOMETRY))
                        fprintf(stderr, "GS Copy Shader:\n");
                si_shader_dump(sscreen, ctx.shader, debug,
                               PIPE_SHADER_GEOMETRY, stderr, true);
-               r = si_shader_binary_upload(sscreen, ctx.shader);
+
+               if (!ctx.shader->config.scratch_bytes_per_wave)
+                       ok = si_shader_binary_upload(sscreen, ctx.shader, 0);
+               else
+                       ok = true;
        }
 
        si_llvm_dispose(&ctx);
 
-       if (r != 0) {
+       if (!ok) {
                FREE(shader);
                shader = NULL;
+       } else {
+               si_fix_resource_usage(sscreen, shader);
        }
        return shader;
 }
@@ -5865,12 +5638,23 @@ static void si_dump_shader_key_vs(const struct si_shader_key *key,
                prefix, prolog->instance_divisor_is_one);
        fprintf(f, "  %s.instance_divisor_is_fetched = %u\n",
                prefix, prolog->instance_divisor_is_fetched);
+       fprintf(f, "  %s.unpack_instance_id_from_vertex_id = %u\n",
+               prefix, prolog->unpack_instance_id_from_vertex_id);
        fprintf(f, "  %s.ls_vgpr_fix = %u\n",
                prefix, prolog->ls_vgpr_fix);
 
+       fprintf(f, "  mono.vs.fetch_opencode = %x\n", key->mono.vs_fetch_opencode);
        fprintf(f, "  mono.vs.fix_fetch = {");
-       for (int i = 0; i < SI_MAX_ATTRIBS; i++)
-               fprintf(f, !i ? "%u" : ", %u", key->mono.vs_fix_fetch[i]);
+       for (int i = 0; i < SI_MAX_ATTRIBS; i++) {
+               union si_vs_fix_fetch fix = key->mono.vs_fix_fetch[i];
+               if (i)
+                       fprintf(f, ", ");
+               if (!fix.bits)
+                       fprintf(f, "0");
+               else
+                       fprintf(f, "%u.%u.%u.%u", fix.u.reverse, fix.u.log_size,
+                               fix.u.num_channels_m1, fix.u.format);
+       }
        fprintf(f, "}\n");
 }
 
@@ -5889,6 +5673,28 @@ static void si_dump_shader_key(unsigned processor, const struct si_shader *shade
                fprintf(f, "  as_ls = %u\n", key->as_ls);
                fprintf(f, "  mono.u.vs_export_prim_id = %u\n",
                        key->mono.u.vs_export_prim_id);
+               fprintf(f, "  opt.vs_as_prim_discard_cs = %u\n",
+                       key->opt.vs_as_prim_discard_cs);
+               fprintf(f, "  opt.cs_prim_type = %s\n",
+                       tgsi_primitive_names[key->opt.cs_prim_type]);
+               fprintf(f, "  opt.cs_indexed = %u\n",
+                       key->opt.cs_indexed);
+               fprintf(f, "  opt.cs_instancing = %u\n",
+                       key->opt.cs_instancing);
+               fprintf(f, "  opt.cs_primitive_restart = %u\n",
+                       key->opt.cs_primitive_restart);
+               fprintf(f, "  opt.cs_provoking_vertex_first = %u\n",
+                       key->opt.cs_provoking_vertex_first);
+               fprintf(f, "  opt.cs_need_correct_orientation = %u\n",
+                       key->opt.cs_need_correct_orientation);
+               fprintf(f, "  opt.cs_cull_front = %u\n",
+                       key->opt.cs_cull_front);
+               fprintf(f, "  opt.cs_cull_back = %u\n",
+                       key->opt.cs_cull_back);
+               fprintf(f, "  opt.cs_cull_z = %u\n",
+                       key->opt.cs_cull_z);
+               fprintf(f, "  opt.cs_halfz_clip_space = %u\n",
+                       key->opt.cs_halfz_clip_space);
                break;
 
        case PIPE_SHADER_TESS_CTRL:
@@ -6044,6 +5850,8 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx)
                        ctx->abi.emit_outputs = si_llvm_emit_ls_epilogue;
                else if (shader->key.as_es)
                        ctx->abi.emit_outputs = si_llvm_emit_es_epilogue;
+               else if (shader->key.opt.vs_as_prim_discard_cs)
+                       ctx->abi.emit_outputs = si_llvm_emit_prim_discard_cs_epilogue;
                else
                        ctx->abi.emit_outputs = si_llvm_emit_vs_epilogue;
                bld_base->emit_epilogue = si_tgsi_emit_epilogue;
@@ -6168,7 +5976,7 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx)
        if (sel->force_correct_derivs_after_kill) {
                ctx->postponed_kill = ac_build_alloca_undef(&ctx->ac, ctx->i1, "");
                /* true = don't kill. */
-               LLVMBuildStore(ctx->ac.builder, LLVMConstInt(ctx->i1, 1, 0),
+               LLVMBuildStore(ctx->ac.builder, ctx->i1true,
                               ctx->postponed_kill);
        }
 
@@ -6575,7 +6383,26 @@ static void si_build_wrapper_function(struct si_shader_context *ctx,
                gprs += size;
        }
 
-       si_create_function(ctx, "wrapper", NULL, 0, &fninfo,
+       /* Prepare the return type. */
+       unsigned num_returns = 0;
+       LLVMTypeRef returns[32], last_func_type, return_type;
+
+       last_func_type = LLVMGetElementType(LLVMTypeOf(parts[num_parts - 1]));
+       return_type = LLVMGetReturnType(last_func_type);
+
+       switch (LLVMGetTypeKind(return_type)) {
+       case LLVMStructTypeKind:
+               num_returns = LLVMCountStructElementTypes(return_type);
+               assert(num_returns <= ARRAY_SIZE(returns));
+               LLVMGetStructElementTypes(return_type, returns);
+               break;
+       case LLVMVoidTypeKind:
+               break;
+       default:
+               unreachable("unexpected type");
+       }
+
+       si_create_function(ctx, "wrapper", returns, num_returns, &fninfo,
                           si_get_max_workgroup_size(ctx->shader));
 
        if (is_merged_shader(ctx))
@@ -6627,9 +6454,9 @@ static void si_build_wrapper_function(struct si_shader_context *ctx,
        initial_num_out_sgpr = num_out_sgpr;
 
        /* Now chain the parts. */
+       LLVMValueRef ret;
        for (unsigned part = 0; part < num_parts; ++part) {
                LLVMValueRef in[48];
-               LLVMValueRef ret;
                LLVMTypeRef ret_type;
                unsigned out_idx = 0;
                unsigned num_params = LLVMCountParams(parts[part]);
@@ -6680,7 +6507,7 @@ static void si_build_wrapper_function(struct si_shader_context *ctx,
                        if (LLVMTypeOf(arg) != param_type) {
                                if (LLVMGetTypeKind(param_type) == LLVMPointerTypeKind) {
                                        if (LLVMGetPointerAddressSpace(param_type) ==
-                                           AC_CONST_32BIT_ADDR_SPACE) {
+                                           AC_ADDR_SPACE_CONST_32BIT) {
                                                arg = LLVMBuildBitCast(builder, arg, ctx->i32, "");
                                                arg = LLVMBuildIntToPtr(builder, arg, param_type, "");
                                        } else {
@@ -6741,7 +6568,11 @@ static void si_build_wrapper_function(struct si_shader_context *ctx,
                }
        }
 
-       LLVMBuildRetVoid(builder);
+       /* Return the value from the last part. */
+       if (LLVMGetTypeKind(LLVMTypeOf(ret)) == LLVMVoidTypeKind)
+               LLVMBuildRetVoid(builder);
+       else
+               LLVMBuildRet(builder, ret);
 }
 
 static bool si_should_optimize_less(struct ac_llvm_compiler *compiler,
@@ -6752,7 +6583,7 @@ static bool si_should_optimize_less(struct ac_llvm_compiler *compiler,
 
        /* Assume a slow CPU. */
        assert(!sel->screen->info.has_dedicated_vram &&
-              sel->screen->info.chip_class <= VI);
+              sel->screen->info.chip_class <= GFX8);
 
        /* For a crazy dEQP test containing 2597 memory opcodes, mostly
         * buffer stores. */
@@ -6811,6 +6642,9 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
 
                si_build_wrapper_function(&ctx, parts + !need_prolog,
                                          1 + need_prolog, need_prolog, 0);
+
+               if (ctx.shader->key.opt.vs_as_prim_discard_cs)
+                       si_build_prim_discard_compute_shader(&ctx);
        } else if (shader->is_monolithic && ctx.type == PIPE_SHADER_TESS_CTRL) {
                if (sscreen->info.chip_class >= GFX9) {
                        struct si_shader_selector *ls = shader->key.part.tcs.ls;
@@ -6982,7 +6816,7 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
 
        if ((debug && debug->debug_message) ||
            si_can_dump_shader(sscreen, ctx.type)) {
-               ctx.shader->config.private_mem_vgprs =
+               ctx.shader->info.private_mem_vgprs =
                        ac_count_scratch_private_memory(ctx.main_fn);
        }
 
@@ -7007,7 +6841,7 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
        if (sel->type == PIPE_SHADER_COMPUTE) {
                unsigned wave_size = 64;
                unsigned max_vgprs = 256;
-               unsigned max_sgprs = sscreen->info.chip_class >= VI ? 800 : 512;
+               unsigned max_sgprs = sscreen->info.chip_class >= GFX8 ? 800 : 512;
                unsigned max_sgprs_per_wave = 128;
                unsigned max_block_threads = si_get_max_workgroup_size(shader);
                unsigned min_waves_per_cu = DIV_ROUND_UP(max_block_threads, wave_size);
@@ -7081,7 +6915,7 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
        }
 
        si_calculate_max_simd_waves(shader);
-       si_shader_dump_stats_for_shader_db(shader, debug);
+       si_shader_dump_stats_for_shader_db(sscreen, shader, debug);
        return 0;
 }
 
@@ -7181,20 +7015,9 @@ static LLVMValueRef si_prolog_get_rw_buffers(struct si_shader_context *ctx)
        LLVMValueRef ptr[2], list;
        bool merged_shader = is_merged_shader(ctx);
 
-       if (HAVE_32BIT_POINTERS) {
-               ptr[0] = LLVMGetParam(ctx->main_fn, (merged_shader ? 8 : 0) + SI_SGPR_RW_BUFFERS);
-               list = LLVMBuildIntToPtr(ctx->ac.builder, ptr[0],
-                                        ac_array_in_const32_addr_space(ctx->v4i32), "");
-               return list;
-       }
-
-       /* Get the pointer to rw buffers. */
        ptr[0] = LLVMGetParam(ctx->main_fn, (merged_shader ? 8 : 0) + SI_SGPR_RW_BUFFERS);
-       ptr[1] = LLVMGetParam(ctx->main_fn, (merged_shader ? 8 : 0) + SI_SGPR_RW_BUFFERS + 1);
-       list = ac_build_gather_values(&ctx->ac, ptr, 2);
-       list = LLVMBuildBitCast(ctx->ac.builder, list, ctx->i64, "");
-       list = LLVMBuildIntToPtr(ctx->ac.builder, list,
-                                ac_array_in_const_addr_space(ctx->v4i32), "");
+       list = LLVMBuildIntToPtr(ctx->ac.builder, ptr[0],
+                                ac_array_in_const32_addr_space(ctx->v4i32), "");
        return list;
 }
 
@@ -7279,8 +7102,21 @@ static void si_build_vs_prolog_function(struct si_shader_context *ctx,
                }
        }
 
-       ctx->abi.vertex_id = input_vgprs[first_vs_vgpr];
-       ctx->abi.instance_id = input_vgprs[first_vs_vgpr + (key->vs_prolog.as_ls ? 2 : 1)];
+       unsigned vertex_id_vgpr = first_vs_vgpr;
+       unsigned instance_id_vgpr = first_vs_vgpr + (key->vs_prolog.as_ls ? 2 : 1);
+
+       ctx->abi.vertex_id = input_vgprs[vertex_id_vgpr];
+       ctx->abi.instance_id = input_vgprs[instance_id_vgpr];
+
+       /* InstanceID = VertexID >> 16;
+        * VertexID   = VertexID & 0xffff;
+        */
+       if (key->vs_prolog.states.unpack_instance_id_from_vertex_id) {
+               ctx->abi.instance_id = LLVMBuildLShr(ctx->ac.builder, ctx->abi.vertex_id,
+                                                    LLVMConstInt(ctx->i32, 16, 0), "");
+               ctx->abi.vertex_id = LLVMBuildAnd(ctx->ac.builder, ctx->abi.vertex_id,
+                                                 LLVMConstInt(ctx->i32, 0xffff, 0), "");
+       }
 
        /* Copy inputs to outputs. This should be no-op, as the registers match,
         * but it will prevent the compiler from overwriting them unintentionally.
@@ -7292,6 +7128,12 @@ static void si_build_vs_prolog_function(struct si_shader_context *ctx,
        }
        for (i = 0; i < num_input_vgprs; i++) {
                LLVMValueRef p = input_vgprs[i];
+
+               if (i == vertex_id_vgpr)
+                       p = ctx->abi.vertex_id;
+               else if (i == instance_id_vgpr)
+                       p = ctx->abi.instance_id;
+
                p = ac_to_float(&ctx->ac, p);
                ret = LLVMBuildInsertValue(ctx->ac.builder, ret, p,
                                           key->vs_prolog.num_input_sgprs + i, "");
@@ -7313,22 +7155,32 @@ static void si_build_vs_prolog_function(struct si_shader_context *ctx,
                        key->vs_prolog.states.instance_divisor_is_one & (1u << i);
                bool divisor_is_fetched =
                        key->vs_prolog.states.instance_divisor_is_fetched & (1u << i);
-               LLVMValueRef index;
-
-               if (divisor_is_one || divisor_is_fetched) {
-                       LLVMValueRef divisor = ctx->i32_1;
-
-                       if (divisor_is_fetched) {
-                               divisor = buffer_load_const(ctx, instance_divisor_constbuf,
-                                                           LLVMConstInt(ctx->i32, i * 4, 0));
-                               divisor = ac_to_integer(&ctx->ac, divisor);
+               LLVMValueRef index = NULL;
+
+               if (divisor_is_one) {
+                       index = ctx->abi.instance_id;
+               } else if (divisor_is_fetched) {
+                       LLVMValueRef udiv_factors[4];
+
+                       for (unsigned j = 0; j < 4; j++) {
+                               udiv_factors[j] =
+                                       buffer_load_const(ctx, instance_divisor_constbuf,
+                                                         LLVMConstInt(ctx->i32, i*16 + j*4, 0));
+                               udiv_factors[j] = ac_to_integer(&ctx->ac, udiv_factors[j]);
                        }
+                       /* The faster NUW version doesn't work when InstanceID == UINT_MAX.
+                        * Such InstanceID might not be achievable in a reasonable time though.
+                        */
+                       index = ac_build_fast_udiv_nuw(&ctx->ac, ctx->abi.instance_id,
+                                                      udiv_factors[0], udiv_factors[1],
+                                                      udiv_factors[2], udiv_factors[3]);
+               }
 
-                       /* InstanceID / Divisor + StartInstance */
-                       index = get_instance_index_for_fetch(ctx,
-                                                            user_sgpr_base +
-                                                            SI_SGPR_START_INSTANCE,
-                                                            divisor);
+               if (divisor_is_one || divisor_is_fetched) {
+                       /* Add StartInstance. */
+                       index = LLVMBuildAdd(ctx->ac.builder, index,
+                                            LLVMGetParam(ctx->main_fn, user_sgpr_base +
+                                                         SI_SGPR_START_INSTANCE), "");
                } else {
                        /* VertexID + BaseVertex */
                        index = LLVMBuildAdd(ctx->ac.builder,
@@ -7412,8 +7264,6 @@ static void si_build_tcs_epilog_function(struct si_shader_context *ctx,
                add_arg(&fninfo, ARG_SGPR, ctx->i32);
                add_arg(&fninfo, ARG_SGPR, ctx->i32);
                add_arg(&fninfo, ARG_SGPR, ctx->i32);
-               if (!HAVE_32BIT_POINTERS)
-                       add_arg(&fninfo, ARG_SGPR, ctx->ac.intptr);
                ctx->param_tcs_offchip_layout = add_arg(&fninfo, ARG_SGPR, ctx->i32);
                add_arg(&fninfo, ARG_SGPR, ctx->i32);
                ctx->param_tcs_out_lds_layout = add_arg(&fninfo, ARG_SGPR, ctx->i32);
@@ -7442,7 +7292,7 @@ static void si_build_tcs_epilog_function(struct si_shader_context *ctx,
 
        /* Create the function. */
        si_create_function(ctx, "tcs_epilog", NULL, 0, &fninfo,
-                          ctx->screen->info.chip_class >= CIK ? 128 : 64);
+                          ctx->screen->info.chip_class >= GFX7 ? 128 : 64);
        ac_declare_lds_as_pointer(&ctx->ac);
        func = ctx->main_fn;
 
@@ -8020,8 +7870,7 @@ void si_multiwave_lds_size_workaround(struct si_screen *sscreen,
         *   It applies to workgroup sizes of more than one wavefront.
         */
        if (sscreen->info.family == CHIP_BONAIRE ||
-           sscreen->info.family == CHIP_KABINI ||
-           sscreen->info.family == CHIP_MULLINS)
+           sscreen->info.family == CHIP_KABINI)
                *lds_size = MAX2(*lds_size, 8);
 }
 
@@ -8039,7 +7888,7 @@ static void si_fix_resource_usage(struct si_screen *sscreen,
        }
 }
 
-int si_shader_create(struct si_screen *sscreen, struct ac_llvm_compiler *compiler,
+bool si_shader_create(struct si_screen *sscreen, struct ac_llvm_compiler *compiler,
                     struct si_shader *shader,
                     struct pipe_debug_callback *debug)
 {
@@ -8059,7 +7908,7 @@ int si_shader_create(struct si_screen *sscreen, struct ac_llvm_compiler *compile
                 */
                r = si_compile_tgsi_shader(sscreen, compiler, shader, debug);
                if (r)
-                       return r;
+                       return false;
        } else {
                /* The shader consists of several parts:
                 *
@@ -8077,7 +7926,7 @@ int si_shader_create(struct si_screen *sscreen, struct ac_llvm_compiler *compile
                 */
 
                if (!mainp)
-                       return -1;
+                       return false;
 
                /* Copy the compiled TGSI shader data over. */
                shader->is_binary_shared = true;
@@ -8098,21 +7947,21 @@ int si_shader_create(struct si_screen *sscreen, struct ac_llvm_compiler *compile
                switch (sel->type) {
                case PIPE_SHADER_VERTEX:
                        if (!si_shader_select_vs_parts(sscreen, compiler, shader, debug))
-                               return -1;
+                               return false;
                        break;
                case PIPE_SHADER_TESS_CTRL:
                        if (!si_shader_select_tcs_parts(sscreen, compiler, shader, debug))
-                               return -1;
+                               return false;
                        break;
                case PIPE_SHADER_TESS_EVAL:
                        break;
                case PIPE_SHADER_GEOMETRY:
                        if (!si_shader_select_gs_parts(sscreen, compiler, shader, debug))
-                               return -1;
+                               return false;
                        break;
                case PIPE_SHADER_FRAGMENT:
                        if (!si_shader_select_ps_parts(sscreen, compiler, shader, debug))
-                               return -1;
+                               return false;
 
                        /* Make sure we have at least as many VGPRs as there
                         * are allocated inputs.
@@ -8140,9 +7989,9 @@ int si_shader_create(struct si_screen *sscreen, struct ac_llvm_compiler *compile
                        shader->config.spilled_vgprs =
                                MAX2(shader->config.spilled_vgprs,
                                     shader->previous_stage->config.spilled_vgprs);
-                       shader->config.private_mem_vgprs =
-                               MAX2(shader->config.private_mem_vgprs,
-                                    shader->previous_stage->config.private_mem_vgprs);
+                       shader->info.private_mem_vgprs =
+                               MAX2(shader->info.private_mem_vgprs,
+                                    shader->previous_stage->info.private_mem_vgprs);
                        shader->config.scratch_bytes_per_wave =
                                MAX2(shader->config.scratch_bytes_per_wave,
                                     shader->previous_stage->config.scratch_bytes_per_wave);
@@ -8169,24 +8018,23 @@ int si_shader_create(struct si_screen *sscreen, struct ac_llvm_compiler *compile
                       stderr, true);
 
        /* Upload. */
-       r = si_shader_binary_upload(sscreen, shader);
-       if (r) {
+       if (!si_shader_binary_upload(sscreen, shader, 0)) {
                fprintf(stderr, "LLVM failed to upload shader\n");
-               return r;
+               return false;
        }
 
-       return 0;
+       return true;
 }
 
 void si_shader_destroy(struct si_shader *shader)
 {
        if (shader->scratch_bo)
-               r600_resource_reference(&shader->scratch_bo, NULL);
+               si_resource_reference(&shader->scratch_bo, NULL);
 
-       r600_resource_reference(&shader->bo, NULL);
+       si_resource_reference(&shader->bo, NULL);
 
        if (!shader->is_binary_shared)
-               ac_shader_binary_clean(&shader->binary);
+               si_shader_binary_clean(&shader->binary);
 
        free(shader->shader_log);
 }