radeonsi/nir: always lower ballot masks as 64-bit, codegen handles it
[mesa.git] / src / amd / common / ac_nir_to_llvm.c
index 530cf7a0212cb403fa9bbb18c6b5a250bec88714..d97387ef13d275daafdf9d87eb645e1b792a73c2 100644 (file)
@@ -38,9 +38,12 @@ struct ac_nir_context {
        struct ac_shader_abi *abi;
 
        gl_shader_stage stage;
+       shader_info *info;
 
        LLVMValueRef *ssa_defs;
 
+       LLVMValueRef scratch;
+
        struct hash_table *defs;
        struct hash_table *phis;
        struct hash_table *vars;
@@ -56,7 +59,7 @@ struct ac_nir_context {
 static LLVMValueRef get_sampler_desc(struct ac_nir_context *ctx,
                                     nir_deref_instr *deref_instr,
                                     enum ac_descriptor_type desc_type,
-                                    const nir_tex_instr *instr,
+                                    const nir_instr *instr,
                                     bool image, bool write);
 
 static void
@@ -83,7 +86,7 @@ get_ac_sampler_dim(const struct ac_llvm_context *ctx, enum glsl_sampler_dim dim,
 {
        switch (dim) {
        case GLSL_SAMPLER_DIM_1D:
-               if (ctx->chip_class >= GFX9)
+               if (ctx->chip_class == GFX9)
                        return is_array ? ac_image_2darray : ac_image_2d;
                return is_array ? ac_image_1darray : ac_image_1d;
        case GLSL_SAMPLER_DIM_2D:
@@ -112,7 +115,7 @@ get_ac_image_dim(const struct ac_llvm_context *ctx, enum glsl_sampler_dim sdim,
        enum ac_image_dim dim = get_ac_sampler_dim(ctx, sdim, is_array);
 
        if (dim == ac_image_cube ||
-           (ctx->chip_class <= VI && dim == ac_image_3d))
+           (ctx->chip_class <= GFX8 && dim == ac_image_3d))
                dim = ac_image_2darray;
 
        return dim;
@@ -224,7 +227,7 @@ static LLVMValueRef emit_intrin_1f_param(struct ac_llvm_context *ctx,
                ac_to_float(ctx, src0),
        };
 
-       MAYBE_UNUSED const int length = snprintf(name, sizeof(name), "%s.f%d", intrin,
+       ASSERTED const int length = snprintf(name, sizeof(name), "%s.f%d", intrin,
                                                 ac_get_elem_bits(ctx, result_type));
        assert(length < sizeof(name));
        return ac_build_intrinsic(ctx, name, result_type, params, 1, AC_FUNC_ATTR_READNONE);
@@ -241,7 +244,7 @@ static LLVMValueRef emit_intrin_2f_param(struct ac_llvm_context *ctx,
                ac_to_float(ctx, src1),
        };
 
-       MAYBE_UNUSED const int length = snprintf(name, sizeof(name), "%s.f%d", intrin,
+       ASSERTED const int length = snprintf(name, sizeof(name), "%s.f%d", intrin,
                                                 ac_get_elem_bits(ctx, result_type));
        assert(length < sizeof(name));
        return ac_build_intrinsic(ctx, name, result_type, params, 2, AC_FUNC_ATTR_READNONE);
@@ -259,7 +262,7 @@ static LLVMValueRef emit_intrin_3f_param(struct ac_llvm_context *ctx,
                ac_to_float(ctx, src2),
        };
 
-       MAYBE_UNUSED const int length = snprintf(name, sizeof(name), "%s.f%d", intrin,
+       ASSERTED const int length = snprintf(name, sizeof(name), "%s.f%d", intrin,
                                                 ac_get_elem_bits(ctx, result_type));
        assert(length < sizeof(name));
        return ac_build_intrinsic(ctx, name, result_type, params, 3, AC_FUNC_ATTR_READNONE);
@@ -277,21 +280,10 @@ static LLVMValueRef emit_bcsel(struct ac_llvm_context *ctx,
                               ac_to_integer_or_pointer(ctx, src2), "");
 }
 
-static LLVMValueRef emit_minmax_int(struct ac_llvm_context *ctx,
-                                   LLVMIntPredicate pred,
-                                   LLVMValueRef src0, LLVMValueRef src1)
-{
-       return LLVMBuildSelect(ctx->builder,
-                              LLVMBuildICmp(ctx->builder, pred, src0, src1, ""),
-                              src0,
-                              src1, "");
-
-}
 static LLVMValueRef emit_iabs(struct ac_llvm_context *ctx,
                              LLVMValueRef src0)
 {
-       return emit_minmax_int(ctx, LLVMIntSGT, src0,
-                              LLVMBuildNeg(ctx->builder, src0, ""));
+       return ac_build_imax(ctx, src0, LLVMBuildNeg(ctx->builder, src0, ""));
 }
 
 static LLVMValueRef emit_uint_carry(struct ac_llvm_context *ctx,
@@ -322,10 +314,16 @@ static LLVMValueRef emit_b2f(struct ac_llvm_context *ctx,
                                           "");
        result = LLVMBuildBitCast(ctx->builder, result, ctx->f32, "");
 
-       if (bitsize == 32)
+       switch (bitsize) {
+       case 16:
+               return LLVMBuildFPTrunc(ctx->builder, result, ctx->f16, "");
+       case 32:
                return result;
-
-       return LLVMBuildFPExt(ctx->builder, result, ctx->f64, "");
+       case 64:
+               return LLVMBuildFPExt(ctx->builder, result, ctx->f64, "");
+       default:
+               unreachable("Unsupported bit size.");
+       }
 }
 
 static LLVMValueRef emit_f2b(struct ac_llvm_context *ctx,
@@ -344,10 +342,18 @@ static LLVMValueRef emit_b2i(struct ac_llvm_context *ctx,
 {
        LLVMValueRef result = LLVMBuildAnd(ctx->builder, src0, ctx->i32_1, "");
 
-       if (bitsize == 32)
+       switch (bitsize) {
+       case 8:
+               return LLVMBuildTrunc(ctx->builder, result, ctx->i8, "");
+       case 16:
+               return LLVMBuildTrunc(ctx->builder, result, ctx->i16, "");
+       case 32:
                return result;
-
-       return LLVMBuildZExt(ctx->builder, result, ctx->i64, "");
+       case 64:
+               return LLVMBuildZExt(ctx->builder, result, ctx->i64, "");
+       default:
+               unreachable("Unsupported bit size.");
+       }
 }
 
 static LLVMValueRef emit_i2b(struct ac_llvm_context *ctx,
@@ -368,7 +374,7 @@ static LLVMValueRef emit_f2f16(struct ac_llvm_context *ctx,
        src0 = ac_to_float(ctx, src0);
        result = LLVMBuildFPTrunc(ctx->builder, src0, ctx->f16, "");
 
-       if (ctx->chip_class >= VI) {
+       if (ctx->chip_class >= GFX8) {
                LLVMValueRef args[2];
                /* Check if the result is a denormal - and flush to 0 if so. */
                args[0] = result;
@@ -379,10 +385,10 @@ static LLVMValueRef emit_f2f16(struct ac_llvm_context *ctx,
        /* need to convert back up to f32 */
        result = LLVMBuildFPExt(ctx->builder, result, ctx->f32, "");
 
-       if (ctx->chip_class >= VI)
+       if (ctx->chip_class >= GFX8)
                result = LLVMBuildSelect(ctx->builder, cond, ctx->f32_0, result, "");
        else {
-               /* for SI/CIK */
+               /* for GFX6-GFX7 */
                /* 0x38800000 is smallest half float value (2^-14) in 32-bit float,
                 * so compare the result and flush to 0 if it's smaller.
                 */
@@ -425,64 +431,36 @@ static LLVMValueRef emit_imul_high(struct ac_llvm_context *ctx,
        return result;
 }
 
-static LLVMValueRef emit_bitfield_extract(struct ac_llvm_context *ctx,
-                                         bool is_signed,
-                                         const LLVMValueRef srcs[3])
+static LLVMValueRef emit_bfm(struct ac_llvm_context *ctx,
+                            LLVMValueRef bits, LLVMValueRef offset)
 {
-       LLVMValueRef result;
-
-       if (HAVE_LLVM >= 0x0800) {
-               LLVMValueRef icond = LLVMBuildICmp(ctx->builder, LLVMIntEQ, srcs[2], LLVMConstInt(ctx->i32, 32, false), "");
-               result = ac_build_bfe(ctx, srcs[0], srcs[1], srcs[2], is_signed);
-               result = LLVMBuildSelect(ctx->builder, icond, srcs[0], result, "");
-       } else {
-               /* FIXME: LLVM 7+ returns incorrect result when count is 0.
-                * https://bugs.freedesktop.org/show_bug.cgi?id=107276
-                */
-               LLVMValueRef zero = ctx->i32_0;
-               LLVMValueRef icond1 = LLVMBuildICmp(ctx->builder, LLVMIntEQ, srcs[2], LLVMConstInt(ctx->i32, 32, false), "");
-               LLVMValueRef icond2 = LLVMBuildICmp(ctx->builder, LLVMIntEQ, srcs[2], zero, "");
-
-               result = ac_build_bfe(ctx, srcs[0], srcs[1], srcs[2], is_signed);
-               result = LLVMBuildSelect(ctx->builder, icond1, srcs[0], result, "");
-               result = LLVMBuildSelect(ctx->builder, icond2, zero, result, "");
-       }
-
-       return result;
+       /* mask = ((1 << bits) - 1) << offset */
+       return LLVMBuildShl(ctx->builder,
+                           LLVMBuildSub(ctx->builder,
+                                        LLVMBuildShl(ctx->builder,
+                                                     ctx->i32_1,
+                                                     bits, ""),
+                                        ctx->i32_1, ""),
+                           offset, "");
 }
 
-static LLVMValueRef emit_bitfield_insert(struct ac_llvm_context *ctx,
-                                        LLVMValueRef src0, LLVMValueRef src1,
-                                        LLVMValueRef src2, LLVMValueRef src3)
+static LLVMValueRef emit_bitfield_select(struct ac_llvm_context *ctx,
+                                        LLVMValueRef mask, LLVMValueRef insert,
+                                        LLVMValueRef base)
 {
-       LLVMValueRef bfi_args[3], result;
-
-       bfi_args[0] = LLVMBuildShl(ctx->builder,
-                                  LLVMBuildSub(ctx->builder,
-                                               LLVMBuildShl(ctx->builder,
-                                                            ctx->i32_1,
-                                                            src3, ""),
-                                               ctx->i32_1, ""),
-                                  src2, "");
-       bfi_args[1] = LLVMBuildShl(ctx->builder, src1, src2, "");
-       bfi_args[2] = src0;
-
-       LLVMValueRef icond = LLVMBuildICmp(ctx->builder, LLVMIntEQ, src3, LLVMConstInt(ctx->i32, 32, false), "");
-
        /* Calculate:
-        *   (arg0 & arg1) | (~arg0 & arg2) = arg2 ^ (arg0 & (arg1 ^ arg2)
+        *   (mask & insert) | (~mask & base) = base ^ (mask & (insert ^ base))
         * Use the right-hand side, which the LLVM backend can convert to V_BFI.
         */
-       result = LLVMBuildXor(ctx->builder, bfi_args[2],
-                             LLVMBuildAnd(ctx->builder, bfi_args[0],
-                                          LLVMBuildXor(ctx->builder, bfi_args[1], bfi_args[2], ""), ""), "");
-
-       result = LLVMBuildSelect(ctx->builder, icond, src1, result, "");
-       return result;
+       return LLVMBuildXor(ctx->builder, base,
+                           LLVMBuildAnd(ctx->builder, mask,
+                                        LLVMBuildXor(ctx->builder, insert, base, ""), ""), "");
 }
 
-static LLVMValueRef emit_pack_half_2x16(struct ac_llvm_context *ctx,
-                                       LLVMValueRef src0)
+static LLVMValueRef emit_pack_2x16(struct ac_llvm_context *ctx,
+                                  LLVMValueRef src0,
+                                  LLVMValueRef (*pack)(struct ac_llvm_context *ctx,
+                                                       LLVMValueRef args[2]))
 {
        LLVMValueRef comp[2];
 
@@ -490,8 +468,7 @@ static LLVMValueRef emit_pack_half_2x16(struct ac_llvm_context *ctx,
        comp[0] = LLVMBuildExtractElement(ctx->builder, src0, ctx->i32_0, "");
        comp[1] = LLVMBuildExtractElement(ctx->builder, src0, ctx->i32_1, "");
 
-       return LLVMBuildBitCast(ctx->builder, ac_build_cvt_pkrtz_f16(ctx, comp),
-                               ctx->i32, "");
+       return LLVMBuildBitCast(ctx->builder, pack(ctx, comp), ctx->i32, "");
 }
 
 static LLVMValueRef emit_unpack_half_2x16(struct ac_llvm_context *ctx,
@@ -537,27 +514,6 @@ static LLVMValueRef emit_ddxy(struct ac_nir_context *ctx,
        return result;
 }
 
-/*
- * 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 emit_ddxy_interp(
-       struct ac_nir_context *ctx,
-       LLVMValueRef interp_ij)
-{
-       LLVMValueRef result[4], a;
-       unsigned i;
-
-       for (i = 0; i < 2; i++) {
-               a = LLVMBuildExtractElement(ctx->ac.builder, interp_ij,
-                                           LLVMConstInt(ctx->ac.i32, i, false), "");
-               result[i] = emit_ddxy(ctx, nir_op_fddx, a);
-               result[2+i] = emit_ddxy(ctx, nir_op_fddy, a);
-       }
-       return ac_build_gather_values(&ctx->ac, result, 4);
-}
-
 static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
 {
        LLVMValueRef src[4], result = NULL;
@@ -573,6 +529,8 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
                src_components = 1;
                break;
        case nir_op_pack_half_2x16:
+       case nir_op_pack_snorm_2x16:
+       case nir_op_pack_unorm_2x16:
                src_components = 2;
                break;
        case nir_op_unpack_half_2x16:
@@ -590,8 +548,7 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
                src[i] = get_alu_src(ctx, instr->src[i], src_components);
 
        switch (instr->op) {
-       case nir_op_fmov:
-       case nir_op_imov:
+       case nir_op_mov:
                result = src[0];
                break;
        case nir_op_fneg:
@@ -671,22 +628,31 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
                result = LLVMBuildXor(ctx->ac.builder, src[0], src[1], "");
                break;
        case nir_op_ishl:
-               result = LLVMBuildShl(ctx->ac.builder, src[0],
-                                     LLVMBuildZExt(ctx->ac.builder, src[1],
-                                                   LLVMTypeOf(src[0]), ""),
-                                     "");
+               if (ac_get_elem_bits(&ctx->ac, LLVMTypeOf(src[1])) < ac_get_elem_bits(&ctx->ac, LLVMTypeOf(src[0])))
+                       src[1] = LLVMBuildZExt(ctx->ac.builder, src[1],
+                                              LLVMTypeOf(src[0]), "");
+               else if (ac_get_elem_bits(&ctx->ac, LLVMTypeOf(src[1])) > ac_get_elem_bits(&ctx->ac, LLVMTypeOf(src[0])))
+                       src[1] = LLVMBuildTrunc(ctx->ac.builder, src[1],
+                                               LLVMTypeOf(src[0]), "");
+               result = LLVMBuildShl(ctx->ac.builder, src[0], src[1], "");
                break;
        case nir_op_ishr:
-               result = LLVMBuildAShr(ctx->ac.builder, src[0],
-                                      LLVMBuildZExt(ctx->ac.builder, src[1],
-                                                    LLVMTypeOf(src[0]), ""),
-                                      "");
+               if (ac_get_elem_bits(&ctx->ac, LLVMTypeOf(src[1])) < ac_get_elem_bits(&ctx->ac, LLVMTypeOf(src[0])))
+                       src[1] = LLVMBuildZExt(ctx->ac.builder, src[1],
+                                              LLVMTypeOf(src[0]), "");
+               else if (ac_get_elem_bits(&ctx->ac, LLVMTypeOf(src[1])) > ac_get_elem_bits(&ctx->ac, LLVMTypeOf(src[0])))
+                       src[1] = LLVMBuildTrunc(ctx->ac.builder, src[1],
+                                               LLVMTypeOf(src[0]), "");
+               result = LLVMBuildAShr(ctx->ac.builder, src[0], src[1], "");
                break;
        case nir_op_ushr:
-               result = LLVMBuildLShr(ctx->ac.builder, src[0],
-                                      LLVMBuildZExt(ctx->ac.builder, src[1],
-                                                    LLVMTypeOf(src[0]), ""),
-                                      "");
+               if (ac_get_elem_bits(&ctx->ac, LLVMTypeOf(src[1])) < ac_get_elem_bits(&ctx->ac, LLVMTypeOf(src[0])))
+                       src[1] = LLVMBuildZExt(ctx->ac.builder, src[1],
+                                              LLVMTypeOf(src[0]), "");
+               else if (ac_get_elem_bits(&ctx->ac, LLVMTypeOf(src[1])) > ac_get_elem_bits(&ctx->ac, LLVMTypeOf(src[0])))
+                       src[1] = LLVMBuildTrunc(ctx->ac.builder, src[1],
+                                               LLVMTypeOf(src[0]), "");
+               result = LLVMBuildLShr(ctx->ac.builder, src[0], src[1], "");
                break;
        case nir_op_ilt32:
                result = emit_int_cmp(&ctx->ac, LLVMIntSLT, src[0], src[1]);
@@ -726,16 +692,16 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
                result = emit_iabs(&ctx->ac, src[0]);
                break;
        case nir_op_imax:
-               result = emit_minmax_int(&ctx->ac, LLVMIntSGT, src[0], src[1]);
+               result = ac_build_imax(&ctx->ac, src[0], src[1]);
                break;
        case nir_op_imin:
-               result = emit_minmax_int(&ctx->ac, LLVMIntSLT, src[0], src[1]);
+               result = ac_build_imin(&ctx->ac, src[0], src[1]);
                break;
        case nir_op_umax:
-               result = emit_minmax_int(&ctx->ac, LLVMIntUGT, src[0], src[1]);
+               result = ac_build_umax(&ctx->ac, src[0], src[1]);
                break;
        case nir_op_umin:
-               result = emit_minmax_int(&ctx->ac, LLVMIntULT, src[0], src[1]);
+               result = ac_build_umin(&ctx->ac, src[0], src[1]);
                break;
        case nir_op_isign:
                result = ac_build_isign(&ctx->ac, src[0],
@@ -794,14 +760,16 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
                break;
        case nir_op_frexp_exp:
                src[0] = ac_to_float(&ctx->ac, src[0]);
-               result = ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.frexp.exp.i32.f64",
-                                           ctx->ac.i32, src, 1, AC_FUNC_ATTR_READNONE);
-
+               result = ac_build_frexp_exp(&ctx->ac, src[0],
+                                           ac_get_elem_bits(&ctx->ac, LLVMTypeOf(src[0])));
+               if (ac_get_elem_bits(&ctx->ac, LLVMTypeOf(src[0])) == 16)
+                       result = LLVMBuildSExt(ctx->ac.builder, result,
+                                              ctx->ac.i32, "");
                break;
        case nir_op_frexp_sig:
                src[0] = ac_to_float(&ctx->ac, src[0]);
-               result = ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.frexp.mant.f64",
-                                           ctx->ac.f64, src, 1, AC_FUNC_ATTR_READNONE);
+               result = ac_build_frexp_mant(&ctx->ac, src[0],
+                                            instr->dest.dest.ssa.bit_size);
                break;
        case nir_op_fpow:
                result = emit_intrin_2f_param(&ctx->ac, "llvm.pow",
@@ -842,14 +810,17 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
                else
                        result = ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.ldexp.f64", ctx->ac.f64, src, 2, AC_FUNC_ATTR_READNONE);
                break;
-       case nir_op_ibitfield_extract:
-               result = emit_bitfield_extract(&ctx->ac, true, src);
+       case nir_op_bfm:
+               result = emit_bfm(&ctx->ac, src[0], src[1]);
+               break;
+       case nir_op_bitfield_select:
+               result = emit_bitfield_select(&ctx->ac, src[0], src[1], src[2]);
                break;
-       case nir_op_ubitfield_extract:
-               result = emit_bitfield_extract(&ctx->ac, false, src);
+       case nir_op_ubfe:
+               result = ac_build_bfe(&ctx->ac, src[0], src[1], src[2], false);
                break;
-       case nir_op_bitfield_insert:
-               result = emit_bitfield_insert(&ctx->ac, src[0], src[1], src[2], src[3]);
+       case nir_op_ibfe:
+               result = ac_build_bfe(&ctx->ac, src[0], src[1], src[2], true);
                break;
        case nir_op_bitfield_reverse:
                result = ac_build_bitfield_reverse(&ctx->ac, src[0]);
@@ -864,12 +835,14 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
                        src[i] = ac_to_integer(&ctx->ac, src[i]);
                result = ac_build_gather_values(&ctx->ac, src, num_components);
                break;
+       case nir_op_f2i8:
        case nir_op_f2i16:
        case nir_op_f2i32:
        case nir_op_f2i64:
                src[0] = ac_to_float(&ctx->ac, src[0]);
                result = LLVMBuildFPToSI(ctx->ac.builder, src[0], def_type, "");
                break;
+       case nir_op_f2u8:
        case nir_op_f2u16:
        case nir_op_f2u32:
        case nir_op_f2u64:
@@ -879,13 +852,11 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
        case nir_op_i2f16:
        case nir_op_i2f32:
        case nir_op_i2f64:
-               src[0] = ac_to_integer(&ctx->ac, src[0]);
                result = LLVMBuildSIToFP(ctx->ac.builder, src[0], ac_to_float_type(&ctx->ac, def_type), "");
                break;
        case nir_op_u2f16:
        case nir_op_u2f32:
        case nir_op_u2f64:
-               src[0] = ac_to_integer(&ctx->ac, src[0]);
                result = LLVMBuildUIToFP(ctx->ac.builder, src[0], ac_to_float_type(&ctx->ac, def_type), "");
                break;
        case nir_op_f2f16_rtz:
@@ -906,19 +877,19 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
                else
                        result = LLVMBuildFPTrunc(ctx->ac.builder, src[0], ac_to_float_type(&ctx->ac, def_type), "");
                break;
+       case nir_op_u2u8:
        case nir_op_u2u16:
        case nir_op_u2u32:
        case nir_op_u2u64:
-               src[0] = ac_to_integer(&ctx->ac, src[0]);
                if (ac_get_elem_bits(&ctx->ac, LLVMTypeOf(src[0])) < ac_get_elem_bits(&ctx->ac, def_type))
                        result = LLVMBuildZExt(ctx->ac.builder, src[0], def_type, "");
                else
                        result = LLVMBuildTrunc(ctx->ac.builder, src[0], def_type, "");
                break;
+       case nir_op_i2i8:
        case nir_op_i2i16:
        case nir_op_i2i32:
        case nir_op_i2i64:
-               src[0] = ac_to_integer(&ctx->ac, src[0]);
                if (ac_get_elem_bits(&ctx->ac, LLVMTypeOf(src[0])) < ac_get_elem_bits(&ctx->ac, def_type))
                        result = LLVMBuildSExt(ctx->ac.builder, src[0], def_type, "");
                else
@@ -928,25 +899,18 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
                result = emit_bcsel(&ctx->ac, src[0], src[1], src[2]);
                break;
        case nir_op_find_lsb:
-               src[0] = ac_to_integer(&ctx->ac, src[0]);
                result = ac_find_lsb(&ctx->ac, ctx->ac.i32, src[0]);
                break;
        case nir_op_ufind_msb:
-               src[0] = ac_to_integer(&ctx->ac, src[0]);
                result = ac_build_umsb(&ctx->ac, src[0], ctx->ac.i32);
                break;
        case nir_op_ifind_msb:
-               src[0] = ac_to_integer(&ctx->ac, src[0]);
                result = ac_build_imsb(&ctx->ac, src[0], ctx->ac.i32);
                break;
        case nir_op_uadd_carry:
-               src[0] = ac_to_integer(&ctx->ac, src[0]);
-               src[1] = ac_to_integer(&ctx->ac, src[1]);
                result = emit_uint_carry(&ctx->ac, "llvm.uadd.with.overflow.i32", src[0], src[1]);
                break;
        case nir_op_usub_borrow:
-               src[0] = ac_to_integer(&ctx->ac, src[0]);
-               src[1] = ac_to_integer(&ctx->ac, src[1]);
                result = emit_uint_carry(&ctx->ac, "llvm.usub.with.overflow.i32", src[0], src[1]);
                break;
        case nir_op_b2f16:
@@ -957,30 +921,32 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
        case nir_op_f2b32:
                result = emit_f2b(&ctx->ac, src[0]);
                break;
+       case nir_op_b2i8:
        case nir_op_b2i16:
        case nir_op_b2i32:
        case nir_op_b2i64:
                result = emit_b2i(&ctx->ac, src[0], instr->dest.dest.ssa.bit_size);
                break;
        case nir_op_i2b32:
-               src[0] = ac_to_integer(&ctx->ac, src[0]);
                result = emit_i2b(&ctx->ac, src[0]);
                break;
        case nir_op_fquantize2f16:
                result = emit_f2f16(&ctx->ac, src[0]);
                break;
        case nir_op_umul_high:
-               src[0] = ac_to_integer(&ctx->ac, src[0]);
-               src[1] = ac_to_integer(&ctx->ac, src[1]);
                result = emit_umul_high(&ctx->ac, src[0], src[1]);
                break;
        case nir_op_imul_high:
-               src[0] = ac_to_integer(&ctx->ac, src[0]);
-               src[1] = ac_to_integer(&ctx->ac, src[1]);
                result = emit_imul_high(&ctx->ac, src[0], src[1]);
                break;
        case nir_op_pack_half_2x16:
-               result = emit_pack_half_2x16(&ctx->ac, src[0]);
+               result = emit_pack_2x16(&ctx->ac, src[0], ac_build_cvt_pkrtz_f16);
+               break;
+       case nir_op_pack_snorm_2x16:
+               result = emit_pack_2x16(&ctx->ac, src[0], ac_build_cvt_pknorm_i16);
+               break;
+       case nir_op_pack_unorm_2x16:
+               result = emit_pack_2x16(&ctx->ac, src[0], ac_build_cvt_pknorm_u16);
                break;
        case nir_op_unpack_half_2x16:
                result = emit_unpack_half_2x16(&ctx->ac, src[0]);
@@ -1015,22 +981,52 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
        }
 
        case nir_op_pack_64_2x32_split: {
-               LLVMValueRef tmp = LLVMGetUndef(ctx->ac.v2i32);
-               tmp = ac_build_gather_values(&ctx->ac, src, 2);
+               LLVMValueRef tmp = ac_build_gather_values(&ctx->ac, src, 2);
                result = LLVMBuildBitCast(ctx->ac.builder, tmp, ctx->ac.i64, "");
                break;
        }
 
+       case nir_op_pack_32_2x16_split: {
+               LLVMValueRef tmp = ac_build_gather_values(&ctx->ac, src, 2);
+               result = LLVMBuildBitCast(ctx->ac.builder, tmp, ctx->ac.i32, "");
+               break;
+       }
+
+       case nir_op_unpack_32_2x16_split_x: {
+               LLVMValueRef tmp = LLVMBuildBitCast(ctx->ac.builder, src[0],
+                                                   ctx->ac.v2i16,
+                                                   "");
+               result = LLVMBuildExtractElement(ctx->ac.builder, tmp,
+                                                ctx->ac.i32_0, "");
+               break;
+       }
+
+       case nir_op_unpack_32_2x16_split_y: {
+               LLVMValueRef tmp = LLVMBuildBitCast(ctx->ac.builder, src[0],
+                                                   ctx->ac.v2i16,
+                                                   "");
+               result = LLVMBuildExtractElement(ctx->ac.builder, tmp,
+                                                ctx->ac.i32_1, "");
+               break;
+       }
+
        case nir_op_cube_face_coord: {
                src[0] = ac_to_float(&ctx->ac, src[0]);
                LLVMValueRef results[2];
                LLVMValueRef in[3];
                for (unsigned chan = 0; chan < 3; chan++)
                        in[chan] = ac_llvm_extract_elem(&ctx->ac, src[0], chan);
-               results[0] = ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.cubetc",
+               results[0] = ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.cubesc",
                                                ctx->ac.f32, in, 3, AC_FUNC_ATTR_READNONE);
-               results[1] = ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.cubesc",
+               results[1] = ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.cubetc",
                                                ctx->ac.f32, in, 3, AC_FUNC_ATTR_READNONE);
+               LLVMValueRef ma = ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.cubema",
+                                                    ctx->ac.f32, in, 3, AC_FUNC_ATTR_READNONE);
+               results[0] = ac_build_fdiv(&ctx->ac, results[0], ma);
+               results[1] = ac_build_fdiv(&ctx->ac, results[1], ma);
+               LLVMValueRef offset = LLVMConstReal(ctx->ac.f32, 0.5);
+               results[0] = LLVMBuildFAdd(ctx->ac.builder, results[0], offset, "");
+               results[1] = LLVMBuildFAdd(ctx->ac.builder, results[1], offset, "");
                result = ac_build_gather_values(&ctx->ac, results, 2);
                break;
        }
@@ -1052,12 +1048,12 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
                                                ac_to_float_type(&ctx->ac, def_type), result, src[2]);
                break;
        case nir_op_umin3:
-               result = emit_minmax_int(&ctx->ac, LLVMIntULT, src[0], src[1]);
-               result = emit_minmax_int(&ctx->ac, LLVMIntULT, result, src[2]);
+               result = ac_build_umin(&ctx->ac, src[0], src[1]);
+               result = ac_build_umin(&ctx->ac, result, src[2]);
                break;
        case nir_op_imin3:
-               result = emit_minmax_int(&ctx->ac, LLVMIntSLT, src[0], src[1]);
-               result = emit_minmax_int(&ctx->ac, LLVMIntSLT, result, src[2]);
+               result = ac_build_imin(&ctx->ac, src[0], src[1]);
+               result = ac_build_imin(&ctx->ac, result, src[2]);
                break;
        case nir_op_fmax3:
                result = emit_intrin_2f_param(&ctx->ac, "llvm.maxnum",
@@ -1066,36 +1062,33 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
                                                ac_to_float_type(&ctx->ac, def_type), result, src[2]);
                break;
        case nir_op_umax3:
-               result = emit_minmax_int(&ctx->ac, LLVMIntUGT, src[0], src[1]);
-               result = emit_minmax_int(&ctx->ac, LLVMIntUGT, result, src[2]);
+               result = ac_build_umax(&ctx->ac, src[0], src[1]);
+               result = ac_build_umax(&ctx->ac, result, src[2]);
                break;
        case nir_op_imax3:
-               result = emit_minmax_int(&ctx->ac, LLVMIntSGT, src[0], src[1]);
-               result = emit_minmax_int(&ctx->ac, LLVMIntSGT, result, src[2]);
+               result = ac_build_imax(&ctx->ac, src[0], src[1]);
+               result = ac_build_imax(&ctx->ac, result, src[2]);
                break;
        case nir_op_fmed3: {
-               LLVMValueRef tmp1 = emit_intrin_2f_param(&ctx->ac, "llvm.minnum",
-                                               ac_to_float_type(&ctx->ac, def_type), src[0], src[1]);
-               LLVMValueRef tmp2 = emit_intrin_2f_param(&ctx->ac, "llvm.maxnum",
-                                               ac_to_float_type(&ctx->ac, def_type), src[0], src[1]);
-               tmp2 = emit_intrin_2f_param(&ctx->ac, "llvm.minnum",
-                                               ac_to_float_type(&ctx->ac, def_type), tmp2, src[2]);
-               result = emit_intrin_2f_param(&ctx->ac, "llvm.maxnum",
-                                               ac_to_float_type(&ctx->ac, def_type), tmp1, tmp2);
+               src[0] = ac_to_float(&ctx->ac, src[0]);
+               src[1] = ac_to_float(&ctx->ac, src[1]);
+               src[2] = ac_to_float(&ctx->ac, src[2]);
+               result = ac_build_fmed3(&ctx->ac, src[0], src[1], src[2],
+                                       instr->dest.dest.ssa.bit_size);
                break;
        }
        case nir_op_imed3: {
-               LLVMValueRef tmp1 = emit_minmax_int(&ctx->ac, LLVMIntSLT, src[0], src[1]);
-               LLVMValueRef tmp2 = emit_minmax_int(&ctx->ac, LLVMIntSGT, src[0], src[1]);
-               tmp2 = emit_minmax_int(&ctx->ac, LLVMIntSLT, tmp2, src[2]);
-               result = emit_minmax_int(&ctx->ac, LLVMIntSGT, tmp1, tmp2);
+               LLVMValueRef tmp1 = ac_build_imin(&ctx->ac, src[0], src[1]);
+               LLVMValueRef tmp2 = ac_build_imax(&ctx->ac, src[0], src[1]);
+               tmp2 = ac_build_imin(&ctx->ac, tmp2, src[2]);
+               result = ac_build_imax(&ctx->ac, tmp1, tmp2);
                break;
        }
        case nir_op_umed3: {
-               LLVMValueRef tmp1 = emit_minmax_int(&ctx->ac, LLVMIntULT, src[0], src[1]);
-               LLVMValueRef tmp2 = emit_minmax_int(&ctx->ac, LLVMIntUGT, src[0], src[1]);
-               tmp2 = emit_minmax_int(&ctx->ac, LLVMIntULT, tmp2, src[2]);
-               result = emit_minmax_int(&ctx->ac, LLVMIntUGT, tmp1, tmp2);
+               LLVMValueRef tmp1 = ac_build_umin(&ctx->ac, src[0], src[1]);
+               LLVMValueRef tmp2 = ac_build_umax(&ctx->ac, src[0], src[1]);
+               tmp2 = ac_build_umin(&ctx->ac, tmp2, src[2]);
+               result = ac_build_umax(&ctx->ac, tmp1, tmp2);
                break;
        }
 
@@ -1124,19 +1117,19 @@ static void visit_load_const(struct ac_nir_context *ctx,
                switch (instr->def.bit_size) {
                case 8:
                        values[i] = LLVMConstInt(element_type,
-                                                instr->value.u8[i], false);
+                                                instr->value[i].u8, false);
                        break;
                case 16:
                        values[i] = LLVMConstInt(element_type,
-                                                instr->value.u16[i], false);
+                                                instr->value[i].u16, false);
                        break;
                case 32:
                        values[i] = LLVMConstInt(element_type,
-                                                instr->value.u32[i], false);
+                                                instr->value[i].u32, false);
                        break;
                case 64:
                        values[i] = LLVMConstInt(element_type,
-                                                instr->value.u64[i], false);
+                                                instr->value[i].u64, false);
                        break;
                default:
                        fprintf(stderr,
@@ -1160,9 +1153,9 @@ get_buffer_size(struct ac_nir_context *ctx, LLVMValueRef descriptor, bool in_ele
                LLVMBuildExtractElement(ctx->ac.builder, descriptor,
                                        LLVMConstInt(ctx->ac.i32, 2, false), "");
 
-       /* VI only */
-       if (ctx->ac.chip_class == VI && in_elements) {
-               /* On VI, the descriptor contains the size in bytes,
+       /* GFX8 only */
+       if (ctx->ac.chip_class == GFX8 && in_elements) {
+               /* On GFX8, the descriptor contains the size in bytes,
                 * but TXQ must return the size in elements.
                 * The stride is always non-zero for resources using TXQ.
                 */
@@ -1257,7 +1250,7 @@ static LLVMValueRef lower_gather4_integer(struct ac_llvm_context *ctx,
                                              LLVMConstInt(ctx->i32, 0x14000000, false), "");
 
                /* replace the NUM FORMAT in the descriptor */
-               tmp2 = LLVMBuildAnd(ctx->builder, tmp2, LLVMConstInt(ctx->i32, C_008F14_NUM_FORMAT_GFX6, false), "");
+               tmp2 = LLVMBuildAnd(ctx->builder, tmp2, LLVMConstInt(ctx->i32, C_008F14_NUM_FORMAT, false), "");
                tmp2 = LLVMBuildOr(ctx->builder, tmp2, tmp, "");
 
                args->resource = LLVMBuildInsertElement(ctx->builder, args->resource, tmp2, ctx->i32_1, "");
@@ -1321,14 +1314,14 @@ static LLVMValueRef build_tex_intrinsic(struct ac_nir_context *ctx,
                                                                     args->coords[0],
                                                                     ctx->ac.i32_0,
                                                                     util_last_bit(mask),
-                                                                    false, true);
+                                                                    0, true);
                } else {
                        return ac_build_buffer_load_format(&ctx->ac,
                                                           args->resource,
                                                           args->coords[0],
                                                           ctx->ac.i32_0,
                                                           util_last_bit(mask),
-                                                          false, true);
+                                                          0, true);
                }
        }
 
@@ -1367,7 +1360,7 @@ static LLVMValueRef build_tex_intrinsic(struct ac_nir_context *ctx,
                break;
        }
 
-       if (instr->op == nir_texop_tg4 && ctx->ac.chip_class <= VI) {
+       if (instr->op == nir_texop_tg4 && ctx->ac.chip_class <= GFX8) {
                nir_deref_instr *texture_deref_instr = get_tex_texture_deref(instr);
                nir_variable *var = nir_deref_instr_get_variable(texture_deref_instr);
                const struct glsl_type *type = glsl_without_array(var->type);
@@ -1378,7 +1371,7 @@ static LLVMValueRef build_tex_intrinsic(struct ac_nir_context *ctx,
        }
 
        /* Fixup for GFX9 which allocates 1D textures as 2D. */
-       if (instr->op == nir_texop_lod && ctx->ac.chip_class >= GFX9) {
+       if (instr->op == nir_texop_lod && ctx->ac.chip_class == GFX9) {
                if ((args->dim == ac_image_2darray ||
                     args->dim == ac_image_2d) && !args->coords[1]) {
                        args->coords[1] = ctx->ac.i32_0;
@@ -1386,6 +1379,22 @@ static LLVMValueRef build_tex_intrinsic(struct ac_nir_context *ctx,
        }
 
        args->attributes = AC_FUNC_ATTR_READNONE;
+       bool cs_derivs = ctx->stage == MESA_SHADER_COMPUTE &&
+                        ctx->info->cs.derivative_group != DERIVATIVE_GROUP_NONE;
+       if (ctx->stage == MESA_SHADER_FRAGMENT || cs_derivs) {
+               /* Prevent texture instructions with implicit derivatives from being
+                * sinked into branches. */
+               switch (instr->op) {
+               case nir_texop_tex:
+               case nir_texop_txb:
+               case nir_texop_lod:
+                       args->attributes |= AC_FUNC_ATTR_CONVERGENT;
+                       break;
+               default:
+                       break;
+               }
+       }
+
        return ac_build_image_opcode(&ctx->ac, args);
 }
 
@@ -1430,9 +1439,32 @@ static LLVMValueRef visit_load_push_constant(struct ac_nir_context *ctx,
                }
        }
 
-       ptr = ac_build_gep0(&ctx->ac, ctx->abi->push_constants, addr);
+       ptr = LLVMBuildGEP(ctx->ac.builder, ctx->abi->push_constants, &addr, 1, "");
 
-       if (instr->dest.ssa.bit_size == 16) {
+       if (instr->dest.ssa.bit_size == 8) {
+               unsigned load_dwords = instr->dest.ssa.num_components > 1 ? 2 : 1;
+               LLVMTypeRef vec_type = LLVMVectorType(LLVMInt8TypeInContext(ctx->ac.context), 4 * load_dwords);
+               ptr = ac_cast_ptr(&ctx->ac, ptr, vec_type);
+               LLVMValueRef res = LLVMBuildLoad(ctx->ac.builder, ptr, "");
+
+               LLVMValueRef params[3];
+               if (load_dwords > 1) {
+                       LLVMValueRef res_vec = LLVMBuildBitCast(ctx->ac.builder, res, LLVMVectorType(ctx->ac.i32, 2), "");
+                       params[0] = LLVMBuildExtractElement(ctx->ac.builder, res_vec, LLVMConstInt(ctx->ac.i32, 1, false), "");
+                       params[1] = LLVMBuildExtractElement(ctx->ac.builder, res_vec, LLVMConstInt(ctx->ac.i32, 0, false), "");
+               } else {
+                       res = LLVMBuildBitCast(ctx->ac.builder, res, ctx->ac.i32, "");
+                       params[0] = ctx->ac.i32_0;
+                       params[1] = res;
+               }
+               params[2] = addr;
+               res = ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.alignbyte", ctx->ac.i32, params, 3, 0);
+
+               res = LLVMBuildTrunc(ctx->ac.builder, res, LLVMIntTypeInContext(ctx->ac.context, instr->dest.ssa.num_components * 8), "");
+               if (instr->dest.ssa.num_components > 1)
+                       res = LLVMBuildBitCast(ctx->ac.builder, res, LLVMVectorType(LLVMInt8TypeInContext(ctx->ac.context), instr->dest.ssa.num_components), "");
+               return res;
+       } else if (instr->dest.ssa.bit_size == 16) {
                unsigned load_dwords = instr->dest.ssa.num_components / 2 + 1;
                LLVMTypeRef vec_type = LLVMVectorType(LLVMInt16TypeInContext(ctx->ac.context), 2 * load_dwords);
                ptr = ac_cast_ptr(&ctx->ac, ptr, vec_type);
@@ -1503,11 +1535,11 @@ static unsigned get_cache_policy(struct ac_nir_context *ctx,
 {
        unsigned cache_policy = 0;
 
-       /* SI has a TC L1 bug causing corruption of 8bit/16bit stores.  All
+       /* GFX6 has a TC L1 bug causing corruption of 8bit/16bit stores.  All
         * store opcodes not aligned to a dword are affected. The only way to
         * get unaligned stores is through shader images.
         */
-       if (((may_store_unaligned && ctx->ac.chip_class == SI) ||
+       if (((may_store_unaligned && ctx->ac.chip_class == GFX6) ||
             /* If this is write-only, don't keep data in L1 to prevent
              * evicting L1 cache lines that may be needed by other
              * instructions.
@@ -1517,24 +1549,25 @@ static unsigned get_cache_policy(struct ac_nir_context *ctx,
                cache_policy |= ac_glc;
        }
 
+       if (access & ACCESS_STREAM_CACHE_POLICY)
+               cache_policy |= ac_slc;
+
        return cache_policy;
 }
 
 static void visit_store_ssbo(struct ac_nir_context *ctx,
                              nir_intrinsic_instr *instr)
 {
-       const char *store_name;
        LLVMValueRef src_data = get_src(ctx, instr->src[0]);
        int elem_size_bytes = ac_get_elem_bits(&ctx->ac, LLVMTypeOf(src_data)) / 8;
        unsigned writemask = nir_intrinsic_write_mask(instr);
        enum gl_access_qualifier access = nir_intrinsic_access(instr);
        bool writeonly_memory = access & ACCESS_NON_READABLE;
        unsigned cache_policy = get_cache_policy(ctx, access, false, writeonly_memory);
-       LLVMValueRef glc = (cache_policy & ac_glc) ? ctx->ac.i1true : ctx->ac.i1false;
 
        LLVMValueRef rsrc = ctx->abi->load_ssbo(ctx->abi,
                                        get_src(ctx, instr->src[1]), true);
-       LLVMValueRef base_data = ac_to_float(&ctx->ac, src_data);
+       LLVMValueRef base_data = src_data;
        base_data = ac_trim_vector(&ctx->ac, base_data, instr->num_components);
        LLVMValueRef base_offset = get_src(ctx, instr->src[2]);
 
@@ -1545,9 +1578,10 @@ static void visit_store_ssbo(struct ac_nir_context *ctx,
 
                u_bit_scan_consecutive_range(&writemask, &start, &count);
 
-               /* Due to an LLVM limitation, split 3-element writes
-                * into a 2-element and a 1-element write. */
-               if (count == 3) {
+               /* Due to an LLVM limitation with LLVM < 9, split 3-element
+                * writes into a 2-element and a 1-element write. */
+               if (count == 3 &&
+                   (elem_size_bytes != 4 || !ac_has_vec3_support(ctx->ac.chip_class, false))) {
                        writemask |= 1 << (start + 2);
                        count = 2;
                }
@@ -1572,26 +1606,14 @@ static void visit_store_ssbo(struct ac_nir_context *ctx,
                offset = LLVMBuildAdd(ctx->ac.builder, base_offset,
                                      LLVMConstInt(ctx->ac.i32, start * elem_size_bytes, false), "");
 
-               if (num_bytes == 2) {
-                       store_name = "llvm.amdgcn.tbuffer.store.i32";
-                       data_type = ctx->ac.i32;
-                       data = LLVMBuildBitCast(ctx->ac.builder, data, ctx->ac.i16, "");
-                       data = LLVMBuildZExt(ctx->ac.builder, data, data_type, "");
-                       LLVMValueRef tbuffer_params[] = {
-                               data,
-                               rsrc,
-                               ctx->ac.i32_0, /* vindex */
-                               offset,        /* voffset */
-                               ctx->ac.i32_0,
-                               ctx->ac.i32_0,
-                               LLVMConstInt(ctx->ac.i32, 2, false), // dfmt (= 16bit)
-                               LLVMConstInt(ctx->ac.i32, 4, false), // nfmt (= uint)
-                               glc,
-                               ctx->ac.i1false,
-                       };
-                       ac_build_intrinsic(&ctx->ac, store_name,
-                                          ctx->ac.voidt, tbuffer_params, 10,
-                                          ac_get_store_intr_attribs(writeonly_memory));
+               if (num_bytes == 1) {
+                       ac_build_tbuffer_store_byte(&ctx->ac, rsrc, data,
+                                                   offset, ctx->ac.i32_0,
+                                                   cache_policy);
+               } else if (num_bytes == 2) {
+                       ac_build_tbuffer_store_short(&ctx->ac, rsrc, data,
+                                                    offset, ctx->ac.i32_0,
+                                                    cache_policy);
                } else {
                        int num_channels = num_bytes / 4;
 
@@ -1599,6 +1621,9 @@ static void visit_store_ssbo(struct ac_nir_context *ctx,
                        case 16: /* v4f32 */
                                data_type = ctx->ac.v4f32;
                                break;
+                       case 12: /* v3f32 */
+                               data_type = ctx->ac.v3f32;
+                               break;
                        case 8: /* v2f32 */
                                data_type = ctx->ac.v2f32;
                                break;
@@ -1613,85 +1638,153 @@ static void visit_store_ssbo(struct ac_nir_context *ctx,
                        ac_build_buffer_store_dword(&ctx->ac, rsrc, data,
                                                    num_channels, offset,
                                                    ctx->ac.i32_0, 0,
-                                                   cache_policy & ac_glc,
-                                                   false, writeonly_memory,
-                                                   false);
+                                                   cache_policy, false);
                }
        }
 }
 
+static LLVMValueRef emit_ssbo_comp_swap_64(struct ac_nir_context *ctx,
+                                           LLVMValueRef descriptor,
+                                          LLVMValueRef offset,
+                                          LLVMValueRef compare,
+                                          LLVMValueRef exchange)
+{
+       LLVMBasicBlockRef start_block = NULL, then_block = NULL;
+       if (ctx->abi->robust_buffer_access) {
+               LLVMValueRef size = ac_llvm_extract_elem(&ctx->ac, descriptor, 2);
+
+               LLVMValueRef cond = LLVMBuildICmp(ctx->ac.builder, LLVMIntULT, offset, size, "");
+               start_block = LLVMGetInsertBlock(ctx->ac.builder);
+
+               ac_build_ifcc(&ctx->ac, cond, -1);
+
+               then_block = LLVMGetInsertBlock(ctx->ac.builder);
+       }
+
+       LLVMValueRef ptr_parts[2] = {
+               ac_llvm_extract_elem(&ctx->ac, descriptor, 0),
+               LLVMBuildAnd(ctx->ac.builder,
+                            ac_llvm_extract_elem(&ctx->ac, descriptor, 1),
+                            LLVMConstInt(ctx->ac.i32, 65535, 0), "")
+       };
+
+       ptr_parts[1] = LLVMBuildTrunc(ctx->ac.builder, ptr_parts[1], ctx->ac.i16, "");
+       ptr_parts[1] = LLVMBuildSExt(ctx->ac.builder, ptr_parts[1], ctx->ac.i32, "");
+
+       offset = LLVMBuildZExt(ctx->ac.builder, offset, ctx->ac.i64, "");
+
+       LLVMValueRef ptr = ac_build_gather_values(&ctx->ac, ptr_parts, 2);
+       ptr = LLVMBuildBitCast(ctx->ac.builder, ptr, ctx->ac.i64, "");
+       ptr = LLVMBuildAdd(ctx->ac.builder, ptr, offset, "");
+       ptr = LLVMBuildIntToPtr(ctx->ac.builder, ptr, LLVMPointerType(ctx->ac.i64, AC_ADDR_SPACE_GLOBAL), "");
+
+       LLVMValueRef result = ac_build_atomic_cmp_xchg(&ctx->ac, ptr, compare, exchange, "singlethread-one-as");
+       result = LLVMBuildExtractValue(ctx->ac.builder, result, 0, "");
+
+       if (ctx->abi->robust_buffer_access) {
+               ac_build_endif(&ctx->ac, -1);
+
+               LLVMBasicBlockRef incoming_blocks[2] = {
+                       start_block,
+                       then_block,
+               };
+
+               LLVMValueRef incoming_values[2] = {
+                       LLVMConstInt(ctx->ac.i64, 0, 0),
+                       result,
+               };
+               LLVMValueRef ret = LLVMBuildPhi(ctx->ac.builder, ctx->ac.i64, "");
+               LLVMAddIncoming(ret, incoming_values, incoming_blocks, 2);
+               return ret;
+       } else {
+               return result;
+       }
+}
+
 static LLVMValueRef visit_atomic_ssbo(struct ac_nir_context *ctx,
                                       const nir_intrinsic_instr *instr)
 {
-       const char *atomic_name;
-       char intrinsic_name[64];
-       LLVMValueRef params[7];
+       LLVMTypeRef return_type = LLVMTypeOf(get_src(ctx, instr->src[2]));
+       const char *op;
+       char name[64], type[8];
+       LLVMValueRef params[6], descriptor;
        int arg_count = 0;
-       int length;
 
        switch (instr->intrinsic) {
        case nir_intrinsic_ssbo_atomic_add:
-               atomic_name = "add";
+               op = "add";
                break;
        case nir_intrinsic_ssbo_atomic_imin:
-               atomic_name = "smin";
+               op = "smin";
                break;
        case nir_intrinsic_ssbo_atomic_umin:
-               atomic_name = "umin";
+               op = "umin";
                break;
        case nir_intrinsic_ssbo_atomic_imax:
-               atomic_name = "smax";
+               op = "smax";
                break;
        case nir_intrinsic_ssbo_atomic_umax:
-               atomic_name = "umax";
+               op = "umax";
                break;
        case nir_intrinsic_ssbo_atomic_and:
-               atomic_name = "and";
+               op = "and";
                break;
        case nir_intrinsic_ssbo_atomic_or:
-               atomic_name = "or";
+               op = "or";
                break;
        case nir_intrinsic_ssbo_atomic_xor:
-               atomic_name = "xor";
+               op = "xor";
                break;
        case nir_intrinsic_ssbo_atomic_exchange:
-               atomic_name = "swap";
+               op = "swap";
                break;
        case nir_intrinsic_ssbo_atomic_comp_swap:
-               atomic_name = "cmpswap";
+               op = "cmpswap";
                break;
        default:
                abort();
        }
 
+       descriptor = ctx->abi->load_ssbo(ctx->abi,
+                                        get_src(ctx, instr->src[0]),
+                                        true);
+
+       if (instr->intrinsic == nir_intrinsic_ssbo_atomic_comp_swap &&
+           return_type == ctx->ac.i64) {
+               return emit_ssbo_comp_swap_64(ctx, descriptor,
+                                             get_src(ctx, instr->src[1]),
+                                             get_src(ctx, instr->src[2]),
+                                             get_src(ctx, instr->src[3]));
+       }
        if (instr->intrinsic == nir_intrinsic_ssbo_atomic_comp_swap) {
                params[arg_count++] = ac_llvm_extract_elem(&ctx->ac, get_src(ctx, instr->src[3]), 0);
        }
        params[arg_count++] = ac_llvm_extract_elem(&ctx->ac, get_src(ctx, instr->src[2]), 0);
-       params[arg_count++] = ctx->abi->load_ssbo(ctx->abi,
-                                                get_src(ctx, instr->src[0]),
-                                                true);
+       params[arg_count++] = descriptor;
 
-       if (HAVE_LLVM >= 0x0800) {
+       if (HAVE_LLVM >= 0x900) {
+               /* XXX: The new raw/struct atomic intrinsics are buggy with
+                * LLVM 8, see r358579.
+                */
                params[arg_count++] = get_src(ctx, instr->src[1]); /* voffset */
                params[arg_count++] = ctx->ac.i32_0; /* soffset */
                params[arg_count++] = ctx->ac.i32_0; /* slc */
 
-               length = snprintf(intrinsic_name, sizeof(intrinsic_name),
-                                 "llvm.amdgcn.raw.buffer.atomic.%s.i32",
-                                 atomic_name);
+               ac_build_type_name_for_intr(return_type, type, sizeof(type));
+               snprintf(name, sizeof(name),
+                        "llvm.amdgcn.raw.buffer.atomic.%s.%s", op, type);
        } else {
                params[arg_count++] = ctx->ac.i32_0; /* vindex */
                params[arg_count++] = get_src(ctx, instr->src[1]); /* voffset */
                params[arg_count++] = ctx->ac.i1false; /* slc */
 
-               length = snprintf(intrinsic_name, sizeof(intrinsic_name),
-                                 "llvm.amdgcn.buffer.atomic.%s", atomic_name);
+               assert(return_type == ctx->ac.i32);
+               snprintf(name, sizeof(name),
+                        "llvm.amdgcn.buffer.atomic.%s", op);
        }
 
-       assert(length < sizeof(intrinsic_name));
-       return ac_build_intrinsic(&ctx->ac, intrinsic_name, ctx->ac.i32,
-                                 params, arg_count, 0);
+       return ac_build_intrinsic(&ctx->ac, name, return_type, params,
+                                 arg_count, 0);
 }
 
 static LLVMValueRef visit_load_buffer(struct ac_nir_context *ctx,
@@ -1722,20 +1815,28 @@ static LLVMValueRef visit_load_buffer(struct ac_nir_context *ctx,
                LLVMValueRef immoffset = LLVMConstInt(ctx->ac.i32, i * elem_size_bytes, false);
 
                LLVMValueRef ret;
-               if (load_bytes == 2) {
-                       ret = ac_build_tbuffer_load_short(&ctx->ac,
+
+               if (load_bytes == 1) {
+                       ret = ac_build_tbuffer_load_byte(&ctx->ac,
                                                          rsrc,
                                                          offset,
                                                          ctx->ac.i32_0,
                                                          immoffset,
-                                                         cache_policy & ac_glc);
+                                                         cache_policy);
+               } else if (load_bytes == 2) {
+                       ret = ac_build_tbuffer_load_short(&ctx->ac,
+                                                        rsrc,
+                                                        offset,
+                                                        ctx->ac.i32_0,
+                                                        immoffset,
+                                                        cache_policy);
                } else {
                        int num_channels = util_next_power_of_two(load_bytes) / 4;
+                       bool can_speculate = access & ACCESS_CAN_REORDER;
 
                        ret = ac_build_buffer_load(&ctx->ac, rsrc, num_channels,
                                                   vindex, offset, immoffset, 0,
-                                                  cache_policy & ac_glc, 0,
-                                                  false, false);
+                                                  cache_policy, can_speculate, false);
                }
 
                LLVMTypeRef byte_vec = LLVMVectorType(ctx->ac.i8, ac_get_type_size(LLVMTypeOf(ret)));
@@ -1768,20 +1869,34 @@ static LLVMValueRef visit_load_ubo_buffer(struct ac_nir_context *ctx,
        if (instr->dest.ssa.bit_size == 64)
                num_components *= 2;
 
-       if (instr->dest.ssa.bit_size == 16) {
+       if (instr->dest.ssa.bit_size == 16 || instr->dest.ssa.bit_size == 8) {
+               unsigned load_bytes = instr->dest.ssa.bit_size / 8;
                LLVMValueRef results[num_components];
                for (unsigned i = 0; i < num_components; ++i) {
-                       results[i] = ac_build_tbuffer_load_short(&ctx->ac,
-                                                                rsrc,
-                                                                offset,
-                                                                ctx->ac.i32_0,
-                                                                LLVMConstInt(ctx->ac.i32, 2 * i, 0),
-                                                                false);
+                       LLVMValueRef immoffset = LLVMConstInt(ctx->ac.i32,
+                                                             load_bytes * i, 0);
+
+                       if (load_bytes == 1) {
+                               results[i] = ac_build_tbuffer_load_byte(&ctx->ac,
+                                                                       rsrc,
+                                                                       offset,
+                                                                       ctx->ac.i32_0,
+                                                                       immoffset,
+                                                                       0);
+                       } else {
+                               assert(load_bytes == 2);
+                               results[i] = ac_build_tbuffer_load_short(&ctx->ac,
+                                                                        rsrc,
+                                                                        offset,
+                                                                        ctx->ac.i32_0,
+                                                                        immoffset,
+                                                                        0);
+                       }
                }
                ret = ac_build_gather_values(&ctx->ac, results, num_components);
        } else {
                ret = ac_build_buffer_load(&ctx->ac, rsrc, num_components, NULL, offset,
-                                          NULL, 0, false, false, true, true);
+                                          NULL, 0, 0, true, true);
 
                ret = ac_trim_vector(&ctx->ac, ret, num_components);
        }
@@ -1808,9 +1923,7 @@ get_deref_offset(struct ac_nir_context *ctx, nir_deref_instr *instr,
                        if (vertex_index_out)
                                *vertex_index_out = 0;
                } else {
-                       nir_const_value *v = nir_src_as_const_value(path.path[idx_lvl]->arr.index);
-                       assert(v);
-                       *vertex_index_out = v->u32[0];
+                       *vertex_index_out = nir_src_as_uint(path.path[idx_lvl]->arr.index);
                }
                ++idx_lvl;
        }
@@ -1820,9 +1933,7 @@ get_deref_offset(struct ac_nir_context *ctx, nir_deref_instr *instr,
 
        if (var->data.compact) {
                assert(instr->deref_type == nir_deref_type_array);
-               nir_const_value *v = nir_src_as_const_value(instr->arr.index);
-               assert(v);
-               const_offset = v->u32[0];
+               const_offset = nir_src_as_uint(instr->arr.index);
                goto out;
        }
 
@@ -2014,6 +2125,11 @@ static LLVMValueRef visit_load_var(struct ac_nir_context *ctx,
                        return load_tess_varyings(ctx, instr, false);
                }
 
+               if (ctx->stage == MESA_SHADER_FRAGMENT &&
+                   var->data.fb_fetch_output &&
+                   ctx->abi->emit_fbfetch)
+                       return ctx->abi->emit_fbfetch(ctx->abi);
+
                for (unsigned chan = comp; chan < ve + comp; chan++) {
                        if (indir_index) {
                                unsigned count = glsl_count_attribute_slots(
@@ -2254,78 +2370,18 @@ static int image_type_to_components_count(enum glsl_sampler_dim dim, bool array)
        return 0;
 }
 
-
-/* Adjust the sample index according to FMASK.
- *
- * For uncompressed MSAA surfaces, FMASK should return 0x76543210,
- * which is the identity mapping. Each nibble says which physical sample
- * should be fetched to get that sample.
- *
- * For example, 0x11111100 means there are only 2 samples stored and
- * the second sample covers 3/4 of the pixel. When reading samples 0
- * and 1, return physical sample 0 (determined by the first two 0s
- * in FMASK), otherwise return physical sample 1.
- *
- * The sample index should be adjusted as follows:
- *   sample_index = (fmask >> (sample_index * 4)) & 0xF;
- */
 static LLVMValueRef adjust_sample_index_using_fmask(struct ac_llvm_context *ctx,
                                                    LLVMValueRef coord_x, LLVMValueRef coord_y,
                                                    LLVMValueRef coord_z,
                                                    LLVMValueRef sample_index,
                                                    LLVMValueRef fmask_desc_ptr)
 {
-       struct ac_image_args args = {0};
-       LLVMValueRef res;
-
-       args.coords[0] = coord_x;
-       args.coords[1] = coord_y;
-       if (coord_z)
-               args.coords[2] = coord_z;
-
-       args.opcode = ac_image_load;
-       args.dim = coord_z ? ac_image_2darray : ac_image_2d;
-       args.resource = fmask_desc_ptr;
-       args.dmask = 0xf;
-       args.attributes = AC_FUNC_ATTR_READNONE;
-
-       res = ac_build_image_opcode(ctx, &args);
-
-       res = ac_to_integer(ctx, res);
-       LLVMValueRef four = LLVMConstInt(ctx->i32, 4, false);
-       LLVMValueRef F = LLVMConstInt(ctx->i32, 0xf, false);
-
-       LLVMValueRef fmask = LLVMBuildExtractElement(ctx->builder,
-                                                    res,
-                                                    ctx->i32_0, "");
+       unsigned sample_chan = coord_z ? 3 : 2;
+       LLVMValueRef addr[4] = {coord_x, coord_y, coord_z};
+       addr[sample_chan] = sample_index;
 
-       LLVMValueRef sample_index4 =
-               LLVMBuildMul(ctx->builder, sample_index, four, "");
-       LLVMValueRef shifted_fmask =
-               LLVMBuildLShr(ctx->builder, fmask, sample_index4, "");
-       LLVMValueRef final_sample =
-               LLVMBuildAnd(ctx->builder, shifted_fmask, F, "");
-
-       /* Don't rewrite the sample index if WORD1.DATA_FORMAT of the FMASK
-        * resource descriptor is 0 (invalid),
-        */
-       LLVMValueRef fmask_desc =
-               LLVMBuildBitCast(ctx->builder, fmask_desc_ptr,
-                                ctx->v8i32, "");
-
-       LLVMValueRef fmask_word1 =
-               LLVMBuildExtractElement(ctx->builder, fmask_desc,
-                                       ctx->i32_1, "");
-
-       LLVMValueRef word1_is_nonzero =
-               LLVMBuildICmp(ctx->builder, LLVMIntNE,
-                             fmask_word1, ctx->i32_0, "");
-
-       /* Replace the MSAA sample index. */
-       sample_index =
-               LLVMBuildSelect(ctx->builder, word1_is_nonzero,
-                               final_sample, sample_index, "");
-       return sample_index;
+       ac_apply_fmask_to_sample(ctx, fmask_desc_ptr, addr, coord_z != NULL);
+       return addr[sample_chan];
 }
 
 static nir_deref_instr *get_image_deref(const nir_intrinsic_instr *instr)
@@ -2339,15 +2395,19 @@ static LLVMValueRef get_image_descriptor(struct ac_nir_context *ctx,
                                          enum ac_descriptor_type desc_type,
                                          bool write)
 {
-       return get_sampler_desc(ctx, nir_instr_as_deref(instr->src[0].ssa->parent_instr), desc_type, NULL, true, write);
+       nir_deref_instr *deref_instr =
+               instr->src[0].ssa->parent_instr->type == nir_instr_type_deref ?
+               nir_instr_as_deref(instr->src[0].ssa->parent_instr) : NULL;
+
+       return get_sampler_desc(ctx, deref_instr, desc_type, &instr->instr, true, write);
 }
 
 static void get_image_coords(struct ac_nir_context *ctx,
                             const nir_intrinsic_instr *instr,
-                            struct ac_image_args *args)
+                            struct ac_image_args *args,
+                            enum glsl_sampler_dim dim,
+                            bool is_array)
 {
-       const struct glsl_type *type = get_image_deref(instr)->type;
-
        LLVMValueRef src0 = get_src(ctx, instr->src[1]);
        LLVMValueRef masks[] = {
                LLVMConstInt(ctx->ac.i32, 0, false), LLVMConstInt(ctx->ac.i32, 1, false),
@@ -2356,18 +2416,17 @@ static void get_image_coords(struct ac_nir_context *ctx,
        LLVMValueRef sample_index = ac_llvm_extract_elem(&ctx->ac, get_src(ctx, instr->src[2]), 0);
 
        int count;
-       enum glsl_sampler_dim dim = glsl_get_sampler_dim(type);
-       bool is_array = glsl_sampler_type_is_array(type);
-       bool add_frag_pos = (dim == GLSL_SAMPLER_DIM_SUBPASS ||
-                            dim == GLSL_SAMPLER_DIM_SUBPASS_MS);
+       ASSERTED bool add_frag_pos = (dim == GLSL_SAMPLER_DIM_SUBPASS ||
+                                         dim == GLSL_SAMPLER_DIM_SUBPASS_MS);
        bool is_ms = (dim == GLSL_SAMPLER_DIM_MS ||
                      dim == GLSL_SAMPLER_DIM_SUBPASS_MS);
-       bool gfx9_1d = ctx->ac.chip_class >= GFX9 && dim == GLSL_SAMPLER_DIM_1D;
+       bool gfx9_1d = ctx->ac.chip_class == GFX9 && dim == GLSL_SAMPLER_DIM_1D;
+       assert(!add_frag_pos && "Input attachments should be lowered by this point.");
        count = image_type_to_components_count(dim, is_array);
 
-       if (is_ms && instr->intrinsic == nir_intrinsic_image_deref_load) {
+       if (is_ms && (instr->intrinsic == nir_intrinsic_image_deref_load ||
+                     instr->intrinsic == nir_intrinsic_bindless_image_load)) {
                LLVMValueRef fmask_load_address[3];
-               int chan;
 
                fmask_load_address[0] = LLVMBuildExtractElement(ctx->ac.builder, src0, masks[0], "");
                fmask_load_address[1] = LLVMBuildExtractElement(ctx->ac.builder, src0, masks[1], "");
@@ -2375,21 +2434,14 @@ static void get_image_coords(struct ac_nir_context *ctx,
                        fmask_load_address[2] = LLVMBuildExtractElement(ctx->ac.builder, src0, masks[2], "");
                else
                        fmask_load_address[2] = NULL;
-               if (add_frag_pos) {
-                       for (chan = 0; chan < 2; ++chan)
-                               fmask_load_address[chan] =
-                                       LLVMBuildAdd(ctx->ac.builder, fmask_load_address[chan],
-                                               LLVMBuildFPToUI(ctx->ac.builder, ctx->abi->frag_pos[chan],
-                                                               ctx->ac.i32, ""), "");
-                       fmask_load_address[2] = ac_to_integer(&ctx->ac, ctx->abi->inputs[ac_llvm_reg_index_soa(VARYING_SLOT_LAYER, 0)]);
-               }
+
                sample_index = adjust_sample_index_using_fmask(&ctx->ac,
                                                               fmask_load_address[0],
                                                               fmask_load_address[1],
                                                               fmask_load_address[2],
                                                               sample_index,
                                                               get_sampler_desc(ctx, nir_instr_as_deref(instr->src[0].ssa->parent_instr),
-                                                                               AC_DESC_FMASK, NULL, false, false));
+                                                                               AC_DESC_FMASK, &instr->instr, true, false));
        }
        if (count == 1 && !gfx9_1d) {
                if (instr->src[1].ssa->num_components)
@@ -2403,18 +2455,6 @@ static void get_image_coords(struct ac_nir_context *ctx,
                for (chan = 0; chan < count; ++chan) {
                        args->coords[chan] = ac_llvm_extract_elem(&ctx->ac, src0, chan);
                }
-               if (add_frag_pos) {
-                       for (chan = 0; chan < 2; ++chan) {
-                               args->coords[chan] = LLVMBuildAdd(
-                                       ctx->ac.builder, args->coords[chan],
-                                       LLVMBuildFPToUI(
-                                               ctx->ac.builder, ctx->abi->frag_pos[chan],
-                                               ctx->ac.i32, ""), "");
-                       }
-                       args->coords[2] = ac_to_integer(&ctx->ac,
-                               ctx->abi->inputs[ac_llvm_reg_index_soa(VARYING_SLOT_LAYER, 0)]);
-                       count++;
-               }
 
                if (gfx9_1d) {
                        if (is_array) {
@@ -2433,10 +2473,12 @@ static void get_image_coords(struct ac_nir_context *ctx,
 }
 
 static LLVMValueRef get_image_buffer_descriptor(struct ac_nir_context *ctx,
-                                                const nir_intrinsic_instr *instr, bool write)
+                                                const nir_intrinsic_instr *instr,
+                                               bool write, bool atomic)
 {
        LLVMValueRef rsrc = get_image_descriptor(ctx, instr, AC_DESC_BUFFER, write);
-       if (ctx->abi->gfx9_stride_size_workaround) {
+       if (ctx->abi->gfx9_stride_size_workaround ||
+           (ctx->abi->gfx9_stride_size_workaround_for_atomic && atomic)) {
                LLVMValueRef elem_count = LLVMBuildExtractElement(ctx->ac.builder, rsrc, LLVMConstInt(ctx->ac.i32, 2, 0), "");
                LLVMValueRef stride = LLVMBuildExtractElement(ctx->ac.builder, rsrc, LLVMConstInt(ctx->ac.i32, 1, 0), "");
                stride = LLVMBuildLShr(ctx->ac.builder, stride, LLVMConstInt(ctx->ac.i32, 16, 0), "");
@@ -2452,65 +2494,91 @@ static LLVMValueRef get_image_buffer_descriptor(struct ac_nir_context *ctx,
 }
 
 static LLVMValueRef visit_image_load(struct ac_nir_context *ctx,
-                                    const nir_intrinsic_instr *instr)
+                                    const nir_intrinsic_instr *instr,
+                                    bool bindless)
 {
        LLVMValueRef res;
-       const nir_deref_instr *image_deref = get_image_deref(instr);
-       const struct glsl_type *type = image_deref->type;
-       const nir_variable *var = nir_deref_instr_get_variable(image_deref);
+
+       enum glsl_sampler_dim dim;
+       enum gl_access_qualifier access;
+       bool is_array;
+       if (bindless) {
+               dim = nir_intrinsic_image_dim(instr);
+               access = nir_intrinsic_access(instr);
+               is_array = nir_intrinsic_image_array(instr);
+       } else {
+               const nir_deref_instr *image_deref = get_image_deref(instr);
+               const struct glsl_type *type = image_deref->type;
+               const nir_variable *var = nir_deref_instr_get_variable(image_deref);
+               dim = glsl_get_sampler_dim(type);
+               access = var->data.image.access;
+               is_array = glsl_sampler_type_is_array(type);
+       }
+
        struct ac_image_args args = {};
 
-       args.cache_policy =
-               get_cache_policy(ctx, var->data.image.access, false, false);
+       args.cache_policy = get_cache_policy(ctx, access, false, false);
 
-       const enum glsl_sampler_dim dim = glsl_get_sampler_dim(type);
        if (dim == GLSL_SAMPLER_DIM_BUF) {
                unsigned mask = nir_ssa_def_components_read(&instr->dest.ssa);
                unsigned num_channels = util_last_bit(mask);
                LLVMValueRef rsrc, vindex;
 
-               rsrc = get_image_buffer_descriptor(ctx, instr, false);
+               rsrc = get_image_buffer_descriptor(ctx, instr, false, false);
                vindex = LLVMBuildExtractElement(ctx->ac.builder, get_src(ctx, instr->src[1]),
                                                 ctx->ac.i32_0, "");
 
-               /* TODO: set "can_speculate" when OpenGL needs it. */
+               bool can_speculate = access & ACCESS_CAN_REORDER;
                res = ac_build_buffer_load_format(&ctx->ac, rsrc, vindex,
                                                  ctx->ac.i32_0, num_channels,
-                                                 !!(args.cache_policy & ac_glc),
-                                                 false);
+                                                 args.cache_policy,
+                                                 can_speculate);
                res = ac_build_expand_to_vec4(&ctx->ac, res, num_channels);
 
                res = ac_trim_vector(&ctx->ac, res, instr->dest.ssa.num_components);
                res = ac_to_integer(&ctx->ac, res);
        } else {
                args.opcode = ac_image_load;
-               get_image_coords(ctx, instr, &args);
+               get_image_coords(ctx, instr, &args, dim, is_array);
                args.resource = get_image_descriptor(ctx, instr, AC_DESC_IMAGE, false);
-               args.dim = get_ac_image_dim(&ctx->ac, glsl_get_sampler_dim(type),
-                                           glsl_sampler_type_is_array(type));
+               args.dim = get_ac_image_dim(&ctx->ac, dim, is_array);
                args.dmask = 15;
                args.attributes = AC_FUNC_ATTR_READONLY;
 
                res = ac_build_image_opcode(&ctx->ac, &args);
        }
-       return ac_to_integer(&ctx->ac, res);
+       return res;
 }
 
 static void visit_image_store(struct ac_nir_context *ctx,
-                             nir_intrinsic_instr *instr)
+                             nir_intrinsic_instr *instr,
+                             bool bindless)
 {
-       const nir_deref_instr *image_deref = get_image_deref(instr);
-       const struct glsl_type *type = image_deref->type;
-       const nir_variable *var = nir_deref_instr_get_variable(image_deref);
-       const enum glsl_sampler_dim dim = glsl_get_sampler_dim(type);
-       bool writeonly_memory = var->data.image.access & ACCESS_NON_READABLE;
+
+
+       enum glsl_sampler_dim dim;
+       enum gl_access_qualifier access;
+       bool is_array;
+       if (bindless) {
+               dim = nir_intrinsic_image_dim(instr);
+               access = nir_intrinsic_access(instr);
+               is_array = nir_intrinsic_image_array(instr);
+       } else {
+               const nir_deref_instr *image_deref = get_image_deref(instr);
+               const struct glsl_type *type = image_deref->type;
+               const nir_variable *var = nir_deref_instr_get_variable(image_deref);
+               dim = glsl_get_sampler_dim(type);
+               access = var->data.image.access;
+               is_array = glsl_sampler_type_is_array(type);
+       }
+
+       bool writeonly_memory = access & ACCESS_NON_READABLE;
        struct ac_image_args args = {};
 
-       args.cache_policy = get_cache_policy(ctx, var->data.image.access, true,
-                                            writeonly_memory);
+       args.cache_policy = get_cache_policy(ctx, access, true, writeonly_memory);
 
        if (dim == GLSL_SAMPLER_DIM_BUF) {
-               LLVMValueRef rsrc = get_image_buffer_descriptor(ctx, instr, true);
+               LLVMValueRef rsrc = get_image_buffer_descriptor(ctx, instr, true, false);
                LLVMValueRef src = ac_to_float(&ctx->ac, get_src(ctx, instr->src[3]));
                unsigned src_channels = ac_get_llvm_num_components(src);
                LLVMValueRef vindex;
@@ -2524,15 +2592,13 @@ static void visit_image_store(struct ac_nir_context *ctx,
 
                ac_build_buffer_store_format(&ctx->ac, rsrc, src, vindex,
                                             ctx->ac.i32_0, src_channels,
-                                            args.cache_policy & ac_glc,
-                                            writeonly_memory);
+                                            args.cache_policy);
        } else {
                args.opcode = ac_image_store;
                args.data[0] = ac_to_float(&ctx->ac, get_src(ctx, instr->src[3]));
-               get_image_coords(ctx, instr, &args);
+               get_image_coords(ctx, instr, &args, dim, is_array);
                args.resource = get_image_descriptor(ctx, instr, AC_DESC_IMAGE, true);
-               args.dim = get_ac_image_dim(&ctx->ac, glsl_get_sampler_dim(type),
-                                           glsl_sampler_type_is_array(type));
+               args.dim = get_ac_image_dim(&ctx->ac, dim, is_array);
                args.dmask = 15;
 
                ac_build_image_opcode(&ctx->ac, &args);
@@ -2541,53 +2607,100 @@ static void visit_image_store(struct ac_nir_context *ctx,
 }
 
 static LLVMValueRef visit_image_atomic(struct ac_nir_context *ctx,
-                                       const nir_intrinsic_instr *instr)
+                                       const nir_intrinsic_instr *instr,
+                                       bool bindless)
 {
        LLVMValueRef params[7];
        int param_count = 0;
-       const struct glsl_type *type = get_image_deref(instr)->type;
 
-       bool cmpswap = instr->intrinsic == nir_intrinsic_image_deref_atomic_comp_swap;
+       bool cmpswap = instr->intrinsic == nir_intrinsic_image_deref_atomic_comp_swap ||
+                      instr->intrinsic == nir_intrinsic_bindless_image_atomic_comp_swap;
        const char *atomic_name;
        char intrinsic_name[64];
        enum ac_atomic_op atomic_subop;
-       MAYBE_UNUSED int length;
-
-       bool is_unsigned = glsl_get_sampler_result_type(type) == GLSL_TYPE_UINT;
+       ASSERTED int length;
+
+       enum glsl_sampler_dim dim;
+       bool is_unsigned = false;
+       bool is_array;
+       if (bindless) {
+               if (instr->intrinsic == nir_intrinsic_bindless_image_atomic_min ||
+                   instr->intrinsic == nir_intrinsic_bindless_image_atomic_max) {
+                       const GLenum format = nir_intrinsic_format(instr);
+                       assert(format == GL_R32UI || format == GL_R32I);
+                       is_unsigned = format == GL_R32UI;
+               }
+               dim = nir_intrinsic_image_dim(instr);
+               is_array = nir_intrinsic_image_array(instr);
+       } else {
+               const struct glsl_type *type = get_image_deref(instr)->type;
+               is_unsigned = glsl_get_sampler_result_type(type) == GLSL_TYPE_UINT;
+               dim = glsl_get_sampler_dim(type);
+               is_array = glsl_sampler_type_is_array(type);
+       }
 
        switch (instr->intrinsic) {
+       case nir_intrinsic_bindless_image_atomic_add:
        case nir_intrinsic_image_deref_atomic_add:
                atomic_name = "add";
                atomic_subop = ac_atomic_add;
                break;
+       case nir_intrinsic_bindless_image_atomic_min:
        case nir_intrinsic_image_deref_atomic_min:
                atomic_name = is_unsigned ? "umin" : "smin";
                atomic_subop = is_unsigned ? ac_atomic_umin : ac_atomic_smin;
                break;
+       case nir_intrinsic_bindless_image_atomic_max:
        case nir_intrinsic_image_deref_atomic_max:
                atomic_name = is_unsigned ? "umax" : "smax";
                atomic_subop = is_unsigned ? ac_atomic_umax : ac_atomic_smax;
                break;
+       case nir_intrinsic_bindless_image_atomic_and:
        case nir_intrinsic_image_deref_atomic_and:
                atomic_name = "and";
                atomic_subop = ac_atomic_and;
                break;
+       case nir_intrinsic_bindless_image_atomic_or:
        case nir_intrinsic_image_deref_atomic_or:
                atomic_name = "or";
                atomic_subop = ac_atomic_or;
                break;
+       case nir_intrinsic_bindless_image_atomic_xor:
        case nir_intrinsic_image_deref_atomic_xor:
                atomic_name = "xor";
                atomic_subop = ac_atomic_xor;
                break;
+       case nir_intrinsic_bindless_image_atomic_exchange:
        case nir_intrinsic_image_deref_atomic_exchange:
                atomic_name = "swap";
                atomic_subop = ac_atomic_swap;
                break;
+       case nir_intrinsic_bindless_image_atomic_comp_swap:
        case nir_intrinsic_image_deref_atomic_comp_swap:
                atomic_name = "cmpswap";
                atomic_subop = 0; /* not used */
                break;
+       case nir_intrinsic_bindless_image_atomic_inc_wrap:
+       case nir_intrinsic_image_deref_atomic_inc_wrap: {
+               atomic_name = "inc";
+               atomic_subop = ac_atomic_inc_wrap;
+               /* ATOMIC_INC instruction does:
+                *      value = (value + 1) % (data + 1)
+                * but we want:
+                *      value = (value + 1) % data
+                * So replace 'data' by 'data - 1'.
+                */
+               ctx->ssa_defs[instr->src[3].ssa->index] =
+                       LLVMBuildSub(ctx->ac.builder,
+                                    ctx->ssa_defs[instr->src[3].ssa->index],
+                                    ctx->ac.i32_1, "");
+               break;
+       }
+       case nir_intrinsic_bindless_image_atomic_dec_wrap:
+       case nir_intrinsic_image_deref_atomic_dec_wrap:
+               atomic_name = "dec";
+               atomic_subop = ac_atomic_dec_wrap;
+               break;
        default:
                abort();
        }
@@ -2596,12 +2709,15 @@ static LLVMValueRef visit_image_atomic(struct ac_nir_context *ctx,
                params[param_count++] = get_src(ctx, instr->src[4]);
        params[param_count++] = get_src(ctx, instr->src[3]);
 
-       if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_BUF) {
-               params[param_count++] = get_image_buffer_descriptor(ctx, instr, true);
+       if (dim == GLSL_SAMPLER_DIM_BUF) {
+               params[param_count++] = get_image_buffer_descriptor(ctx, instr, true, true);
                params[param_count++] = LLVMBuildExtractElement(ctx->ac.builder, get_src(ctx, instr->src[1]),
                                                                ctx->ac.i32_0, ""); /* vindex */
                params[param_count++] = ctx->ac.i32_0; /* voffset */
-               if (HAVE_LLVM >= 0x800) {
+               if (HAVE_LLVM >= 0x900) {
+                       /* XXX: The new raw/struct atomic intrinsics are buggy
+                        * with LLVM 8, see r358579.
+                        */
                        params[param_count++] = ctx->ac.i32_0; /* soffset */
                        params[param_count++] = ctx->ac.i32_0;  /* slc */
 
@@ -2624,23 +2740,31 @@ static LLVMValueRef visit_image_atomic(struct ac_nir_context *ctx,
                args.data[0] = params[0];
                if (cmpswap)
                        args.data[1] = params[1];
-               get_image_coords(ctx, instr, &args);
+               get_image_coords(ctx, instr, &args, dim, is_array);
                args.resource = get_image_descriptor(ctx, instr, AC_DESC_IMAGE, true);
-               args.dim = get_ac_image_dim(&ctx->ac, glsl_get_sampler_dim(type),
-                                           glsl_sampler_type_is_array(type));
+               args.dim = get_ac_image_dim(&ctx->ac, dim, is_array);
 
                return ac_build_image_opcode(&ctx->ac, &args);
        }
 }
 
 static LLVMValueRef visit_image_samples(struct ac_nir_context *ctx,
-                                       const nir_intrinsic_instr *instr)
+                                       const nir_intrinsic_instr *instr,
+                                       bool bindless)
 {
-       const struct glsl_type *type = get_image_deref(instr)->type;
+       enum glsl_sampler_dim dim;
+       bool is_array;
+       if (bindless) {
+               dim = nir_intrinsic_image_dim(instr);
+               is_array = nir_intrinsic_image_array(instr);
+       } else {
+               const struct glsl_type *type = get_image_deref(instr)->type;
+               dim = glsl_get_sampler_dim(type);
+               is_array = glsl_sampler_type_is_array(type);
+       }
 
        struct ac_image_args args = { 0 };
-       args.dim = get_ac_sampler_dim(&ctx->ac, glsl_get_sampler_dim(type),
-                                     glsl_sampler_type_is_array(type));
+       args.dim = get_ac_sampler_dim(&ctx->ac, dim, is_array);
        args.dmask = 0xf;
        args.resource = get_image_descriptor(ctx, instr, AC_DESC_IMAGE, false);
        args.opcode = ac_image_get_resinfo;
@@ -2651,18 +2775,28 @@ static LLVMValueRef visit_image_samples(struct ac_nir_context *ctx,
 }
 
 static LLVMValueRef visit_image_size(struct ac_nir_context *ctx,
-                                    const nir_intrinsic_instr *instr)
+                                    const nir_intrinsic_instr *instr,
+                                    bool bindless)
 {
        LLVMValueRef res;
-       const struct glsl_type *type = get_image_deref(instr)->type;
 
-       if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_BUF)
+       enum glsl_sampler_dim dim;
+       bool is_array;
+       if (bindless) {
+               dim = nir_intrinsic_image_dim(instr);
+               is_array = nir_intrinsic_image_array(instr);
+       } else {
+               const struct glsl_type *type = get_image_deref(instr)->type;
+               dim = glsl_get_sampler_dim(type);
+               is_array = glsl_sampler_type_is_array(type);
+       }
+
+       if (dim == GLSL_SAMPLER_DIM_BUF)
                return get_buffer_size(ctx, get_image_descriptor(ctx, instr, AC_DESC_BUFFER, false), true);
 
        struct ac_image_args args = { 0 };
 
-       args.dim = get_ac_image_dim(&ctx->ac, glsl_get_sampler_dim(type),
-                                   glsl_sampler_type_is_array(type));
+       args.dim = get_ac_image_dim(&ctx->ac, dim, is_array);
        args.dmask = 0xf;
        args.resource = get_image_descriptor(ctx, instr, AC_DESC_IMAGE, false);
        args.opcode = ac_image_get_resinfo;
@@ -2673,16 +2807,13 @@ static LLVMValueRef visit_image_size(struct ac_nir_context *ctx,
 
        LLVMValueRef two = LLVMConstInt(ctx->ac.i32, 2, false);
 
-       if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_CUBE &&
-           glsl_sampler_type_is_array(type)) {
+       if (dim == GLSL_SAMPLER_DIM_CUBE && is_array) {
                LLVMValueRef six = LLVMConstInt(ctx->ac.i32, 6, false);
                LLVMValueRef z = LLVMBuildExtractElement(ctx->ac.builder, res, two, "");
                z = LLVMBuildSDiv(ctx->ac.builder, z, six, "");
                res = LLVMBuildInsertElement(ctx->ac.builder, res, z, two, "");
        }
-       if (ctx->ac.chip_class >= GFX9 &&
-           glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_1D &&
-           glsl_sampler_type_is_array(type)) {
+       if (ctx->ac.chip_class == GFX9 && dim == GLSL_SAMPLER_DIM_1D && is_array) {
                LLVMValueRef layers = LLVMBuildExtractElement(ctx->ac.builder, res, two, "");
                res = LLVMBuildInsertElement(ctx->ac.builder, res, layers,
                                                ctx->ac.i32_1, "");
@@ -2694,36 +2825,36 @@ static LLVMValueRef visit_image_size(struct ac_nir_context *ctx,
 static void emit_membar(struct ac_llvm_context *ac,
                        const nir_intrinsic_instr *instr)
 {
-       unsigned waitcnt = NOOP_WAITCNT;
+       unsigned wait_flags = 0;
 
        switch (instr->intrinsic) {
        case nir_intrinsic_memory_barrier:
        case nir_intrinsic_group_memory_barrier:
-               waitcnt &= VM_CNT & LGKM_CNT;
+               wait_flags = AC_WAIT_LGKM | AC_WAIT_VLOAD | AC_WAIT_VSTORE;
                break;
        case nir_intrinsic_memory_barrier_atomic_counter:
        case nir_intrinsic_memory_barrier_buffer:
        case nir_intrinsic_memory_barrier_image:
-               waitcnt &= VM_CNT;
+               wait_flags = AC_WAIT_VLOAD | AC_WAIT_VSTORE;
                break;
        case nir_intrinsic_memory_barrier_shared:
-               waitcnt &= LGKM_CNT;
+               wait_flags = AC_WAIT_LGKM;
                break;
        default:
                break;
        }
-       if (waitcnt != NOOP_WAITCNT)
-               ac_build_waitcnt(ac, waitcnt);
+
+       ac_build_waitcnt(ac, wait_flags);
 }
 
 void ac_emit_barrier(struct ac_llvm_context *ac, gl_shader_stage stage)
 {
-       /* 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 (ac->chip_class == SI && stage == MESA_SHADER_TESS_CTRL) {
-               ac_build_waitcnt(ac, LGKM_CNT & VM_CNT);
+       if (ac->chip_class == GFX6 && stage == MESA_SHADER_TESS_CTRL) {
+               ac_build_waitcnt(ac, AC_WAIT_LGKM | AC_WAIT_VLOAD | AC_WAIT_VSTORE);
                return;
        }
        ac_build_s_barrier(ac);
@@ -2746,17 +2877,6 @@ static void emit_discard(struct ac_nir_context *ctx,
        ctx->abi->emit_kill(ctx->abi, cond);
 }
 
-static LLVMValueRef
-visit_load_helper_invocation(struct ac_nir_context *ctx)
-{
-       LLVMValueRef result = ac_build_intrinsic(&ctx->ac,
-                                                "llvm.amdgcn.ps.live",
-                                                ctx->ac.i1, NULL, 0,
-                                                AC_FUNC_ATTR_READNONE);
-       result = LLVMBuildNot(ctx->ac.builder, result, "");
-       return LLVMBuildSExt(ctx->ac.builder, result, ctx->ac.i32, "");
-}
-
 static LLVMValueRef
 visit_load_local_invocation_index(struct ac_nir_context *ctx)
 {
@@ -2796,12 +2916,12 @@ static LLVMValueRef
 visit_first_invocation(struct ac_nir_context *ctx)
 {
        LLVMValueRef active_set = ac_build_ballot(&ctx->ac, ctx->ac.i32_1);
+       const char *intr = ctx->ac.wave_size == 32 ? "llvm.cttz.i32" : "llvm.cttz.i64";
 
        /* The second argument is whether cttz(0) should be defined, but we do not care. */
        LLVMValueRef args[] = {active_set, ctx->ac.i1false};
-       LLVMValueRef result =  ac_build_intrinsic(&ctx->ac,
-                                                 "llvm.cttz.i64",
-                                                 ctx->ac.i64, args, 2,
+       LLVMValueRef result =  ac_build_intrinsic(&ctx->ac, intr,
+                                                 ctx->ac.iN_wavemask, args, 2,
                                                  AC_FUNC_ATTR_NOUNWIND |
                                                  AC_FUNC_ATTR_READNONE);
 
@@ -2855,14 +2975,12 @@ static LLVMValueRef visit_var_atomic(struct ac_nir_context *ctx,
        LLVMValueRef result;
        LLVMValueRef src = get_src(ctx, instr->src[src_idx]);
 
+       const char *sync_scope = HAVE_LLVM >= 0x0900 ? "workgroup-one-as" : "workgroup";
+
        if (instr->intrinsic == nir_intrinsic_shared_atomic_comp_swap ||
            instr->intrinsic == nir_intrinsic_deref_atomic_comp_swap) {
                LLVMValueRef src1 = get_src(ctx, instr->src[src_idx + 1]);
-               result = LLVMBuildAtomicCmpXchg(ctx->ac.builder,
-                                               ptr, src, src1,
-                                               LLVMAtomicOrderingSequentiallyConsistent,
-                                               LLVMAtomicOrderingSequentiallyConsistent,
-                                               false);
+               result = ac_build_atomic_cmp_xchg(&ctx->ac, ptr, src, src1, sync_scope);
                result = LLVMBuildExtractValue(ctx->ac.builder, result, 0, "");
        } else {
                LLVMAtomicRMWBinOp op;
@@ -2907,9 +3025,7 @@ static LLVMValueRef visit_var_atomic(struct ac_nir_context *ctx,
                        return NULL;
                }
 
-               result = LLVMBuildAtomicRMW(ctx->ac.builder, op, ptr, ac_to_integer(&ctx->ac, src),
-                                           LLVMAtomicOrderingSequentiallyConsistent,
-                                           false);
+               result = ac_build_atomic_rmw(&ctx->ac, op, ptr, ac_to_integer(&ctx->ac, src), sync_scope);
        }
        return result;
 }
@@ -2927,149 +3043,158 @@ static LLVMValueRef load_sample_pos(struct ac_nir_context *ctx)
        return ac_build_gather_values(&ctx->ac, values, 2);
 }
 
-static LLVMValueRef visit_interp(struct ac_nir_context *ctx,
-                                const nir_intrinsic_instr *instr)
+static LLVMValueRef barycentric_center(struct ac_nir_context *ctx,
+                                      unsigned mode)
 {
-       LLVMValueRef result[4];
-       LLVMValueRef interp_param;
-       unsigned location;
-       unsigned chan;
-       LLVMValueRef src_c0 = NULL;
-       LLVMValueRef src_c1 = NULL;
-       LLVMValueRef src0 = NULL;
-
-       nir_deref_instr *deref_instr = nir_instr_as_deref(instr->src[0].ssa->parent_instr);
-       nir_variable *var = nir_deref_instr_get_variable(deref_instr);
-       int input_base = ctx->abi->fs_input_attr_indices[var->data.location - VARYING_SLOT_VAR0];
-       switch (instr->intrinsic) {
-       case nir_intrinsic_interp_deref_at_centroid:
-               location = INTERP_CENTROID;
-               break;
-       case nir_intrinsic_interp_deref_at_sample:
-       case nir_intrinsic_interp_deref_at_offset:
-               location = INTERP_CENTER;
-               src0 = get_src(ctx, instr->src[1]);
-               break;
-       default:
-               break;
-       }
+       LLVMValueRef interp_param = ctx->abi->lookup_interp_param(ctx->abi, mode, INTERP_CENTER);
+       return LLVMBuildBitCast(ctx->ac.builder, interp_param, ctx->ac.v2i32, "");
+}
 
-       if (instr->intrinsic == nir_intrinsic_interp_deref_at_offset) {
-               src_c0 = ac_to_float(&ctx->ac, LLVMBuildExtractElement(ctx->ac.builder, src0, ctx->ac.i32_0, ""));
-               src_c1 = ac_to_float(&ctx->ac, LLVMBuildExtractElement(ctx->ac.builder, src0, ctx->ac.i32_1, ""));
-       } else if (instr->intrinsic == nir_intrinsic_interp_deref_at_sample) {
-               LLVMValueRef sample_position;
-               LLVMValueRef halfval = LLVMConstReal(ctx->ac.f32, 0.5f);
+static LLVMValueRef barycentric_offset(struct ac_nir_context *ctx,
+                                      unsigned mode,
+                                      LLVMValueRef offset)
+{
+       LLVMValueRef interp_param = ctx->abi->lookup_interp_param(ctx->abi, mode, INTERP_CENTER);
+       LLVMValueRef src_c0 = ac_to_float(&ctx->ac, LLVMBuildExtractElement(ctx->ac.builder, offset, ctx->ac.i32_0, ""));
+       LLVMValueRef src_c1 = ac_to_float(&ctx->ac, LLVMBuildExtractElement(ctx->ac.builder, offset, ctx->ac.i32_1, ""));
 
-               /* fetch sample ID */
-               sample_position = ctx->abi->load_sample_position(ctx->abi, src0);
+       LLVMValueRef ij_out[2];
+       LLVMValueRef ddxy_out = ac_build_ddxy_interp(&ctx->ac, interp_param);
 
-               src_c0 = LLVMBuildExtractElement(ctx->ac.builder, sample_position, ctx->ac.i32_0, "");
-               src_c0 = LLVMBuildFSub(ctx->ac.builder, src_c0, halfval, "");
-               src_c1 = LLVMBuildExtractElement(ctx->ac.builder, sample_position, ctx->ac.i32_1, "");
-               src_c1 = LLVMBuildFSub(ctx->ac.builder, src_c1, halfval, "");
-       }
-       interp_param = ctx->abi->lookup_interp_param(ctx->abi, var->data.interpolation, location);
+       /*
+        * take the I then J parameters, and the DDX/Y for it, and
+        * calculate the IJ inputs for the interpolator.
+        * temp1 = ddx * offset/sample.x + I;
+        * interp_param.I = ddy * offset/sample.y + temp1;
+        * temp1 = ddx * offset/sample.x + J;
+        * interp_param.J = ddy * offset/sample.y + temp1;
+        */
+       for (unsigned i = 0; i < 2; i++) {
+               LLVMValueRef ix_ll = LLVMConstInt(ctx->ac.i32, i, false);
+               LLVMValueRef iy_ll = LLVMConstInt(ctx->ac.i32, i + 2, false);
+               LLVMValueRef ddx_el = LLVMBuildExtractElement(ctx->ac.builder,
+                                                             ddxy_out, ix_ll, "");
+               LLVMValueRef ddy_el = LLVMBuildExtractElement(ctx->ac.builder,
+                                                             ddxy_out, iy_ll, "");
+               LLVMValueRef interp_el = LLVMBuildExtractElement(ctx->ac.builder,
+                                                                interp_param, ix_ll, "");
+               LLVMValueRef temp1, temp2;
+
+               interp_el = LLVMBuildBitCast(ctx->ac.builder, interp_el,
+                                            ctx->ac.f32, "");
+
+               temp1 = ac_build_fmad(&ctx->ac, ddx_el, src_c0, interp_el);
+               temp2 = ac_build_fmad(&ctx->ac, ddy_el, src_c1, temp1);
+
+               ij_out[i] = LLVMBuildBitCast(ctx->ac.builder,
+                                            temp2, ctx->ac.i32, "");
+       }
+       interp_param = ac_build_gather_values(&ctx->ac, ij_out, 2);
+       return LLVMBuildBitCast(ctx->ac.builder, interp_param, ctx->ac.v2i32, "");
+}
 
-       if (location == INTERP_CENTER) {
-               LLVMValueRef ij_out[2];
-               LLVMValueRef ddxy_out = emit_ddxy_interp(ctx, interp_param);
+static LLVMValueRef barycentric_centroid(struct ac_nir_context *ctx,
+                                        unsigned mode)
+{
+       LLVMValueRef interp_param = ctx->abi->lookup_interp_param(ctx->abi, mode, INTERP_CENTROID);
+       return LLVMBuildBitCast(ctx->ac.builder, interp_param, ctx->ac.v2i32, "");
+}
 
-               /*
-                * take the I then J parameters, and the DDX/Y for it, and
-                * calculate the IJ inputs for the interpolator.
-                * temp1 = ddx * offset/sample.x + I;
-                * interp_param.I = ddy * offset/sample.y + temp1;
-                * temp1 = ddx * offset/sample.x + J;
-                * interp_param.J = ddy * offset/sample.y + temp1;
-                */
-               for (unsigned i = 0; i < 2; i++) {
-                       LLVMValueRef ix_ll = LLVMConstInt(ctx->ac.i32, i, false);
-                       LLVMValueRef iy_ll = LLVMConstInt(ctx->ac.i32, i + 2, false);
-                       LLVMValueRef ddx_el = LLVMBuildExtractElement(ctx->ac.builder,
-                                                                     ddxy_out, ix_ll, "");
-                       LLVMValueRef ddy_el = LLVMBuildExtractElement(ctx->ac.builder,
-                                                                     ddxy_out, iy_ll, "");
-                       LLVMValueRef interp_el = LLVMBuildExtractElement(ctx->ac.builder,
-                                                                        interp_param, ix_ll, "");
-                       LLVMValueRef temp1, temp2;
-
-                       interp_el = LLVMBuildBitCast(ctx->ac.builder, interp_el,
-                                                    ctx->ac.f32, "");
-
-                       temp1 = ac_build_fmad(&ctx->ac, ddx_el, src_c0, interp_el);
-                       temp2 = ac_build_fmad(&ctx->ac, ddy_el, src_c1, temp1);
-
-                       ij_out[i] = LLVMBuildBitCast(ctx->ac.builder,
-                                                    temp2, ctx->ac.i32, "");
-               }
-               interp_param = ac_build_gather_values(&ctx->ac, ij_out, 2);
+static LLVMValueRef barycentric_at_sample(struct ac_nir_context *ctx,
+                                         unsigned mode,
+                                         LLVMValueRef sample_id)
+{
+       if (ctx->abi->interp_at_sample_force_center)
+               return barycentric_center(ctx, mode);
 
-       }
+       LLVMValueRef halfval = LLVMConstReal(ctx->ac.f32, 0.5f);
 
-       LLVMValueRef attrib_idx = ctx->ac.i32_0;
-       while(deref_instr->deref_type != nir_deref_type_var) {
-               if (deref_instr->deref_type == nir_deref_type_array) {
-                       unsigned array_size = glsl_count_attribute_slots(deref_instr->type, false);
+       /* fetch sample ID */
+       LLVMValueRef sample_pos = ctx->abi->load_sample_position(ctx->abi, sample_id);
 
-                       LLVMValueRef offset;
-                       nir_const_value *const_value = nir_src_as_const_value(deref_instr->arr.index);
-                       if (const_value) {
-                               offset = LLVMConstInt(ctx->ac.i32, array_size * const_value->u32[0], false);
-                       } else {
-                               LLVMValueRef indirect = get_src(ctx, deref_instr->arr.index);
+       LLVMValueRef src_c0 = LLVMBuildExtractElement(ctx->ac.builder, sample_pos, ctx->ac.i32_0, "");
+       src_c0 = LLVMBuildFSub(ctx->ac.builder, src_c0, halfval, "");
+       LLVMValueRef src_c1 = LLVMBuildExtractElement(ctx->ac.builder, sample_pos, ctx->ac.i32_1, "");
+       src_c1 = LLVMBuildFSub(ctx->ac.builder, src_c1, halfval, "");
+       LLVMValueRef coords[] = { src_c0, src_c1 };
+       LLVMValueRef offset = ac_build_gather_values(&ctx->ac, coords, 2);
+
+       return barycentric_offset(ctx, mode, offset);
+}
 
-                               offset = LLVMBuildMul(ctx->ac.builder, indirect,
-                                                     LLVMConstInt(ctx->ac.i32, array_size, false), "");
-                       }
 
-                       attrib_idx = LLVMBuildAdd(ctx->ac.builder, attrib_idx, offset, "");
-                       deref_instr = nir_src_as_deref(deref_instr->parent);
-               } else if (deref_instr->deref_type == nir_deref_type_struct) {
-                       LLVMValueRef offset;
-                       unsigned sidx = deref_instr->strct.index;
-                       deref_instr = nir_src_as_deref(deref_instr->parent);
-                       offset = LLVMConstInt(ctx->ac.i32, glsl_get_struct_location_offset(deref_instr->type, sidx), false);
-                       attrib_idx = LLVMBuildAdd(ctx->ac.builder, attrib_idx, offset, "");
+static LLVMValueRef barycentric_sample(struct ac_nir_context *ctx,
+                                      unsigned mode)
+{
+       LLVMValueRef interp_param = ctx->abi->lookup_interp_param(ctx->abi, mode, INTERP_SAMPLE);
+       return LLVMBuildBitCast(ctx->ac.builder, interp_param, ctx->ac.v2i32, "");
+}
+
+static LLVMValueRef load_interpolated_input(struct ac_nir_context *ctx,
+                                           LLVMValueRef interp_param,
+                                           unsigned index, unsigned comp_start,
+                                           unsigned num_components,
+                                           unsigned bitsize)
+{
+       LLVMValueRef attr_number = LLVMConstInt(ctx->ac.i32, index, false);
+
+       interp_param = LLVMBuildBitCast(ctx->ac.builder,
+                               interp_param, ctx->ac.v2f32, "");
+       LLVMValueRef i = LLVMBuildExtractElement(
+               ctx->ac.builder, interp_param, ctx->ac.i32_0, "");
+       LLVMValueRef j = LLVMBuildExtractElement(
+               ctx->ac.builder, interp_param, ctx->ac.i32_1, "");
+
+       LLVMValueRef values[4];
+       assert(bitsize == 16 || bitsize == 32);
+       for (unsigned comp = 0; comp < num_components; comp++) {
+               LLVMValueRef llvm_chan = LLVMConstInt(ctx->ac.i32, comp_start + comp, false);
+               if (bitsize == 16) {
+                       values[comp] = ac_build_fs_interp_f16(&ctx->ac, llvm_chan, attr_number,
+                                                             ctx->abi->prim_mask, i, j);
                } else {
-                       unreachable("Unsupported deref type");
+                       values[comp] = ac_build_fs_interp(&ctx->ac, llvm_chan, attr_number,
+                                                         ctx->abi->prim_mask, i, j);
                }
-
        }
 
-       unsigned attrib_size = glsl_count_attribute_slots(var->type, false);
-       for (chan = 0; chan < 4; chan++) {
-               LLVMValueRef gather = LLVMGetUndef(LLVMVectorType(ctx->ac.f32, attrib_size));
-               LLVMValueRef llvm_chan = LLVMConstInt(ctx->ac.i32, chan, false);
-
-               for (unsigned idx = 0; idx < attrib_size; ++idx) {
-                       LLVMValueRef v, attr_number;
-
-                       attr_number = LLVMConstInt(ctx->ac.i32, input_base + idx, false);
-                       if (interp_param) {
-                               interp_param = LLVMBuildBitCast(ctx->ac.builder,
-                                                       interp_param, ctx->ac.v2f32, "");
-                               LLVMValueRef i = LLVMBuildExtractElement(
-                                       ctx->ac.builder, interp_param, ctx->ac.i32_0, "");
-                               LLVMValueRef j = LLVMBuildExtractElement(
-                                       ctx->ac.builder, interp_param, ctx->ac.i32_1, "");
-
-                               v = ac_build_fs_interp(&ctx->ac, llvm_chan, attr_number,
-                                                      ctx->abi->prim_mask, i, j);
-                       } else {
-                               v = ac_build_fs_interp_mov(&ctx->ac, LLVMConstInt(ctx->ac.i32, 2, false),
-                                                          llvm_chan, attr_number, ctx->abi->prim_mask);
-                       }
+       return ac_to_integer(&ctx->ac, ac_build_gather_values(&ctx->ac, values, num_components));
+}
 
-                       gather = LLVMBuildInsertElement(ctx->ac.builder, gather, v,
-                                                       LLVMConstInt(ctx->ac.i32, idx, false), "");
-               }
+static LLVMValueRef load_flat_input(struct ac_nir_context *ctx,
+                                   unsigned index, unsigned comp_start,
+                                   unsigned num_components,
+                                   unsigned bit_size)
+{
+       LLVMValueRef attr_number = LLVMConstInt(ctx->ac.i32, index, false);
 
-               result[chan] = LLVMBuildExtractElement(ctx->ac.builder, gather, attrib_idx, "");
+       LLVMValueRef values[8];
 
+       /* Each component of a 64-bit value takes up two GL-level channels. */
+       unsigned channels =
+               bit_size == 64 ? num_components * 2 : num_components;
+
+       for (unsigned chan = 0; chan < channels; chan++) {
+               if (comp_start + chan > 4)
+                       attr_number = LLVMConstInt(ctx->ac.i32, index + 1, false);
+               LLVMValueRef llvm_chan = LLVMConstInt(ctx->ac.i32, (comp_start + chan) % 4, false);
+               values[chan] = ac_build_fs_interp_mov(&ctx->ac,
+                                                     LLVMConstInt(ctx->ac.i32, 2, false),
+                                                     llvm_chan,
+                                                     attr_number,
+                                                     ctx->abi->prim_mask);
+               values[chan] = LLVMBuildBitCast(ctx->ac.builder, values[chan], ctx->ac.i32, "");
+               values[chan] = LLVMBuildTruncOrBitCast(ctx->ac.builder, values[chan],
+                                                      bit_size == 16 ? ctx->ac.i16 : ctx->ac.i32, "");
+       }
+
+       LLVMValueRef result = ac_build_gather_values(&ctx->ac, values, channels);
+       if (bit_size == 64) {
+               LLVMTypeRef type = num_components == 1 ? ctx->ac.i64 :
+                       LLVMVectorType(ctx->ac.i64, num_components);
+               result = LLVMBuildBitCast(ctx->ac.builder, result, type, "");
        }
-       return ac_build_varying_gather_values(&ctx->ac, result, instr->num_components,
-                                             var->data.location_frac);
+       return result;
 }
 
 static void visit_intrinsic(struct ac_nir_context *ctx,
@@ -3080,6 +3205,8 @@ static void visit_intrinsic(struct ac_nir_context *ctx,
        switch (instr->intrinsic) {
        case nir_intrinsic_ballot:
                result = ac_build_ballot(&ctx->ac, get_src(ctx, instr->src[0]));
+               if (ctx->ac.ballot_mask_bits > ctx->ac.wave_size)
+                       result = LLVMBuildZExt(ctx->ac.builder, result, ctx->ac.iN_ballotmask, "");
                break;
        case nir_intrinsic_read_invocation:
                result = ac_build_readlane(&ctx->ac, get_src(ctx, instr->src[0]),
@@ -3131,10 +3258,17 @@ static void visit_intrinsic(struct ac_nir_context *ctx,
                result = ctx->abi->view_index;
                break;
        case nir_intrinsic_load_invocation_id:
-               if (ctx->stage == MESA_SHADER_TESS_CTRL)
+               if (ctx->stage == MESA_SHADER_TESS_CTRL) {
                        result = ac_unpack_param(&ctx->ac, ctx->abi->tcs_rel_ids, 8, 5);
-               else
-                       result = ctx->abi->gs_invocation_id;
+               } else {
+                       if (ctx->ac.chip_class >= GFX10) {
+                               result = LLVMBuildAnd(ctx->ac.builder,
+                                                     ctx->abi->gs_invocation_id,
+                                                     LLVMConstInt(ctx->ac.i32, 127, 0), "");
+                       } else {
+                               result = ctx->abi->gs_invocation_id;
+                       }
+               }
                break;
        case nir_intrinsic_load_primitive_id:
                if (ctx->stage == MESA_SHADER_GEOMETRY) {
@@ -3162,14 +3296,28 @@ static void visit_intrinsic(struct ac_nir_context *ctx,
                        ctx->abi->frag_pos[2],
                        ac_build_fdiv(&ctx->ac, ctx->ac.f32_1, ctx->abi->frag_pos[3])
                };
-               result = ac_build_gather_values(&ctx->ac, values, 4);
+               result = ac_to_integer(&ctx->ac,
+                                      ac_build_gather_values(&ctx->ac, values, 4));
                break;
        }
+       case nir_intrinsic_load_layer_id:
+               result = ctx->abi->inputs[ac_llvm_reg_index_soa(VARYING_SLOT_LAYER, 0)];
+               break;
        case nir_intrinsic_load_front_face:
                result = ctx->abi->front_face;
                break;
        case nir_intrinsic_load_helper_invocation:
-               result = visit_load_helper_invocation(ctx);
+               result = ac_build_load_helper_invocation(&ctx->ac);
+               break;
+       case nir_intrinsic_load_color0:
+               result = ctx->abi->color0;
+               break;
+       case nir_intrinsic_load_color1:
+               result = ctx->abi->color1;
+               break;
+       case nir_intrinsic_load_user_data_amd:
+               assert(LLVMTypeOf(ctx->abi->user_data) == ctx->ac.v4i32);
+               result = ctx->abi->user_data;
                break;
        case nir_intrinsic_load_instance_id:
                result = ctx->abi->instance_id;
@@ -3240,14 +3388,35 @@ static void visit_intrinsic(struct ac_nir_context *ctx,
        case nir_intrinsic_store_shared:
                visit_store_shared(ctx, instr);
                break;
+       case nir_intrinsic_bindless_image_samples:
+               result = visit_image_samples(ctx, instr, true);
+               break;
        case nir_intrinsic_image_deref_samples:
-               result = visit_image_samples(ctx, instr);
+               result = visit_image_samples(ctx, instr, false);
+               break;
+       case nir_intrinsic_bindless_image_load:
+               result = visit_image_load(ctx, instr, true);
                break;
        case nir_intrinsic_image_deref_load:
-               result = visit_image_load(ctx, instr);
+               result = visit_image_load(ctx, instr, false);
+               break;
+       case nir_intrinsic_bindless_image_store:
+               visit_image_store(ctx, instr, true);
                break;
        case nir_intrinsic_image_deref_store:
-               visit_image_store(ctx, instr);
+               visit_image_store(ctx, instr, false);
+               break;
+       case nir_intrinsic_bindless_image_atomic_add:
+       case nir_intrinsic_bindless_image_atomic_min:
+       case nir_intrinsic_bindless_image_atomic_max:
+       case nir_intrinsic_bindless_image_atomic_and:
+       case nir_intrinsic_bindless_image_atomic_or:
+       case nir_intrinsic_bindless_image_atomic_xor:
+       case nir_intrinsic_bindless_image_atomic_exchange:
+       case nir_intrinsic_bindless_image_atomic_comp_swap:
+       case nir_intrinsic_bindless_image_atomic_inc_wrap:
+       case nir_intrinsic_bindless_image_atomic_dec_wrap:
+               result = visit_image_atomic(ctx, instr, true);
                break;
        case nir_intrinsic_image_deref_atomic_add:
        case nir_intrinsic_image_deref_atomic_min:
@@ -3257,10 +3426,15 @@ static void visit_intrinsic(struct ac_nir_context *ctx,
        case nir_intrinsic_image_deref_atomic_xor:
        case nir_intrinsic_image_deref_atomic_exchange:
        case nir_intrinsic_image_deref_atomic_comp_swap:
-               result = visit_image_atomic(ctx, instr);
+       case nir_intrinsic_image_deref_atomic_inc_wrap:
+       case nir_intrinsic_image_deref_atomic_dec_wrap:
+               result = visit_image_atomic(ctx, instr, false);
+               break;
+       case nir_intrinsic_bindless_image_size:
+               result = visit_image_size(ctx, instr, true);
                break;
        case nir_intrinsic_image_deref_size:
-               result = visit_image_size(ctx, instr);
+               result = visit_image_size(ctx, instr, false);
                break;
        case nir_intrinsic_shader_clock:
                result = ac_build_shader_clock(&ctx->ac);
@@ -3308,11 +3482,53 @@ static void visit_intrinsic(struct ac_nir_context *ctx,
                result = visit_var_atomic(ctx, instr, ptr, 1);
                break;
        }
-       case nir_intrinsic_interp_deref_at_centroid:
-       case nir_intrinsic_interp_deref_at_sample:
-       case nir_intrinsic_interp_deref_at_offset:
-               result = visit_interp(ctx, instr);
+       case nir_intrinsic_load_barycentric_pixel:
+               result = barycentric_center(ctx, nir_intrinsic_interp_mode(instr));
+               break;
+       case nir_intrinsic_load_barycentric_centroid:
+               result = barycentric_centroid(ctx, nir_intrinsic_interp_mode(instr));
+               break;
+       case nir_intrinsic_load_barycentric_sample:
+               result = barycentric_sample(ctx, nir_intrinsic_interp_mode(instr));
+               break;
+       case nir_intrinsic_load_barycentric_at_offset: {
+               LLVMValueRef offset = ac_to_float(&ctx->ac, get_src(ctx, instr->src[0]));
+               result = barycentric_offset(ctx, nir_intrinsic_interp_mode(instr), offset);
+               break;
+       }
+       case nir_intrinsic_load_barycentric_at_sample: {
+               LLVMValueRef sample_id = get_src(ctx, instr->src[0]);
+               result = barycentric_at_sample(ctx, nir_intrinsic_interp_mode(instr), sample_id);
+               break;
+       }
+       case nir_intrinsic_load_interpolated_input: {
+               /* We assume any indirect loads have been lowered away */
+               ASSERTED nir_const_value *offset = nir_src_as_const_value(instr->src[1]);
+               assert(offset);
+               assert(offset[0].i32 == 0);
+
+               LLVMValueRef interp_param = get_src(ctx, instr->src[0]);
+               unsigned index = nir_intrinsic_base(instr);
+               unsigned component = nir_intrinsic_component(instr);
+               result = load_interpolated_input(ctx, interp_param, index,
+                                                component,
+                                                instr->dest.ssa.num_components,
+                                                instr->dest.ssa.bit_size);
+               break;
+       }
+       case nir_intrinsic_load_input: {
+               /* We only lower inputs for fragment shaders ATM */
+               ASSERTED nir_const_value *offset = nir_src_as_const_value(instr->src[0]);
+               assert(offset);
+               assert(offset[0].i32 == 0);
+
+               unsigned index = nir_intrinsic_base(instr);
+               unsigned component = nir_intrinsic_component(instr);
+               result = load_flat_input(ctx, index, component,
+                                        instr->dest.ssa.num_components,
+                                        instr->dest.ssa.bit_size);
                break;
+       }
        case nir_intrinsic_emit_vertex:
                ctx->abi->emit_vertex(ctx->abi, nir_intrinsic_stream_id(instr), ctx->abi->outputs);
                break;
@@ -3323,10 +3539,16 @@ static void visit_intrinsic(struct ac_nir_context *ctx,
                result = ctx->abi->load_tess_coord(ctx->abi);
                break;
        case nir_intrinsic_load_tess_level_outer:
-               result = ctx->abi->load_tess_level(ctx->abi, VARYING_SLOT_TESS_LEVEL_OUTER);
+               result = ctx->abi->load_tess_level(ctx->abi, VARYING_SLOT_TESS_LEVEL_OUTER, false);
                break;
        case nir_intrinsic_load_tess_level_inner:
-               result = ctx->abi->load_tess_level(ctx->abi, VARYING_SLOT_TESS_LEVEL_INNER);
+               result = ctx->abi->load_tess_level(ctx->abi, VARYING_SLOT_TESS_LEVEL_INNER, false);
+               break;
+       case nir_intrinsic_load_tess_level_outer_default:
+               result = ctx->abi->load_tess_level(ctx->abi, VARYING_SLOT_TESS_LEVEL_OUTER, true);
+               break;
+       case nir_intrinsic_load_tess_level_inner_default:
+               result = ctx->abi->load_tess_level(ctx->abi, VARYING_SLOT_TESS_LEVEL_INNER, true);
                break;
        case nir_intrinsic_load_patch_vertices_in:
                result = ctx->abi->load_patch_vertices_in(ctx->abi);
@@ -3362,7 +3584,7 @@ static void visit_intrinsic(struct ac_nir_context *ctx,
                                instr->const_index[0]);
                break;
        case nir_intrinsic_quad_broadcast: {
-               unsigned lane = nir_src_as_const_value(instr->src[1])->u32[0];
+               unsigned lane = nir_src_as_uint(instr->src[1]);
                result = ac_build_quad_swizzle(&ctx->ac, get_src(ctx, instr->src[0]),
                                lane, lane, lane, lane);
                break;
@@ -3376,6 +3598,70 @@ static void visit_intrinsic(struct ac_nir_context *ctx,
        case nir_intrinsic_quad_swap_diagonal:
                result = ac_build_quad_swizzle(&ctx->ac, get_src(ctx, instr->src[0]), 3, 2, 1 ,0);
                break;
+       case nir_intrinsic_quad_swizzle_amd: {
+               uint32_t mask = nir_intrinsic_swizzle_mask(instr);
+               result = ac_build_quad_swizzle(&ctx->ac, get_src(ctx, instr->src[0]),
+                                              mask & 0x3, (mask >> 2) & 0x3,
+                                              (mask >> 4) & 0x3, (mask >> 6) & 0x3);
+               break;
+       }
+       case nir_intrinsic_masked_swizzle_amd: {
+               uint32_t mask = nir_intrinsic_swizzle_mask(instr);
+               result = ac_build_ds_swizzle(&ctx->ac, get_src(ctx, instr->src[0]), mask);
+               break;
+       }
+       case nir_intrinsic_write_invocation_amd:
+               result = ac_build_writelane(&ctx->ac, get_src(ctx, instr->src[0]),
+                                           get_src(ctx, instr->src[1]),
+                                           get_src(ctx, instr->src[2]));
+               break;
+       case nir_intrinsic_mbcnt_amd:
+               result = ac_build_mbcnt(&ctx->ac, get_src(ctx, instr->src[0]));
+               break;
+       case nir_intrinsic_load_scratch: {
+               LLVMValueRef offset = get_src(ctx, instr->src[0]);
+               LLVMValueRef ptr = ac_build_gep0(&ctx->ac, ctx->scratch,
+                                                offset);
+               LLVMTypeRef comp_type =
+                       LLVMIntTypeInContext(ctx->ac.context, instr->dest.ssa.bit_size);
+               LLVMTypeRef vec_type =
+                       instr->dest.ssa.num_components == 1 ? comp_type :
+                       LLVMVectorType(comp_type, instr->dest.ssa.num_components);
+               unsigned addr_space = LLVMGetPointerAddressSpace(LLVMTypeOf(ptr));
+               ptr = LLVMBuildBitCast(ctx->ac.builder, ptr,
+                                      LLVMPointerType(vec_type, addr_space), "");
+               result = LLVMBuildLoad(ctx->ac.builder, ptr, "");
+               break;
+       }
+       case nir_intrinsic_store_scratch: {
+               LLVMValueRef offset = get_src(ctx, instr->src[1]);
+               LLVMValueRef ptr = ac_build_gep0(&ctx->ac, ctx->scratch,
+                                                offset);
+               LLVMTypeRef comp_type =
+                       LLVMIntTypeInContext(ctx->ac.context, instr->src[0].ssa->bit_size);
+               unsigned addr_space = LLVMGetPointerAddressSpace(LLVMTypeOf(ptr));
+               ptr = LLVMBuildBitCast(ctx->ac.builder, ptr,
+                                      LLVMPointerType(comp_type, addr_space), "");
+               LLVMValueRef src = get_src(ctx, instr->src[0]);
+               unsigned wrmask = nir_intrinsic_write_mask(instr);
+               while (wrmask) {
+                       int start, count;
+                       u_bit_scan_consecutive_range(&wrmask, &start, &count);
+                       
+                       LLVMValueRef offset = LLVMConstInt(ctx->ac.i32, start, false);
+                       LLVMValueRef offset_ptr = LLVMBuildGEP(ctx->ac.builder, ptr, &offset, 1, "");
+                       LLVMTypeRef vec_type =
+                               count == 1 ? comp_type : LLVMVectorType(comp_type, count);
+                       offset_ptr = LLVMBuildBitCast(ctx->ac.builder,
+                                                     offset_ptr,
+                                                     LLVMPointerType(vec_type, addr_space),
+                                                     "");
+                       LLVMValueRef offset_src =
+                               ac_extract_components(&ctx->ac, src, start, count);
+                       LLVMBuildStore(ctx->ac.builder, offset_src, offset_ptr);
+               }
+               break;
+       }
        default:
                fprintf(stderr, "Unknown intrinsic: ");
                nir_print_instr(&instr->instr, stderr);
@@ -3403,7 +3689,7 @@ static LLVMValueRef get_bindless_index_from_uniform(struct ac_nir_context *ctx,
        LLVMValueRef ubo_index = ctx->abi->load_ubo(ctx->abi, ctx->ac.i32_0);
 
        LLVMValueRef ret = ac_build_buffer_load(&ctx->ac, ubo_index, 1, NULL, offset,
-                                               NULL, 0, false, false, true, true);
+                                               NULL, 0, 0, true, true);
 
        return LLVMBuildBitCast(ctx->ac.builder, ret, ctx->ac.i32, "");
 }
@@ -3411,7 +3697,7 @@ static LLVMValueRef get_bindless_index_from_uniform(struct ac_nir_context *ctx,
 static LLVMValueRef get_sampler_desc(struct ac_nir_context *ctx,
                                     nir_deref_instr *deref_instr,
                                     enum ac_descriptor_type desc_type,
-                                    const nir_tex_instr *tex_instr,
+                                    const nir_instr *instr,
                                     bool image, bool write)
 {
        LLVMValueRef index = NULL;
@@ -3421,9 +3707,25 @@ static LLVMValueRef get_sampler_desc(struct ac_nir_context *ctx,
        bool bindless = false;
 
        if (!deref_instr) {
-               assert(tex_instr && !image);
                descriptor_set = 0;
-               base_index = tex_instr->sampler_index;
+               if (image) {
+                       nir_intrinsic_instr *img_instr = nir_instr_as_intrinsic(instr);
+                       base_index = 0;
+                       bindless = true;
+                       index = get_src(ctx, img_instr->src[0]);
+               } else {
+                       nir_tex_instr *tex_instr = nir_instr_as_tex(instr);
+                       int sampSrcIdx = nir_tex_instr_src_index(tex_instr,
+                                                                nir_tex_src_sampler_handle);
+                       if (sampSrcIdx != -1) {
+                               base_index = 0;
+                               bindless = true;
+                               index = get_src(ctx, tex_instr->src[sampSrcIdx].src);
+                       } else {
+                               assert(tex_instr && !image);
+                               base_index = tex_instr->sampler_index;
+                       }
+               }
        } else {
                while(deref_instr->deref_type != nir_deref_type_var) {
                        if (deref_instr->deref_type == nir_deref_type_array) {
@@ -3431,9 +3733,8 @@ static LLVMValueRef get_sampler_desc(struct ac_nir_context *ctx,
                                if (!array_size)
                                        array_size = 1;
 
-                               nir_const_value *const_value = nir_src_as_const_value(deref_instr->arr.index);
-                               if (const_value) {
-                                       constant_index += array_size * const_value->u32[0];
+                               if (nir_src_is_const(deref_instr->arr.index)) {
+                                       constant_index += array_size * nir_src_as_uint(deref_instr->arr.index);
                                } else {
                                        LLVMValueRef indirect = get_src(ctx, deref_instr->arr.index);
 
@@ -3480,13 +3781,13 @@ static LLVMValueRef get_sampler_desc(struct ac_nir_context *ctx,
 
 /* Disable anisotropic filtering if BASE_LEVEL == LAST_LEVEL.
  *
- * SI-CI:
+ * GFX6-GFX7:
  *   If BASE_LEVEL == LAST_LEVEL, the shader must disable anisotropic
  *   filtering manually. The driver sets img7 to a mask clearing
  *   MAX_ANISO_RATIO if BASE_LEVEL == LAST_LEVEL. The shader must do:
  *     s_and_b32 samp0, samp0, img7
  *
- * VI:
+ * GFX8:
  *   The ANISO_OVERRIDE sampler field enables this fix in TA.
  */
 static LLVMValueRef sici_fix_sampler_aniso(struct ac_nir_context *ctx,
@@ -3495,7 +3796,7 @@ static LLVMValueRef sici_fix_sampler_aniso(struct ac_nir_context *ctx,
        LLVMBuilderRef builder = ctx->ac.builder;
        LLVMValueRef img7, samp0;
 
-       if (ctx->ac.chip_class >= VI)
+       if (ctx->ac.chip_class >= GFX8)
                return samp;
 
        img7 = LLVMBuildExtractElement(builder, res,
@@ -3514,6 +3815,7 @@ static void tex_fetch_ptrs(struct ac_nir_context *ctx,
 {
        nir_deref_instr *texture_deref_instr = NULL;
        nir_deref_instr *sampler_deref_instr = NULL;
+       int plane = -1;
 
        for (unsigned i = 0; i < instr->num_srcs; i++) {
                switch (instr->src[i].src_type) {
@@ -3523,6 +3825,9 @@ static void tex_fetch_ptrs(struct ac_nir_context *ctx,
                case nir_tex_src_sampler_deref:
                        sampler_deref_instr = nir_src_as_deref(instr->src[i].src);
                        break;
+               case nir_tex_src_plane:
+                       plane = nir_src_as_int(instr->src[i].src);
+                       break;
                default:
                        break;
                }
@@ -3531,18 +3836,26 @@ static void tex_fetch_ptrs(struct ac_nir_context *ctx,
        if (!sampler_deref_instr)
                sampler_deref_instr = texture_deref_instr;
 
-       if (instr->sampler_dim  == GLSL_SAMPLER_DIM_BUF)
-               *res_ptr = get_sampler_desc(ctx, texture_deref_instr, AC_DESC_BUFFER, instr, false, false);
-       else
-               *res_ptr = get_sampler_desc(ctx, texture_deref_instr, AC_DESC_IMAGE, instr, false, false);
+       enum ac_descriptor_type main_descriptor = instr->sampler_dim  == GLSL_SAMPLER_DIM_BUF ? AC_DESC_BUFFER : AC_DESC_IMAGE;
+
+       if (plane >= 0) {
+               assert(instr->op != nir_texop_txf_ms &&
+                      instr->op != nir_texop_samples_identical);
+               assert(instr->sampler_dim  != GLSL_SAMPLER_DIM_BUF);
+
+               main_descriptor = AC_DESC_PLANE_0 + plane;
+       }
+
+       *res_ptr = get_sampler_desc(ctx, texture_deref_instr, main_descriptor, &instr->instr, false, false);
+
        if (samp_ptr) {
-               *samp_ptr = get_sampler_desc(ctx, sampler_deref_instr, AC_DESC_SAMPLER, instr, false, false);
+               *samp_ptr = get_sampler_desc(ctx, sampler_deref_instr, AC_DESC_SAMPLER, &instr->instr, false, false);
                if (instr->sampler_dim < GLSL_SAMPLER_DIM_RECT)
                        *samp_ptr = sici_fix_sampler_aniso(ctx, *res_ptr, *samp_ptr);
        }
        if (fmask_ptr && (instr->op == nir_texop_txf_ms ||
                          instr->op == nir_texop_samples_identical))
-               *fmask_ptr = get_sampler_desc(ctx, texture_deref_instr, AC_DESC_FMASK, instr, false, false);
+               *fmask_ptr = get_sampler_desc(ctx, texture_deref_instr, AC_DESC_FMASK, &instr->instr, false, false);
 }
 
 static LLVMValueRef apply_round_slice(struct ac_llvm_context *ctx,
@@ -3587,9 +3900,7 @@ static void visit_tex(struct ac_nir_context *ctx, nir_tex_instr *instr)
                                args.bias = get_src(ctx, instr->src[i].src);
                        break;
                case nir_tex_src_lod: {
-                       nir_const_value *val = nir_src_as_const_value(instr->src[i].src);
-
-                       if (val && val->i32[0] == 0)
+                       if (nir_src_is_const(instr->src[i].src) && nir_src_as_uint(instr->src[i].src) == 0)
                                args.level_zero = true;
                        else
                                args.lod = get_src(ctx, instr->src[i].src);
@@ -3643,7 +3954,7 @@ static void visit_tex(struct ac_nir_context *ctx, nir_tex_instr *instr)
                goto write_result;
        }
 
-       if (args.offset && instr->op != nir_texop_txf) {
+       if (args.offset && instr->op != nir_texop_txf && instr->op != nir_texop_txf_ms) {
                LLVMValueRef offset[3], pack;
                for (unsigned chan = 0; chan < 3; ++chan)
                        offset[chan] = ctx->ac.i32_0;
@@ -3664,12 +3975,16 @@ static void visit_tex(struct ac_nir_context *ctx, nir_tex_instr *instr)
 
        /* TC-compatible HTILE on radeonsi promotes Z16 and Z24 to Z32_FLOAT,
         * so the depth comparison value isn't clamped for Z16 and
-        * Z24 anymore. Do it manually here.
+        * Z24 anymore. Do it manually here for GFX8-9; GFX10 has an explicitly
+        * clamped 32-bit float format.
         *
         * It's unnecessary if the original texture format was
         * Z32_FLOAT, but we don't know that here.
         */
-       if (args.compare && ctx->ac.chip_class >= VI && ctx->abi->clamp_shadow_reference)
+       if (args.compare &&
+           ctx->ac.chip_class >= GFX8 &&
+           ctx->ac.chip_class <= GFX9 &&
+           ctx->abi->clamp_shadow_reference)
                args.compare = ac_build_clamp(&ctx->ac, ac_to_float(&ctx->ac, args.compare));
 
        /* pack derivatives */
@@ -3688,7 +4003,7 @@ static void visit_tex(struct ac_nir_context *ctx, nir_tex_instr *instr)
                        break;
                case GLSL_SAMPLER_DIM_1D:
                        num_src_deriv_channels = 1;
-                       if (ctx->ac.chip_class >= GFX9) {
+                       if (ctx->ac.chip_class == GFX9) {
                                num_dest_deriv_channels = 2;
                        } else {
                                num_dest_deriv_channels = 1;
@@ -3736,7 +4051,7 @@ static void visit_tex(struct ac_nir_context *ctx, nir_tex_instr *instr)
                args.coords[2] = apply_round_slice(&ctx->ac, args.coords[2]);
        }
 
-       if (ctx->ac.chip_class >= GFX9 &&
+       if (ctx->ac.chip_class == GFX9 &&
            instr->sampler_dim == GLSL_SAMPLER_DIM_1D &&
            instr->op != nir_texop_lod) {
                LLVMValueRef filler;
@@ -3768,7 +4083,8 @@ static void visit_tex(struct ac_nir_context *ctx, nir_tex_instr *instr)
                goto write_result;
        }
 
-       if (instr->sampler_dim == GLSL_SAMPLER_DIM_MS &&
+       if ((instr->sampler_dim == GLSL_SAMPLER_DIM_SUBPASS_MS ||
+            instr->sampler_dim == GLSL_SAMPLER_DIM_MS) &&
            instr->op != nir_texop_txs) {
                unsigned sample_chan = instr->is_array ? 3 : 2;
                args.coords[sample_chan] = adjust_sample_index_using_fmask(
@@ -3777,21 +4093,24 @@ static void visit_tex(struct ac_nir_context *ctx, nir_tex_instr *instr)
                        args.coords[sample_chan], fmask_ptr);
        }
 
-       if (args.offset && instr->op == nir_texop_txf) {
-               nir_const_value *const_offset =
-                       nir_src_as_const_value(instr->src[offset_src].src);
+       if (args.offset && (instr->op == nir_texop_txf || instr->op == nir_texop_txf_ms)) {
                int num_offsets = instr->src[offset_src].src.ssa->num_components;
-               assert(const_offset);
                num_offsets = MIN2(num_offsets, instr->coord_components);
                for (unsigned i = 0; i < num_offsets; ++i) {
                        args.coords[i] = LLVMBuildAdd(
                                ctx->ac.builder, args.coords[i],
-                               LLVMConstInt(ctx->ac.i32, const_offset->i32[i], false), "");
+                               LLVMConstInt(ctx->ac.i32, nir_src_comp_as_uint(instr->src[offset_src].src, i), false), "");
                }
                args.offset = NULL;
        }
 
-       /* TODO TG4 support */
+       /* DMASK was repurposed for GATHER4. 4 components are always
+        * returned and DMASK works like a swizzle - it selects
+        * the component to fetch. The only valid DMASK values are
+        * 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
+        * (red,red,red,red) etc.) The ISA document doesn't mention
+        * this.
+        */
        args.dmask = 0xf;
        if (instr->op == nir_texop_tg4) {
                if (instr->is_shadow)
@@ -3818,7 +4137,7 @@ static void visit_tex(struct ac_nir_context *ctx, nir_tex_instr *instr)
                LLVMValueRef z = LLVMBuildExtractElement(ctx->ac.builder, result, two, "");
                z = LLVMBuildSDiv(ctx->ac.builder, z, six, "");
                result = LLVMBuildInsertElement(ctx->ac.builder, result, z, two, "");
-       } else if (ctx->ac.chip_class >= GFX9 &&
+       } else if (ctx->ac.chip_class == GFX9 &&
                   instr->op == nir_texop_txs &&
                   instr->sampler_dim == GLSL_SAMPLER_DIM_1D &&
                   instr->is_array) {
@@ -3911,6 +4230,9 @@ glsl_base_to_llvm_type(struct ac_llvm_context *ac,
        case GLSL_TYPE_BOOL:
        case GLSL_TYPE_SUBROUTINE:
                return ac->i32;
+       case GLSL_TYPE_INT8:
+       case GLSL_TYPE_UINT8:
+               return ac->i8;
        case GLSL_TYPE_INT16:
        case GLSL_TYPE_UINT16:
                return ac->i16;
@@ -4080,7 +4402,6 @@ static void visit_cf_list(struct ac_nir_context *ctx,
 
 static void visit_block(struct ac_nir_context *ctx, nir_block *block)
 {
-       LLVMBasicBlockRef llvm_block = LLVMGetInsertBlock(ctx->ac.builder);
        nir_foreach_instr(instr, block)
        {
                switch (instr->type) {
@@ -4116,7 +4437,8 @@ static void visit_block(struct ac_nir_context *ctx, nir_block *block)
                }
        }
 
-       _mesa_hash_table_insert(ctx->defs, block, llvm_block);
+       _mesa_hash_table_insert(ctx->defs, block,
+                               LLVMGetInsertBlock(ctx->ac.builder));
 }
 
 static void visit_if(struct ac_nir_context *ctx, nir_if *if_stmt)
@@ -4240,6 +4562,18 @@ setup_locals(struct ac_nir_context *ctx,
        }
 }
 
+static void
+setup_scratch(struct ac_nir_context *ctx,
+             struct nir_shader *shader)
+{
+       if (shader->scratch_size == 0)
+               return;
+
+       ctx->scratch = ac_build_alloca_undef(&ctx->ac,
+                                            LLVMArrayType(ctx->ac.i8, shader->scratch_size),
+                                            "scratch");
+}
+
 static void
 setup_shared(struct ac_nir_context *ctx,
             struct nir_shader *nir)
@@ -4264,6 +4598,7 @@ void ac_nir_translate(struct ac_llvm_context *ac, struct ac_shader_abi *abi,
        ctx.abi = abi;
 
        ctx.stage = nir->info.stage;
+       ctx.info = &nir->info;
 
        ctx.main_function = LLVMGetBasicBlockParent(LLVMGetInsertBlock(ctx.ac.builder));
 
@@ -4284,6 +4619,7 @@ void ac_nir_translate(struct ac_llvm_context *ac, struct ac_shader_abi *abi,
        ctx.ssa_defs = calloc(func->impl->ssa_alloc, sizeof(LLVMValueRef));
 
        setup_locals(&ctx, func);
+       setup_scratch(&ctx, nir);
 
        if (gl_shader_stage_is_compute(nir->info.stage))
                setup_shared(&ctx, nir);
@@ -4305,11 +4641,19 @@ void ac_nir_translate(struct ac_llvm_context *ac, struct ac_shader_abi *abi,
 void
 ac_lower_indirect_derefs(struct nir_shader *nir, enum chip_class chip_class)
 {
+       /* Lower large variables to scratch first so that we won't bloat the
+        * shader by generating large if ladders for them. We later lower
+        * scratch to alloca's, assuming LLVM won't generate VGPR indexing.
+        */
+       NIR_PASS_V(nir, nir_lower_vars_to_scratch,
+                  nir_var_function_temp,
+                  256,
+                  glsl_get_natural_size_align_bytes);
+
        /* While it would be nice not to have this flag, we are constrained
-        * by the reality that LLVM 5.0 doesn't have working VGPR indexing
-        * on GFX9.
+        * by the reality that LLVM 9.0 has buggy VGPR indexing on GFX9.
         */
-       bool llvm_has_working_vgpr_indexing = chip_class <= VI;
+       bool llvm_has_working_vgpr_indexing = chip_class != GFX9;
 
        /* TODO: Indirect indexing of GS inputs is unimplemented.
         *