[Mesa-dev] [PATCH 01/11] radeonsi: use ac helpers for bitcasts

Marek Olšák maraeo at gmail.com
Fri Sep 29 14:49:45 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

---
 src/gallium/drivers/radeonsi/si_shader.c           | 147 ++++++++-------------
 src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c  |  14 +-
 src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c  |  38 +++---
 .../drivers/radeonsi/si_shader_tgsi_setup.c        |  14 +-
 4 files changed, 86 insertions(+), 127 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 71f0f4a..c420573 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -252,22 +252,21 @@ build_phi(struct ac_llvm_context *ctx, LLVMTypeRef type,
  */
 static LLVMValueRef unpack_param(struct si_shader_context *ctx,
 				 unsigned param, unsigned rshift,
 				 unsigned bitwidth)
 {
 	struct gallivm_state *gallivm = &ctx->gallivm;
 	LLVMValueRef value = LLVMGetParam(ctx->main_fn,
 					  param);
 
 	if (LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMFloatTypeKind)
-		value = bitcast(&ctx->bld_base,
-				TGSI_TYPE_UNSIGNED, value);
+		value = ac_to_integer(&ctx->ac, value);
 
 	if (rshift)
 		value = LLVMBuildLShr(gallivm->builder, value,
 				      LLVMConstInt(ctx->i32, rshift, 0), "");
 
 	if (rshift + bitwidth < 32) {
 		unsigned mask = (1 << bitwidth) - 1;
 		value = LLVMBuildAnd(gallivm->builder, value,
 				     LLVMConstInt(ctx->i32, mask, 0), "");
 	}
@@ -553,21 +552,21 @@ void si_llvm_load_input_vs(
 		/* The hardware returns an unsigned value; convert it to a
 		 * signed one.
 		 */
 		LLVMValueRef tmp = out[3];
 		LLVMValueRef c30 = LLVMConstInt(ctx->i32, 30, 0);
 
 		/* First, recover the sign-extended signed integer value. */
 		if (fix_fetch == SI_FIX_FETCH_A2_SSCALED)
 			tmp = LLVMBuildFPToUI(gallivm->builder, tmp, ctx->i32, "");
 		else
-			tmp = LLVMBuildBitCast(gallivm->builder, tmp, ctx->i32, "");
+			tmp = ac_to_integer(&ctx->ac, tmp);
 
 		/* For the integer-like cases, do a natural sign extension.
 		 *
 		 * For the SNORM case, the values are 0.0, 0.333, 0.666, 1.0
 		 * and happen to contain 0, 1, 2, 3 as the two LSBs of the
 		 * exponent.
 		 */
 		tmp = LLVMBuildShl(gallivm->builder, tmp,
 				   fix_fetch == SI_FIX_FETCH_A2_SNORM ?
 				   LLVMConstInt(ctx->i32, 7, 0) : c30, "");
@@ -583,67 +582,63 @@ void si_llvm_load_input_vs(
 		} else if (fix_fetch == SI_FIX_FETCH_A2_SSCALED) {
 			tmp = LLVMBuildSIToFP(gallivm->builder, tmp, ctx->f32, "");
 		}
 
 		out[3] = tmp;
 		break;
 	}
 	case SI_FIX_FETCH_RGBA_32_UNORM:
 	case SI_FIX_FETCH_RGBX_32_UNORM:
 		for (chan = 0; chan < 4; chan++) {
-			out[chan] = LLVMBuildBitCast(gallivm->builder, out[chan],
-						     ctx->i32, "");
+			out[chan] = ac_to_integer(&ctx->ac, out[chan]);
 			out[chan] = LLVMBuildUIToFP(gallivm->builder,
 						    out[chan], ctx->f32, "");
 			out[chan] = LLVMBuildFMul(gallivm->builder, out[chan],
 						  LLVMConstReal(ctx->f32, 1.0 / UINT_MAX), "");
 		}
 		/* RGBX UINT returns 1 in alpha, which would be rounded to 0 by normalizing. */
 		if (fix_fetch == SI_FIX_FETCH_RGBX_32_UNORM)
 			out[3] = LLVMConstReal(ctx->f32, 1);
 		break;
 	case SI_FIX_FETCH_RGBA_32_SNORM:
 	case SI_FIX_FETCH_RGBX_32_SNORM:
 	case SI_FIX_FETCH_RGBA_32_FIXED:
 	case SI_FIX_FETCH_RGBX_32_FIXED: {
 		double scale;
 		if (fix_fetch >= SI_FIX_FETCH_RGBA_32_FIXED)
 			scale = 1.0 / 0x10000;
 		else
 			scale = 1.0 / INT_MAX;
 
 		for (chan = 0; chan < 4; chan++) {
-			out[chan] = LLVMBuildBitCast(gallivm->builder, out[chan],
-						     ctx->i32, "");
+			out[chan] = ac_to_integer(&ctx->ac, out[chan]);
 			out[chan] = LLVMBuildSIToFP(gallivm->builder,
 						    out[chan], ctx->f32, "");
 			out[chan] = LLVMBuildFMul(gallivm->builder, out[chan],
 						  LLVMConstReal(ctx->f32, scale), "");
 		}
 		/* RGBX SINT returns 1 in alpha, which would be rounded to 0 by normalizing. */
 		if (fix_fetch == SI_FIX_FETCH_RGBX_32_SNORM ||
 		    fix_fetch == SI_FIX_FETCH_RGBX_32_FIXED)
 			out[3] = LLVMConstReal(ctx->f32, 1);
 		break;
 	}
 	case SI_FIX_FETCH_RGBA_32_USCALED:
 		for (chan = 0; chan < 4; chan++) {
-			out[chan] = LLVMBuildBitCast(gallivm->builder, out[chan],
-						     ctx->i32, "");
+			out[chan] = ac_to_integer(&ctx->ac, out[chan]);
 			out[chan] = LLVMBuildUIToFP(gallivm->builder,
 						    out[chan], ctx->f32, "");
 		}
 		break;
 	case SI_FIX_FETCH_RGBA_32_SSCALED:
 		for (chan = 0; chan < 4; chan++) {
-			out[chan] = LLVMBuildBitCast(gallivm->builder, out[chan],
-						     ctx->i32, "");
+			out[chan] = ac_to_integer(&ctx->ac, out[chan]);
 			out[chan] = LLVMBuildSIToFP(gallivm->builder,
 						    out[chan], ctx->f32, "");
 		}
 		break;
 	case SI_FIX_FETCH_RG_64_FLOAT:
 		for (chan = 0; chan < 2; chan++)
 			out[chan] = extract_double_to_float(ctx, input[0], chan);
 
 		out[2] = LLVMConstReal(ctx->f32, 0);
 		out[3] = LLVMConstReal(ctx->f32, 1);
@@ -666,22 +661,21 @@ void si_llvm_load_input_vs(
 	case SI_FIX_FETCH_RGB_16_INT:
 		for (chan = 0; chan < 3; chan++) {
 			out[chan] = LLVMBuildExtractElement(gallivm->builder,
 							    input[chan],
 							    ctx->i32_0, "");
 		}
 		if (fix_fetch == SI_FIX_FETCH_RGB_8 ||
 		    fix_fetch == SI_FIX_FETCH_RGB_16) {
 			out[3] = LLVMConstReal(ctx->f32, 1);
 		} else {
-			out[3] = LLVMBuildBitCast(gallivm->builder, ctx->i32_1,
-						  ctx->f32, "");
+			out[3] = ac_to_float(&ctx->ac, ctx->i32_1);
 		}
 		break;
 	}
 }
 
 static void declare_input_vs(
 	struct si_shader_context *ctx,
 	unsigned input_index,
 	const struct tgsi_full_declaration *decl,
 	LLVMValueRef out[4])
@@ -1066,26 +1060,25 @@ static LLVMValueRef lds_load(struct lp_build_tgsi_context *bld_base,
  *
  * \param swizzle	offset (typically 0..3)
  * \param dw_addr	address in dwords
  * \param value		value to store
  */
 static void lds_store(struct lp_build_tgsi_context *bld_base,
 		      unsigned dw_offset_imm, LLVMValueRef dw_addr,
 		      LLVMValueRef value)
 {
 	struct si_shader_context *ctx = si_shader_context(bld_base);
-	struct gallivm_state *gallivm = &ctx->gallivm;
 
 	dw_addr = lp_build_add(&bld_base->uint_bld, dw_addr,
 			    LLVMConstInt(ctx->i32, dw_offset_imm, 0));
 
-	value = LLVMBuildBitCast(gallivm->builder, value, ctx->i32, "");
+	value = ac_to_integer(&ctx->ac, value);
 	ac_build_indexed_store(&ctx->ac, ctx->lds,
 			       dw_addr, value);
 }
 
 static LLVMValueRef desc_from_addr_base64k(struct si_shader_context *ctx,
 						  unsigned param)
 {
 	LLVMBuilderRef builder = ctx->gallivm.builder;
 
 	LLVMValueRef addr = LLVMGetParam(ctx->main_fn, param);
@@ -1219,21 +1212,21 @@ static void store_output_tcs(struct lp_build_tgsi_context *bld_base,
 		chan_index = u_bit_scan(&writemask);
 		LLVMValueRef value = dst[chan_index];
 
 		if (inst->Instruction.Saturate)
 			value = ac_build_clamp(&ctx->ac, value);
 
 		/* Skip LDS stores if there is no LDS read of this output. */
 		if (!skip_lds_store)
 			lds_store(bld_base, chan_index, dw_addr, value);
 
-		value = LLVMBuildBitCast(gallivm->builder, value, ctx->i32, "");
+		value = ac_to_integer(&ctx->ac, value);
 		values[chan_index] = value;
 
 		if (reg->Register.WriteMask != 0xF && !is_tess_factor) {
 			ac_build_buffer_store_dword(&ctx->ac, buffer, value, 1,
 						    buf_addr, base,
 						    4 * chan_index, 1, 0, true, false);
 		}
 
 		/* Write tess factors into VGPRs for the epilog. */
 		if (is_tess_factor &&
@@ -2079,42 +2072,38 @@ static void si_llvm_init_export_args(struct lp_build_tgsi_context *bld_base,
 		args->compr = 1; /* COMPR flag */
 
 		for (chan = 0; chan < 2; chan++) {
 			LLVMValueRef pack_args[2] = {
 				values[2 * chan],
 				values[2 * chan + 1]
 			};
 			LLVMValueRef packed;
 
 			packed = ac_build_cvt_pkrtz_f16(&ctx->ac, pack_args);
-			args->out[chan] =
-				LLVMBuildBitCast(ctx->gallivm.builder,
-						 packed, ctx->f32, "");
+			args->out[chan] = ac_to_float(&ctx->ac, packed);
 		}
 		break;
 
 	case V_028714_SPI_SHADER_UNORM16_ABGR:
 		for (chan = 0; chan < 4; chan++) {
 			val[chan] = ac_build_clamp(&ctx->ac, values[chan]);
 			val[chan] = LLVMBuildFMul(builder, val[chan],
 						  LLVMConstReal(ctx->f32, 65535), "");
 			val[chan] = LLVMBuildFAdd(builder, val[chan],
 						  LLVMConstReal(ctx->f32, 0.5), "");
 			val[chan] = LLVMBuildFPToUI(builder, val[chan],
 						    ctx->i32, "");
 		}
 
 		args->compr = 1; /* COMPR flag */
-		args->out[0] = bitcast(bld_base, TGSI_TYPE_FLOAT,
-				  si_llvm_pack_two_int16(ctx, val));
-		args->out[1] = bitcast(bld_base, TGSI_TYPE_FLOAT,
-				  si_llvm_pack_two_int16(ctx, val+2));
+		args->out[0] = ac_to_float(&ctx->ac, si_llvm_pack_two_int16(ctx, val));
+		args->out[1] = ac_to_float(&ctx->ac, si_llvm_pack_two_int16(ctx, val+2));
 		break;
 
 	case V_028714_SPI_SHADER_SNORM16_ABGR:
 		for (chan = 0; chan < 4; chan++) {
 			/* Clamp between [-1, 1]. */
 			val[chan] = lp_build_emit_llvm_binary(bld_base, TGSI_OPCODE_MIN,
 							      values[chan],
 							      LLVMConstReal(ctx->f32, 1));
 			val[chan] = lp_build_emit_llvm_binary(bld_base, TGSI_OPCODE_MAX,
 							      val[chan],
@@ -2126,74 +2115,68 @@ static void si_llvm_init_export_args(struct lp_build_tgsi_context *bld_base,
 			val[chan] = LLVMBuildFAdd(builder, val[chan],
 					LLVMBuildSelect(builder,
 						LLVMBuildFCmp(builder, LLVMRealOGE,
 							      val[chan], base->zero, ""),
 						LLVMConstReal(ctx->f32, 0.5),
 						LLVMConstReal(ctx->f32, -0.5), ""), "");
 			val[chan] = LLVMBuildFPToSI(builder, val[chan], ctx->i32, "");
 		}
 
 		args->compr = 1; /* COMPR flag */
-		args->out[0] = bitcast(bld_base, TGSI_TYPE_FLOAT,
-				  si_llvm_pack_two_int32_as_int16(ctx, val));
-		args->out[1] = bitcast(bld_base, TGSI_TYPE_FLOAT,
-				  si_llvm_pack_two_int32_as_int16(ctx, val+2));
+		args->out[0] = ac_to_float(&ctx->ac, si_llvm_pack_two_int32_as_int16(ctx, val));
+		args->out[1] = ac_to_float(&ctx->ac, si_llvm_pack_two_int32_as_int16(ctx, val+2));
 		break;
 
 	case V_028714_SPI_SHADER_UINT16_ABGR: {
 		LLVMValueRef max_rgb = LLVMConstInt(ctx->i32,
 			is_int8 ? 255 : is_int10 ? 1023 : 65535, 0);
 		LLVMValueRef max_alpha =
 			!is_int10 ? max_rgb : LLVMConstInt(ctx->i32, 3, 0);
 
 		/* Clamp. */
 		for (chan = 0; chan < 4; chan++) {
-			val[chan] = bitcast(bld_base, TGSI_TYPE_UNSIGNED, values[chan]);
+			val[chan] = ac_to_integer(&ctx->ac, values[chan]);
 			val[chan] = lp_build_emit_llvm_binary(bld_base, TGSI_OPCODE_UMIN,
 					val[chan],
 					chan == 3 ? max_alpha : max_rgb);
 		}
 
 		args->compr = 1; /* COMPR flag */
-		args->out[0] = bitcast(bld_base, TGSI_TYPE_FLOAT,
-				  si_llvm_pack_two_int16(ctx, val));
-		args->out[1] = bitcast(bld_base, TGSI_TYPE_FLOAT,
-				  si_llvm_pack_two_int16(ctx, val+2));
+		args->out[0] = ac_to_float(&ctx->ac, si_llvm_pack_two_int16(ctx, val));
+		args->out[1] = ac_to_float(&ctx->ac, si_llvm_pack_two_int16(ctx, val+2));
 		break;
 	}
 
 	case V_028714_SPI_SHADER_SINT16_ABGR: {
 		LLVMValueRef max_rgb = LLVMConstInt(ctx->i32,
 			is_int8 ? 127 : is_int10 ? 511 : 32767, 0);
 		LLVMValueRef min_rgb = LLVMConstInt(ctx->i32,
 			is_int8 ? -128 : is_int10 ? -512 : -32768, 0);
 		LLVMValueRef max_alpha =
 			!is_int10 ? max_rgb : ctx->i32_1;
 		LLVMValueRef min_alpha =
 			!is_int10 ? min_rgb : LLVMConstInt(ctx->i32, -2, 0);
 
 		/* Clamp. */
 		for (chan = 0; chan < 4; chan++) {
-			val[chan] = bitcast(bld_base, TGSI_TYPE_UNSIGNED, values[chan]);
+			val[chan] = ac_to_integer(&ctx->ac, values[chan]);
 			val[chan] = lp_build_emit_llvm_binary(bld_base,
 					TGSI_OPCODE_IMIN,
 					val[chan], chan == 3 ? max_alpha : max_rgb);
 			val[chan] = lp_build_emit_llvm_binary(bld_base,
 					TGSI_OPCODE_IMAX,
 					val[chan], chan == 3 ? min_alpha : min_rgb);
 		}
 
 		args->compr = 1; /* COMPR flag */
-		args->out[0] = bitcast(bld_base, TGSI_TYPE_FLOAT,
-				  si_llvm_pack_two_int32_as_int16(ctx, val));
-		args->out[1] = bitcast(bld_base, TGSI_TYPE_FLOAT,
-				  si_llvm_pack_two_int32_as_int16(ctx, val+2));
+		args->out[0] = ac_to_float(&ctx->ac, si_llvm_pack_two_int32_as_int16(ctx, val));
+		args->out[1] = ac_to_float(&ctx->ac, si_llvm_pack_two_int32_as_int16(ctx, val+2));
 		break;
 	}
 
 	case V_028714_SPI_SHADER_32_ABGR:
 		memcpy(&args->out[0], values, sizeof(values[0]) * 4);
 		break;
 	}
 }
 
 static void si_alpha_test(struct lp_build_tgsi_context *bld_base,
@@ -2225,21 +2208,21 @@ static LLVMValueRef si_scale_alpha_by_sample_mask(struct lp_build_tgsi_context *
 						  LLVMValueRef alpha,
 						  unsigned samplemask_param)
 {
 	struct si_shader_context *ctx = si_shader_context(bld_base);
 	struct gallivm_state *gallivm = &ctx->gallivm;
 	LLVMValueRef coverage;
 
 	/* alpha = alpha * popcount(coverage) / SI_NUM_SMOOTH_AA_SAMPLES */
 	coverage = LLVMGetParam(ctx->main_fn,
 				samplemask_param);
-	coverage = bitcast(bld_base, TGSI_TYPE_SIGNED, coverage);
+	coverage = ac_to_integer(&ctx->ac, coverage);
 
 	coverage = lp_build_intrinsic(gallivm->builder, "llvm.ctpop.i32",
 				   ctx->i32,
 				   &coverage, 1, LP_FUNC_ATTR_READNONE);
 
 	coverage = LLVMBuildUIToFP(gallivm->builder, coverage,
 				   ctx->f32, "");
 
 	coverage = LLVMBuildFMul(gallivm->builder, coverage,
 				 LLVMConstReal(ctx->f32,
@@ -2328,23 +2311,21 @@ static void emit_streamout_output(struct si_shader_context *ctx,
 	LLVMValueRef out[4];
 
 	assert(num_comps && num_comps <= 4);
 	if (!num_comps || num_comps > 4)
 		return;
 
 	/* Load the output as int. */
 	for (int j = 0; j < num_comps; j++) {
 		assert(stream_out->stream == shader_out->vertex_stream[start + j]);
 
-		out[j] = LLVMBuildBitCast(builder,
-					  shader_out->values[start + j],
-				ctx->i32, "");
+		out[j] = ac_to_integer(&ctx->ac, shader_out->values[start + j]);
 	}
 
 	/* Pack the output. */
 	LLVMValueRef vdata = NULL;
 
 	switch (num_comps) {
 	case 1: /* as i32 */
 		vdata = out[0];
 		break;
 	case 2: /* as v2i32 */
@@ -2594,42 +2575,39 @@ static void si_llvm_export_vs(struct lp_build_tgsi_context *bld_base,
 			/* The output is a float, but the hw expects an integer
 			 * with the first bit containing the edge flag. */
 			edgeflag_value = LLVMBuildFPToUI(ctx->gallivm.builder,
 							 edgeflag_value,
 							 ctx->i32, "");
 			edgeflag_value = ac_build_umin(&ctx->ac,
 						      edgeflag_value,
 						      ctx->i32_1);
 
 			/* The LLVM intrinsic expects a float. */
-			pos_args[1].out[1] = LLVMBuildBitCast(ctx->gallivm.builder,
-							  edgeflag_value,
-							  ctx->f32, "");
+			pos_args[1].out[1] = ac_to_float(&ctx->ac, edgeflag_value);
 		}
 
 		if (ctx->screen->b.chip_class >= GFX9) {
 			/* GFX9 has the layer in out.z[10:0] and the viewport
 			 * index in out.z[19:16].
 			 */
 			if (shader->selector->info.writes_layer)
 				pos_args[1].out[2] = layer_value;
 
 			if (shader->selector->info.writes_viewport_index) {
 				LLVMValueRef v = viewport_index_value;
 
-				v = bitcast(bld_base, TGSI_TYPE_UNSIGNED, v);
+				v = ac_to_integer(&ctx->ac, v);
 				v = LLVMBuildShl(ctx->gallivm.builder, v,
 						 LLVMConstInt(ctx->i32, 16, 0), "");
 				v = LLVMBuildOr(ctx->gallivm.builder, v,
-						bitcast(bld_base, TGSI_TYPE_UNSIGNED,
-						        pos_args[1].out[2]), "");
-				pos_args[1].out[2] = bitcast(bld_base, TGSI_TYPE_FLOAT, v);
+						ac_to_integer(&ctx->ac,  pos_args[1].out[2]), "");
+				pos_args[1].out[2] = ac_to_float(&ctx->ac, v);
 				pos_args[1].enabled_channels |= 1 << 2;
 			}
 		} else {
 			if (shader->selector->info.writes_layer)
 				pos_args[1].out[2] = layer_value;
 
 			if (shader->selector->info.writes_viewport_index) {
 				pos_args[1].out[3] = viewport_index_value;
 				pos_args[1].enabled_channels |= 1 << 3;
 			}
@@ -2888,21 +2866,21 @@ si_insert_input_ret(struct si_shader_context *ctx, LLVMValueRef ret,
 }
 
 static LLVMValueRef
 si_insert_input_ret_float(struct si_shader_context *ctx, LLVMValueRef ret,
 			  unsigned param, unsigned return_index)
 {
 	LLVMBuilderRef builder = ctx->gallivm.builder;
 	LLVMValueRef p = LLVMGetParam(ctx->main_fn, param);
 
 	return LLVMBuildInsertValue(builder, ret,
-				    LLVMBuildBitCast(builder, p, ctx->f32, ""),
+				    ac_to_float(&ctx->ac, p),
 				    return_index, "");
 }
 
 static LLVMValueRef
 si_insert_input_ptr_as_2xi32(struct si_shader_context *ctx, LLVMValueRef ret,
 			     unsigned param, unsigned return_index)
 {
 	LLVMBuilderRef builder = ctx->gallivm.builder;
 	LLVMValueRef ptr, lo, hi;
 
@@ -2974,39 +2952,39 @@ static void si_llvm_emit_tcs_epilogue(struct lp_build_tgsi_context *bld_base)
 					  GFX6_SGPR_TCS_FACTOR_ADDR_BASE64K);
 		/* Tess offchip and tess factor offsets are after user SGPRs. */
 		ret = si_insert_input_ret(ctx, ret, ctx->param_tcs_offchip_offset,
 					  GFX6_TCS_NUM_USER_SGPR);
 		ret = si_insert_input_ret(ctx, ret, ctx->param_tcs_factor_offset,
 					  GFX6_TCS_NUM_USER_SGPR + 1);
 		vgpr = GFX6_TCS_NUM_USER_SGPR + 2;
 	}
 
 	/* VGPRs */
-	rel_patch_id = bitcast(bld_base, TGSI_TYPE_FLOAT, rel_patch_id);
-	invocation_id = bitcast(bld_base, TGSI_TYPE_FLOAT, invocation_id);
-	tf_lds_offset = bitcast(bld_base, TGSI_TYPE_FLOAT, tf_lds_offset);
+	rel_patch_id = ac_to_float(&ctx->ac, rel_patch_id);
+	invocation_id = ac_to_float(&ctx->ac, invocation_id);
+	tf_lds_offset = ac_to_float(&ctx->ac, tf_lds_offset);
 
 	/* Leave a hole corresponding to the two input VGPRs. This ensures that
 	 * the invocation_id output does not alias the param_tcs_rel_ids input,
 	 * which saves a V_MOV on gfx9.
 	 */
 	vgpr += 2;
 
 	ret = LLVMBuildInsertValue(builder, ret, rel_patch_id, vgpr++, "");
 	ret = LLVMBuildInsertValue(builder, ret, invocation_id, vgpr++, "");
 
 	if (ctx->shader->selector->tcs_info.tessfactors_are_def_in_all_invocs) {
 		vgpr++; /* skip the tess factor LDS offset */
 		for (unsigned i = 0; i < 6; i++) {
 			LLVMValueRef value =
 				LLVMBuildLoad(builder, ctx->invoc0_tess_factors[i], "");
-			value = bitcast(bld_base, TGSI_TYPE_FLOAT, value);
+			value = ac_to_float(&ctx->ac, value);
 			ret = LLVMBuildInsertValue(builder, ret, value, vgpr++, "");
 		}
 	} else {
 		ret = LLVMBuildInsertValue(builder, ret, tf_lds_offset, vgpr++, "");
 	}
 	ctx->return_value = ret;
 }
 
 /* Pass TCS inputs from LS to TCS on GFX9. */
 static void si_set_ls_return_value_for_tcs(struct si_shader_context *ctx)
@@ -3159,21 +3137,21 @@ static void si_llvm_emit_es_epilogue(struct lp_build_tgsi_context *bld_base)
 
 		if (info->output_semantic_name[i] == TGSI_SEMANTIC_VIEWPORT_INDEX ||
 		    info->output_semantic_name[i] == TGSI_SEMANTIC_LAYER)
 			continue;
 
 		param = si_shader_io_get_unique_index(info->output_semantic_name[i],
 						      info->output_semantic_index[i]);
 
 		for (chan = 0; chan < 4; chan++) {
 			LLVMValueRef out_val = LLVMBuildLoad(gallivm->builder, out_ptr[chan], "");
-			out_val = LLVMBuildBitCast(gallivm->builder, out_val, ctx->i32, "");
+			out_val = ac_to_integer(&ctx->ac, out_val);
 
 			/* GFX9 has the ESGS ring in LDS. */
 			if (ctx->screen->b.chip_class >= GFX9) {
 				lds_store(bld_base, param * 4 + chan, lds_base, out_val);
 				continue;
 			}
 
 			ac_build_buffer_store_dword(&ctx->ac,
 						    ctx->esgs_ring,
 						    out_val, 1, NULL, soffset,
@@ -3272,22 +3250,21 @@ static void si_llvm_emit_vs_epilogue(struct ac_shader_abi *abi,
 		}
 	}
 
 	if (ctx->shader->selector->so.num_outputs)
 		si_llvm_emit_streamout(ctx, outputs, i, 0);
 
 	/* Export PrimitiveID. */
 	if (ctx->shader->key.mono.u.vs_export_prim_id) {
 		outputs[i].semantic_name = TGSI_SEMANTIC_PRIMID;
 		outputs[i].semantic_index = 0;
-		outputs[i].values[0] = LLVMBuildBitCast(gallivm->builder,
-				get_primitive_id(ctx, 0), ctx->f32, "");
+		outputs[i].values[0] = ac_to_float(&ctx->ac, get_primitive_id(ctx, 0));
 		for (j = 1; j < 4; j++)
 			outputs[i].values[j] = LLVMConstReal(ctx->f32, 0);
 
 		memset(outputs[i].vertex_stream, 0,
 		       sizeof(outputs[i].vertex_stream));
 		i++;
 	}
 
 	si_llvm_export_vs(&ctx->bld_base, outputs, i);
 	FREE(outputs);
@@ -3350,24 +3327,24 @@ static void si_export_mrt_z(struct lp_build_tgsi_context *bld_base,
 	args.out[1] = base->undef; /* G, stencil test value[0:7], stencil op value[8:15] */
 	args.out[2] = base->undef; /* B, sample mask */
 	args.out[3] = base->undef; /* A, alpha to mask */
 
 	if (format == V_028710_SPI_SHADER_UINT16_ABGR) {
 		assert(!depth);
 		args.compr = 1; /* COMPR flag */
 
 		if (stencil) {
 			/* Stencil should be in X[23:16]. */
-			stencil = bitcast(bld_base, TGSI_TYPE_UNSIGNED, stencil);
+			stencil = ac_to_integer(&ctx->ac, stencil);
 			stencil = LLVMBuildShl(ctx->gallivm.builder, stencil,
 					       LLVMConstInt(ctx->i32, 16, 0), "");
-			args.out[0] = bitcast(bld_base, TGSI_TYPE_FLOAT, stencil);
+			args.out[0] = ac_to_float(&ctx->ac, stencil);
 			mask |= 0x3;
 		}
 		if (samplemask) {
 			/* SampleMask should be in Y[15:0]. */
 			args.out[1] = samplemask;
 			mask |= 0xc;
 		}
 	} else {
 		if (depth) {
 			args.out[0] = depth;
@@ -3549,24 +3526,23 @@ static void si_llvm_return_fs_outputs(struct ac_shader_abi *abi,
 			fprintf(stderr, "Warning: SI unhandled fs output type:%d\n",
 				semantic_name);
 		}
 	}
 
 	/* Fill the return structure. */
 	ret = ctx->return_value;
 
 	/* Set SGPRs. */
 	ret = LLVMBuildInsertValue(builder, ret,
-				   LLVMBuildBitCast(ctx->ac.builder,
-						LLVMGetParam(ctx->main_fn,
-							SI_PARAM_ALPHA_REF),
-						ctx->i32, ""),
+				   ac_to_integer(&ctx->ac,
+                                                 LLVMGetParam(ctx->main_fn,
+                                                              SI_PARAM_ALPHA_REF)),
 				   SI_SGPR_ALPHA_REF, "");
 
 	/* Set VGPRs */
 	first_vgpr = vgpr = SI_SGPR_ALPHA_REF + 1;
 	for (i = 0; i < ARRAY_SIZE(color); i++) {
 		if (!color[i][0])
 			continue;
 
 		for (j = 0; j < 4; j++)
 			ret = LLVMBuildInsertValue(builder, ret, color[i][j], vgpr++, "");
@@ -3648,37 +3624,36 @@ LLVMTypeRef si_const_array(LLVMTypeRef elem_type, int num_elements)
 	return LLVMPointerType(LLVMArrayType(elem_type, num_elements),
 			       CONST_ADDR_SPACE);
 }
 
 static void si_llvm_emit_ddxy(
 	const struct lp_build_tgsi_action *action,
 	struct lp_build_tgsi_context *bld_base,
 	struct lp_build_emit_data *emit_data)
 {
 	struct si_shader_context *ctx = si_shader_context(bld_base);
-	struct gallivm_state *gallivm = &ctx->gallivm;
 	unsigned opcode = emit_data->info->opcode;
 	LLVMValueRef val;
 	int idx;
 	unsigned mask;
 
 	if (opcode == TGSI_OPCODE_DDX_FINE)
 		mask = AC_TID_MASK_LEFT;
 	else if (opcode == TGSI_OPCODE_DDY_FINE)
 		mask = AC_TID_MASK_TOP;
 	else
 		mask = AC_TID_MASK_TOP_LEFT;
 
 	/* for DDX we want to next X pixel, DDY next Y pixel. */
 	idx = (opcode == TGSI_OPCODE_DDX || opcode == TGSI_OPCODE_DDX_FINE) ? 1 : 2;
 
-	val = LLVMBuildBitCast(gallivm->builder, emit_data->args[0], ctx->i32, "");
+	val = ac_to_integer(&ctx->ac, emit_data->args[0]);
 	val = ac_build_ddxy(&ctx->ac, mask, idx, val);
 	emit_data->output[emit_data->chan] = val;
 }
 
 /*
  * this takes an I,J coordinate pair,
  * and works out the X and Y derivatives.
  * it returns DDX(I), DDX(J), DDY(I), DDY(J).
  */
 static LLVMValueRef si_llvm_emit_ddxy_interp(
@@ -3720,22 +3695,21 @@ static void interp_fetch_args(
 	} else if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE) {
 		LLVMValueRef sample_position;
 		LLVMValueRef sample_id;
 		LLVMValueRef halfval = LLVMConstReal(ctx->f32, 0.5f);
 
 		/* fetch sample ID, then fetch its sample position,
 		 * and place into first two channels.
 		 */
 		sample_id = lp_build_emit_fetch(bld_base,
 						emit_data->inst, 1, TGSI_CHAN_X);
-		sample_id = LLVMBuildBitCast(gallivm->builder, sample_id,
-					     ctx->i32, "");
+		sample_id = ac_to_integer(&ctx->ac, sample_id);
 
 		/* Section 8.13.2 (Interpolation Functions) of the OpenGL Shading
 		 * Language 4.50 spec says about interpolateAtSample:
 		 *
 		 *    "Returns the value of the input interpolant variable at
 		 *     the location of sample number sample. If multisample
 		 *     buffers are not available, the input variable will be
 		 *     evaluated at the center of the pixel. If sample sample
 		 *     does not exist, the position used to interpolate the
 		 *     input variable is undefined."
@@ -3844,49 +3818,44 @@ static void build_interp_intrinsic(const struct lp_build_tgsi_action *action,
 			LLVMValueRef ix_ll = LLVMConstInt(ctx->i32, i, 0);
 			LLVMValueRef iy_ll = LLVMConstInt(ctx->i32, i + 2, 0);
 			LLVMValueRef ddx_el = LLVMBuildExtractElement(gallivm->builder,
 								      ddxy_out, ix_ll, "");
 			LLVMValueRef ddy_el = LLVMBuildExtractElement(gallivm->builder,
 								      ddxy_out, iy_ll, "");
 			LLVMValueRef interp_el = LLVMBuildExtractElement(gallivm->builder,
 									 interp_param, ix_ll, "");
 			LLVMValueRef temp1, temp2;
 
-			interp_el = LLVMBuildBitCast(gallivm->builder, interp_el,
-						     ctx->f32, "");
+			interp_el = ac_to_float(&ctx->ac, interp_el);
 
 			temp1 = LLVMBuildFMul(gallivm->builder, ddx_el, emit_data->args[0], "");
 
 			temp1 = LLVMBuildFAdd(gallivm->builder, temp1, interp_el, "");
 
 			temp2 = LLVMBuildFMul(gallivm->builder, ddy_el, emit_data->args[1], "");
 
 			ij_out[i] = LLVMBuildFAdd(gallivm->builder, temp2, temp1, "");
 		}
 		interp_param = lp_build_gather_values(gallivm, ij_out, 2);
 	}
 
-	if (interp_param) {
-		interp_param = LLVMBuildBitCast(gallivm->builder,
-			interp_param, LLVMVectorType(ctx->f32, 2), "");
-	}
+	if (interp_param)
+		interp_param = ac_to_float(&ctx->ac, interp_param);
 
 	for (chan = 0; chan < 4; chan++) {
 		LLVMValueRef gather = LLVMGetUndef(LLVMVectorType(ctx->f32, input_array_size));
 		unsigned schan = tgsi_util_get_full_src_register_swizzle(&inst->Src[0], chan);
 
 		for (unsigned idx = 0; idx < input_array_size; ++idx) {
 			LLVMValueRef v, i = NULL, j = NULL;
 
 			if (interp_param) {
-				interp_param = LLVMBuildBitCast(gallivm->builder,
-					interp_param, LLVMVectorType(ctx->f32, 2), "");
 				i = LLVMBuildExtractElement(
 					gallivm->builder, interp_param, ctx->i32_0, "");
 				j = LLVMBuildExtractElement(
 					gallivm->builder, interp_param, ctx->i32_1, "");
 			}
 			v = si_build_fs_interp(ctx, input_base + idx, schan,
 					       prim_mask, i, j);
 
 			gather = LLVMBuildInsertElement(gallivm->builder,
 				gather, v, LLVMConstInt(ctx->i32, idx, false), "");
@@ -3965,31 +3934,28 @@ static void read_invoc_fetch_args(
 						 1, TGSI_CHAN_X);
 	emit_data->arg_count = 2;
 }
 
 static void read_lane_emit(
 	const struct lp_build_tgsi_action *action,
 	struct lp_build_tgsi_context *bld_base,
 	struct lp_build_emit_data *emit_data)
 {
 	struct si_shader_context *ctx = si_shader_context(bld_base);
-	LLVMBuilderRef builder = ctx->gallivm.builder;
 
 	/* We currently have no other way to prevent LLVM from lifting the icmp
 	 * calls to a dominating basic block.
 	 */
 	ac_build_optimization_barrier(&ctx->ac, &emit_data->args[0]);
 
-	for (unsigned i = 0; i < emit_data->arg_count; ++i) {
-		emit_data->args[i] = LLVMBuildBitCast(builder, emit_data->args[i],
-						      ctx->i32, "");
-	}
+	for (unsigned i = 0; i < emit_data->arg_count; ++i)
+		emit_data->args[i] = ac_to_integer(&ctx->ac, emit_data->args[i]);
 
 	emit_data->output[emit_data->chan] =
 		ac_build_intrinsic(&ctx->ac, action->intr_name,
 				   ctx->i32, emit_data->args, emit_data->arg_count,
 				   AC_FUNC_ATTR_READNONE |
 				   AC_FUNC_ATTR_CONVERGENT);
 }
 
 static unsigned si_llvm_get_stream(struct lp_build_tgsi_context *bld_base,
 				       struct lp_build_emit_data *emit_data)
@@ -4067,21 +4033,21 @@ static void si_llvm_emit_vertex(
 
 			LLVMValueRef out_val = LLVMBuildLoad(gallivm->builder, out_ptr[chan], "");
 			LLVMValueRef voffset =
 				LLVMConstInt(ctx->i32, offset *
 					     shader->selector->gs_max_out_vertices, 0);
 			offset++;
 
 			voffset = lp_build_add(uint, voffset, gs_next_vertex);
 			voffset = lp_build_mul_imm(uint, voffset, 4);
 
-			out_val = LLVMBuildBitCast(gallivm->builder, out_val, ctx->i32, "");
+			out_val = ac_to_integer(&ctx->ac, out_val);
 
 			ac_build_buffer_store_dword(&ctx->ac,
 						    ctx->gsvs_ring[stream],
 						    out_val, 1,
 						    voffset, soffset, 0,
 						    1, 1, true, true);
 		}
 	}
 
 	gs_next_vertex = lp_build_add(uint, gs_next_vertex,
@@ -4810,21 +4776,21 @@ static void si_llvm_emit_polygon_stipple(struct si_shader_context *ctx,
 	address[1] = unpack_param(ctx, param_pos_fixed_pt, 16, 5);
 
 	/* Load the buffer descriptor. */
 	slot = LLVMConstInt(ctx->i32, SI_PS_CONST_POLY_STIPPLE, 0);
 	desc = ac_build_indexed_load_const(&ctx->ac, param_rw_buffers, slot);
 
 	/* The stipple pattern is 32x32, each row has 32 bits. */
 	offset = LLVMBuildMul(builder, address[1],
 			      LLVMConstInt(ctx->i32, 4, 0), "");
 	row = buffer_load_const(ctx, desc, offset);
-	row = LLVMBuildBitCast(builder, row, ctx->i32, "");
+	row = ac_to_integer(&ctx->ac, row);
 	bit = LLVMBuildLShr(builder, row, address[0], "");
 	bit = LLVMBuildTrunc(builder, bit, ctx->i1, "");
 
 	/* The intrinsic kills the thread if arg < 0. */
 	bit = LLVMBuildSelect(builder, bit, LLVMConstReal(ctx->f32, 0),
 			      LLVMConstReal(ctx->f32, -1), "");
 	ac_build_kill(&ctx->ac, bit);
 }
 
 void si_shader_binary_read_config(struct ac_shader_binary *binary,
@@ -6053,21 +6019,21 @@ static void si_build_gs_prolog_function(struct si_shader_context *ctx,
 	/* Copy inputs to outputs. This should be no-op, as the registers match,
 	 * but it will prevent the compiler from overwriting them unintentionally.
 	 */
 	ret = ctx->return_value;
 	for (unsigned i = 0; i < num_sgprs; i++) {
 		LLVMValueRef p = LLVMGetParam(func, i);
 		ret = LLVMBuildInsertValue(builder, ret, p, i, "");
 	}
 	for (unsigned i = 0; i < num_vgprs; i++) {
 		LLVMValueRef p = LLVMGetParam(func, num_sgprs + i);
-		p = LLVMBuildBitCast(builder, p, ctx->f32, "");
+		p = ac_to_float(&ctx->ac, p);
 		ret = LLVMBuildInsertValue(builder, ret, p, num_sgprs + i, "");
 	}
 
 	if (key->gs_prolog.states.tri_strip_adj_fix) {
 		/* Remap the input vertices for every other primitive. */
 		const unsigned gfx6_vtx_params[6] = {
 			num_sgprs,
 			num_sgprs + 1,
 			num_sgprs + 3,
 			num_sgprs + 4,
@@ -6102,29 +6068,29 @@ static void si_build_gs_prolog_function(struct si_shader_context *ctx,
 			vtx_out[i] = LLVMBuildSelect(builder, rotate, rotated, base, "");
 		}
 
 		if (ctx->screen->b.chip_class >= GFX9) {
 			for (unsigned i = 0; i < 3; i++) {
 				LLVMValueRef hi, out;
 
 				hi = LLVMBuildShl(builder, vtx_out[i*2+1],
 						  LLVMConstInt(ctx->i32, 16, 0), "");
 				out = LLVMBuildOr(builder, vtx_out[i*2], hi, "");
-				out = LLVMBuildBitCast(builder, out, ctx->f32, "");
+				out = ac_to_float(&ctx->ac, out);
 				ret = LLVMBuildInsertValue(builder, ret, out,
 							   gfx9_vtx_params[i], "");
 			}
 		} else {
 			for (unsigned i = 0; i < 6; i++) {
 				LLVMValueRef out;
 
-				out = LLVMBuildBitCast(builder, vtx_out[i], ctx->f32, "");
+				out = ac_to_float(&ctx->ac, vtx_out[i]);
 				ret = LLVMBuildInsertValue(builder, ret, out,
 							   gfx6_vtx_params[i], "");
 			}
 		}
 	}
 
 	LLVMBuildRet(builder, ret);
 }
 
 /**
@@ -6866,21 +6832,21 @@ static void si_build_vs_prolog_function(struct si_shader_context *ctx,
 	/* Copy inputs to outputs. This should be no-op, as the registers match,
 	 * but it will prevent the compiler from overwriting them unintentionally.
 	 */
 	ret = ctx->return_value;
 	for (i = 0; i < key->vs_prolog.num_input_sgprs; i++) {
 		LLVMValueRef p = LLVMGetParam(func, i);
 		ret = LLVMBuildInsertValue(gallivm->builder, ret, p, i, "");
 	}
 	for (i = 0; i < num_input_vgprs; i++) {
 		LLVMValueRef p = input_vgprs[i];
-		p = LLVMBuildBitCast(gallivm->builder, p, ctx->f32, "");
+		p = ac_to_float(&ctx->ac, p);
 		ret = LLVMBuildInsertValue(gallivm->builder, ret, p,
 					   key->vs_prolog.num_input_sgprs + i, "");
 	}
 
 	/* Compute vertex load indices from instance divisors. */
 	LLVMValueRef instance_divisor_constbuf = NULL;
 
 	if (key->vs_prolog.states.instance_divisor_is_fetched) {
 		LLVMValueRef list = si_prolog_get_rw_buffers(ctx);
 		LLVMValueRef buf_index =
@@ -6895,38 +6861,37 @@ static void si_build_vs_prolog_function(struct si_shader_context *ctx,
 		bool divisor_is_fetched =
 			key->vs_prolog.states.instance_divisor_is_fetched & (1u << i);
 		LLVMValueRef index;
 
 		if (divisor_is_one || divisor_is_fetched) {
 			LLVMValueRef divisor = ctx->i32_1;
 
 			if (divisor_is_fetched) {
 				divisor = buffer_load_const(ctx, instance_divisor_constbuf,
 							    LLVMConstInt(ctx->i32, i * 4, 0));
-				divisor = LLVMBuildBitCast(gallivm->builder, divisor,
-							   ctx->i32, "");
+				divisor = ac_to_integer(&ctx->ac, divisor);
 			}
 
 			/* InstanceID / Divisor + StartInstance */
 			index = get_instance_index_for_fetch(ctx,
 							     user_sgpr_base +
 							     SI_SGPR_START_INSTANCE,
 							     divisor);
 		} else {
 			/* VertexID + BaseVertex */
 			index = LLVMBuildAdd(gallivm->builder,
 					     ctx->abi.vertex_id,
 					     LLVMGetParam(func, user_sgpr_base +
 								SI_SGPR_BASE_VERTEX), "");
 		}
 
-		index = LLVMBuildBitCast(gallivm->builder, index, ctx->f32, "");
+		index = ac_to_float(&ctx->ac, index);
 		ret = LLVMBuildInsertValue(gallivm->builder, ret, index,
 					   fninfo.num_params + i, "");
 	}
 
 	si_llvm_build_ret(ctx, ret);
 }
 
 static bool si_get_vs_prolog(struct si_screen *sscreen,
 			     LLVMTargetMachineRef tm,
 			     struct si_shader *shader,
@@ -7310,21 +7275,21 @@ static void si_build_ps_prolog_function(struct si_shader_context *ctx,
 			interp[1] = LLVMBuildExtractValue(gallivm->builder, ret,
 							  interp_vgpr + 1, "");
 			interp_ij = lp_build_gather_values(gallivm, interp, 2);
 		}
 
 		/* Use the absolute location of the input. */
 		prim_mask = LLVMGetParam(func, SI_PS_NUM_USER_SGPR);
 
 		if (key->ps_prolog.states.color_two_side) {
 			face = LLVMGetParam(func, face_vgpr);
-			face = LLVMBuildBitCast(gallivm->builder, face, ctx->i32, "");
+			face = ac_to_integer(&ctx->ac, face);
 		}
 
 		interp_fs_input(ctx,
 				key->ps_prolog.color_attr_index[i],
 				TGSI_SEMANTIC_COLOR, i,
 				key->ps_prolog.num_interp_inputs,
 				key->ps_prolog.colors_read, interp_ij,
 				prim_mask, face, color);
 
 		while (writemask) {
@@ -7361,29 +7326,29 @@ static void si_build_ps_prolog_function(struct si_shader_context *ctx,
 			0x0001,
 		};
 		assert(key->ps_prolog.states.samplemask_log_ps_iter < ARRAY_SIZE(ps_iter_masks));
 
 		uint32_t ps_iter_mask = ps_iter_masks[key->ps_prolog.states.samplemask_log_ps_iter];
 		unsigned ancillary_vgpr = key->ps_prolog.num_input_sgprs +
 					  key->ps_prolog.ancillary_vgpr_index;
 		LLVMValueRef sampleid = unpack_param(ctx, ancillary_vgpr, 8, 4);
 		LLVMValueRef samplemask = LLVMGetParam(func, ancillary_vgpr + 1);
 
-		samplemask = LLVMBuildBitCast(gallivm->builder, samplemask, ctx->i32, "");
+		samplemask = ac_to_integer(&ctx->ac, samplemask);
 		samplemask = LLVMBuildAnd(
 			gallivm->builder,
 			samplemask,
 			LLVMBuildShl(gallivm->builder,
 				     LLVMConstInt(ctx->i32, ps_iter_mask, false),
 				     sampleid, ""),
 			"");
-		samplemask = LLVMBuildBitCast(gallivm->builder, samplemask, ctx->f32, "");
+		samplemask = ac_to_float(&ctx->ac, samplemask);
 
 		ret = LLVMBuildInsertValue(gallivm->builder, ret, samplemask,
 					   ancillary_vgpr + 1, "");
 	}
 
 	/* Tell LLVM to insert WQM instruction sequence when needed. */
 	if (key->ps_prolog.wqm) {
 		LLVMAddTargetDependentFunctionAttr(func,
 						   "amdgpu-ps-wqm-outputs", "");
 	}
diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c
index 818ca49..3dcbb23 100644
--- a/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c
+++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c
@@ -121,24 +121,24 @@ static void emit_icmp(const struct lp_build_tgsi_action *action,
 	v = LLVMBuildSExtOrBitCast(builder, v,
 			LLVMInt32TypeInContext(context), "");
 
 	emit_data->output[emit_data->chan] = v;
 }
 
 static void emit_ucmp(const struct lp_build_tgsi_action *action,
 		      struct lp_build_tgsi_context *bld_base,
 		      struct lp_build_emit_data *emit_data)
 {
+	struct si_shader_context *ctx = si_shader_context(bld_base);
 	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
 
-	LLVMValueRef arg0 = LLVMBuildBitCast(builder, emit_data->args[0],
-					     bld_base->uint_bld.elem_type, "");
+	LLVMValueRef arg0 = ac_to_integer(&ctx->ac, emit_data->args[0]);
 
 	LLVMValueRef v = LLVMBuildICmp(builder, LLVMIntNE, arg0,
 				       bld_base->uint_bld.zero, "");
 
 	emit_data->output[emit_data->chan] =
 		LLVMBuildSelect(builder, v, emit_data->args[1], emit_data->args[2], "");
 }
 
 static void emit_cmp(const struct lp_build_tgsi_action *action,
 		     struct lp_build_tgsi_context *bld_base,
@@ -235,23 +235,23 @@ static void emit_dcmp(const struct lp_build_tgsi_action *action,
 	v = LLVMBuildSExtOrBitCast(builder, v,
 			LLVMInt32TypeInContext(context), "");
 
 	emit_data->output[emit_data->chan] = v;
 }
 
 static void emit_not(const struct lp_build_tgsi_action *action,
 		     struct lp_build_tgsi_context *bld_base,
 		     struct lp_build_emit_data *emit_data)
 {
+	struct si_shader_context *ctx = si_shader_context(bld_base);
 	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
-	LLVMValueRef v = bitcast(bld_base, TGSI_TYPE_UNSIGNED,
-			emit_data->args[0]);
+	LLVMValueRef v = ac_to_integer(&ctx->ac, emit_data->args[0]);
 	emit_data->output[emit_data->chan] = LLVMBuildNot(builder, v, "");
 }
 
 static void emit_arl(const struct lp_build_tgsi_action *action,
 		     struct lp_build_tgsi_context *bld_base,
 		     struct lp_build_emit_data *emit_data)
 {
 	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
 	LLVMValueRef floor_index =  lp_build_emit_llvm_unary(bld_base, TGSI_OPCODE_FLR, emit_data->args[0]);
 	emit_data->output[emit_data->chan] = LLVMBuildFPToSI(builder,
@@ -675,36 +675,36 @@ static void up2h_fetch_args(struct lp_build_tgsi_context *bld_base,
 			    struct lp_build_emit_data *emit_data)
 {
 	emit_data->args[0] = lp_build_emit_fetch(bld_base, emit_data->inst,
 						 0, TGSI_CHAN_X);
 }
 
 static void emit_up2h(const struct lp_build_tgsi_action *action,
 		      struct lp_build_tgsi_context *bld_base,
 		      struct lp_build_emit_data *emit_data)
 {
+	struct si_shader_context *ctx = si_shader_context(bld_base);
 	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
 	LLVMContextRef context = bld_base->base.gallivm->context;
 	struct lp_build_context *uint_bld = &bld_base->uint_bld;
-	LLVMTypeRef fp16, i16;
+	LLVMTypeRef i16;
 	LLVMValueRef const16, input, val;
 	unsigned i;
 
-	fp16 = LLVMHalfTypeInContext(context);
 	i16 = LLVMInt16TypeInContext(context);
 	const16 = lp_build_const_int32(uint_bld->gallivm, 16);
 	input = emit_data->args[0];
 
 	for (i = 0; i < 2; i++) {
 		val = i == 1 ? LLVMBuildLShr(builder, input, const16, "") : input;
 		val = LLVMBuildTrunc(builder, val, i16, "");
-		val = LLVMBuildBitCast(builder, val, fp16, "");
+		val = ac_to_float(&ctx->ac, val);
 		emit_data->output[i] =
 			LLVMBuildFPExt(builder, val, bld_base->base.elem_type, "");
 	}
 }
 
 static void emit_fdiv(const struct lp_build_tgsi_action *action,
 		      struct lp_build_tgsi_context *bld_base,
 		      struct lp_build_emit_data *emit_data)
 {
 	struct si_shader_context *ctx = si_shader_context(bld_base);
diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
index ba13d3b..887475b 100644
--- a/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
+++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
@@ -241,21 +241,21 @@ static LLVMValueRef image_fetch_coords(
 	struct gallivm_state *gallivm = &ctx->gallivm;
 	LLVMBuilderRef builder = gallivm->builder;
 	unsigned target = inst->Memory.Texture;
 	unsigned num_coords = tgsi_util_get_texture_coord_dim(target);
 	LLVMValueRef coords[4];
 	LLVMValueRef tmp;
 	int chan;
 
 	for (chan = 0; chan < num_coords; ++chan) {
 		tmp = lp_build_emit_fetch(bld_base, inst, src, chan);
-		tmp = LLVMBuildBitCast(builder, tmp, ctx->i32, "");
+		tmp = ac_to_integer(&ctx->ac, tmp);
 		coords[chan] = tmp;
 	}
 
 	if (ctx->screen->b.chip_class >= GFX9) {
 		/* 1D textures are allocated and used as 2D on GFX9. */
 		if (target == TGSI_TEXTURE_1D) {
 			coords[1] = ctx->i32_0;
 			num_coords++;
 		} else if (target == TGSI_TEXTURE_1D_ARRAY) {
 			coords[2] = coords[1];
@@ -360,38 +360,36 @@ static void buffer_append_args(
 			i1true : i1false; /* glc */
 	}
 	emit_data->args[emit_data->arg_count++] = i1false; /* slc */
 }
 
 static void load_fetch_args(
 		struct lp_build_tgsi_context * bld_base,
 		struct lp_build_emit_data * emit_data)
 {
 	struct si_shader_context *ctx = si_shader_context(bld_base);
-	struct gallivm_state *gallivm = &ctx->gallivm;
 	const struct tgsi_full_instruction * inst = emit_data->inst;
 	unsigned target = inst->Memory.Texture;
 	LLVMValueRef rsrc;
 
 	emit_data->dst_type = ctx->v4f32;
 
 	if (inst->Src[0].Register.File == TGSI_FILE_BUFFER ||
 		   inst->Src[0].Register.File == TGSI_FILE_CONSTBUF) {
-		LLVMBuilderRef builder = gallivm->builder;
 		LLVMValueRef offset;
 		LLVMValueRef tmp;
 
 		bool ubo = inst->Src[0].Register.File == TGSI_FILE_CONSTBUF;
 		rsrc = shader_buffer_fetch_rsrc(ctx, &inst->Src[0], ubo);
 
 		tmp = lp_build_emit_fetch(bld_base, inst, 1, 0);
-		offset = LLVMBuildBitCast(builder, tmp, ctx->i32, "");
+		offset = ac_to_integer(&ctx->ac, tmp);
 
 		buffer_append_args(ctx, emit_data, rsrc, ctx->i32_0,
 				   offset, false, false);
 	} else if (inst->Src[0].Register.File == TGSI_FILE_IMAGE ||
 		   tgsi_is_bindless_image_file(inst->Src[0].Register.File)) {
 		LLVMValueRef coords;
 
 		image_fetch_rsrc(bld_base, &inst->Src[0], false, target, &rsrc);
 		coords = image_fetch_coords(bld_base, inst, 1, rsrc);
 
@@ -460,21 +458,21 @@ static void load_emit_buffer(struct si_shader_context *ctx,
 static LLVMValueRef get_memory_ptr(struct si_shader_context *ctx,
                                    const struct tgsi_full_instruction *inst,
                                    LLVMTypeRef type, int arg)
 {
 	struct gallivm_state *gallivm = &ctx->gallivm;
 	LLVMBuilderRef builder = gallivm->builder;
 	LLVMValueRef offset, ptr;
 	int addr_space;
 
 	offset = lp_build_emit_fetch(&ctx->bld_base, inst, arg, 0);
-	offset = LLVMBuildBitCast(builder, offset, ctx->i32, "");
+	offset = ac_to_integer(&ctx->ac, offset);
 
 	ptr = ctx->shared_memory;
 	ptr = LLVMBuildGEP(builder, ptr, &offset, 1, "");
 	addr_space = LLVMGetPointerAddressSpace(LLVMTypeOf(ptr));
 	ptr = LLVMBuildBitCast(builder, ptr, LLVMPointerType(type, addr_space), "");
 
 	return ptr;
 }
 
 static void load_emit_memory(
@@ -624,21 +622,20 @@ static void load_emit(
 				get_load_intr_attribs(can_speculate));
 	}
 }
 
 static void store_fetch_args(
 		struct lp_build_tgsi_context * bld_base,
 		struct lp_build_emit_data * emit_data)
 {
 	struct si_shader_context *ctx = si_shader_context(bld_base);
 	struct gallivm_state *gallivm = &ctx->gallivm;
-	LLVMBuilderRef builder = gallivm->builder;
 	const struct tgsi_full_instruction * inst = emit_data->inst;
 	struct tgsi_full_src_register memory;
 	LLVMValueRef chans[4];
 	LLVMValueRef data;
 	LLVMValueRef rsrc;
 	unsigned chan;
 
 	emit_data->dst_type = LLVMVoidTypeInContext(gallivm->context);
 
 	for (chan = 0; chan < 4; ++chan) {
@@ -650,21 +647,21 @@ static void store_fetch_args(
 
 	memory = tgsi_full_src_register_from_dst(&inst->Dst[0]);
 
 	if (inst->Dst[0].Register.File == TGSI_FILE_BUFFER) {
 		LLVMValueRef offset;
 		LLVMValueRef tmp;
 
 		rsrc = shader_buffer_fetch_rsrc(ctx, &memory, false);
 
 		tmp = lp_build_emit_fetch(bld_base, inst, 0, 0);
-		offset = LLVMBuildBitCast(builder, tmp, ctx->i32, "");
+		offset = ac_to_integer(&ctx->ac, tmp);
 
 		buffer_append_args(ctx, emit_data, rsrc, ctx->i32_0,
 				   offset, false, false);
 	} else if (inst->Dst[0].Register.File == TGSI_FILE_IMAGE ||
 		   tgsi_is_bindless_image_file(inst->Dst[0].Register.File)) {
 		unsigned target = inst->Memory.Texture;
 		LLVMValueRef coords;
 
 		/* 8bit/16bit TC L1 write corruption bug on SI.
 		 * All store opcodes not aligned to a dword are affected.
@@ -840,51 +837,49 @@ static void store_emit(
 				emit_data->args, emit_data->arg_count,
 				get_store_intr_attribs(writeonly_memory));
 	}
 }
 
 static void atomic_fetch_args(
 		struct lp_build_tgsi_context * bld_base,
 		struct lp_build_emit_data * emit_data)
 {
 	struct si_shader_context *ctx = si_shader_context(bld_base);
-	struct gallivm_state *gallivm = &ctx->gallivm;
-	LLVMBuilderRef builder = gallivm->builder;
 	const struct tgsi_full_instruction * inst = emit_data->inst;
 	LLVMValueRef data1, data2;
 	LLVMValueRef rsrc;
 	LLVMValueRef tmp;
 
 	emit_data->dst_type = ctx->f32;
 
 	tmp = lp_build_emit_fetch(bld_base, inst, 2, 0);
-	data1 = LLVMBuildBitCast(builder, tmp, ctx->i32, "");
+	data1 = ac_to_integer(&ctx->ac, tmp);
 
 	if (inst->Instruction.Opcode == TGSI_OPCODE_ATOMCAS) {
 		tmp = lp_build_emit_fetch(bld_base, inst, 3, 0);
-		data2 = LLVMBuildBitCast(builder, tmp, ctx->i32, "");
+		data2 = ac_to_integer(&ctx->ac, tmp);
 	}
 
 	/* llvm.amdgcn.image/buffer.atomic.cmpswap reflect the hardware order
 	 * of arguments, which is reversed relative to TGSI (and GLSL)
 	 */
 	if (inst->Instruction.Opcode == TGSI_OPCODE_ATOMCAS)
 		emit_data->args[emit_data->arg_count++] = data2;
 	emit_data->args[emit_data->arg_count++] = data1;
 
 	if (inst->Src[0].Register.File == TGSI_FILE_BUFFER) {
 		LLVMValueRef offset;
 
 		rsrc = shader_buffer_fetch_rsrc(ctx, &inst->Src[0], false);
 
 		tmp = lp_build_emit_fetch(bld_base, inst, 1, 0);
-		offset = LLVMBuildBitCast(builder, tmp, ctx->i32, "");
+		offset = ac_to_integer(&ctx->ac, tmp);
 
 		buffer_append_args(ctx, emit_data, rsrc, ctx->i32_0,
 				   offset, true, false);
 	} else if (inst->Src[0].Register.File == TGSI_FILE_IMAGE ||
 		   tgsi_is_bindless_image_file(inst->Src[0].Register.File)) {
 		unsigned target = inst->Memory.Texture;
 		LLVMValueRef coords;
 
 		image_fetch_rsrc(bld_base, &inst->Src[0], true, target, &rsrc);
 		coords = image_fetch_coords(bld_base, inst, 1, rsrc);
@@ -904,28 +899,28 @@ static void atomic_fetch_args(
 static void atomic_emit_memory(struct si_shader_context *ctx,
                                struct lp_build_emit_data *emit_data) {
 	struct gallivm_state *gallivm = &ctx->gallivm;
 	LLVMBuilderRef builder = gallivm->builder;
 	const struct tgsi_full_instruction * inst = emit_data->inst;
 	LLVMValueRef ptr, result, arg;
 
 	ptr = get_memory_ptr(ctx, inst, ctx->i32, 1);
 
 	arg = lp_build_emit_fetch(&ctx->bld_base, inst, 2, 0);
-	arg = LLVMBuildBitCast(builder, arg, ctx->i32, "");
+	arg = ac_to_integer(&ctx->ac, arg);
 
 	if (inst->Instruction.Opcode == TGSI_OPCODE_ATOMCAS) {
 		LLVMValueRef new_data;
 		new_data = lp_build_emit_fetch(&ctx->bld_base,
 		                               inst, 3, 0);
 
-		new_data = LLVMBuildBitCast(builder, new_data, ctx->i32, "");
+		new_data = ac_to_integer(&ctx->ac, new_data);
 
 		result = LLVMBuildAtomicCmpXchg(builder, ptr, arg, new_data,
 		                       LLVMAtomicOrderingSequentiallyConsistent,
 		                       LLVMAtomicOrderingSequentiallyConsistent,
 		                       false);
 
 		result = LLVMBuildExtractValue(builder, result, 0, "");
 	} else {
 		LLVMAtomicRMWBinOp op;
 
@@ -1000,22 +995,21 @@ static void atomic_emit(
 
 		ac_build_type_name_for_intr(LLVMTypeOf(coords), coords_type, sizeof(coords_type));
 		snprintf(intrinsic_name, sizeof(intrinsic_name),
 			 "llvm.amdgcn.image.atomic.%s.%s",
 			 action->intr_name, coords_type);
 	}
 
 	tmp = lp_build_intrinsic(
 		builder, intrinsic_name, ctx->i32,
 		emit_data->args, emit_data->arg_count, 0);
-	emit_data->output[emit_data->chan] =
-		LLVMBuildBitCast(builder, tmp, ctx->f32, "");
+	emit_data->output[emit_data->chan] = ac_to_float(&ctx->ac, tmp);
 }
 
 static void set_tex_fetch_args(struct si_shader_context *ctx,
 			       struct lp_build_emit_data *emit_data,
 			       unsigned target,
 			       LLVMValueRef res_ptr, LLVMValueRef samp_ptr,
 			       LLVMValueRef *param, unsigned count,
 			       unsigned dmask)
 {
 	struct gallivm_state *gallivm = &ctx->gallivm;
@@ -1545,24 +1539,22 @@ static void tex_fetch_args(
 	if (opcode == TGSI_OPCODE_TXL || opcode == TGSI_OPCODE_TXF)
 		address[count++] = coords[3];
 	else if (opcode == TGSI_OPCODE_TXL2)
 		address[count++] = lp_build_emit_fetch(bld_base, inst, 1, TGSI_CHAN_X);
 
 	if (count > 16) {
 		assert(!"Cannot handle more than 16 texture address parameters");
 		count = 16;
 	}
 
-	for (chan = 0; chan < count; chan++ ) {
-		address[chan] = LLVMBuildBitCast(gallivm->builder,
-						 address[chan], ctx->i32, "");
-	}
+	for (chan = 0; chan < count; chan++ )
+		address[chan] = ac_to_integer(&ctx->ac, address[chan]);
 
 	/* 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
@@ -1796,23 +1788,23 @@ si_lower_gather4_integer(struct si_shader_context *ctx,
 			half_texel[c] = LLVMBuildFMul(builder, half_texel[c],
 						      LLVMConstReal(ctx->f32, -0.5), "");
 		}
 	}
 
 	for (c = 0; c < 2; c++) {
 		LLVMValueRef tmp;
 		LLVMValueRef index = LLVMConstInt(ctx->i32, coord_vgpr_index + c, 0);
 
 		tmp = LLVMBuildExtractElement(builder, coord, index, "");
-		tmp = LLVMBuildBitCast(builder, tmp, ctx->f32, "");
+		tmp = ac_to_float(&ctx->ac, tmp);
 		tmp = LLVMBuildFAdd(builder, tmp, half_texel[c], "");
-		tmp = LLVMBuildBitCast(builder, tmp, ctx->i32, "");
+		tmp = ac_to_integer(&ctx->ac, tmp);
 		coord = LLVMBuildInsertElement(builder, coord, tmp, index, "");
 	}
 
 	args->addr = coord;
 
 	return NULL;
 }
 
 /* The second half of the cube texture 8_8_8_8 integer workaround: adjust the
  * result after the gather operation.
@@ -1832,21 +1824,21 @@ si_fix_gather4_integer_result(struct si_shader_context *ctx,
 		LLVMValueRef chanv = LLVMConstInt(ctx->i32, chan, false);
 		LLVMValueRef value;
 		LLVMValueRef wa_value;
 
 		value = LLVMBuildExtractElement(builder, result, chanv, "");
 
 		if (return_type == TGSI_RETURN_TYPE_UINT)
 			wa_value = LLVMBuildFPToUI(builder, value, ctx->i32, "");
 		else
 			wa_value = LLVMBuildFPToSI(builder, value, ctx->i32, "");
-		wa_value = LLVMBuildBitCast(builder, wa_value, ctx->f32, "");
+		wa_value = ac_to_float(&ctx->ac, wa_value);
 		value = LLVMBuildSelect(builder, wa, wa_value, value, "");
 
 		result = LLVMBuildInsertElement(builder, result, value, chanv, "");
 	}
 
 	return result;
 }
 
 static void build_tex_intrinsic(const struct lp_build_tgsi_action *action,
 				struct lp_build_tgsi_context *bld_base,
diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
index d6529f2..5b20ff3 100644
--- a/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
+++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
@@ -399,32 +399,33 @@ get_pointer_into_array(struct si_shader_context *ctx,
 	idxs[1] = index;
 	return LLVMBuildGEP(builder, alloca, idxs, 2, "");
 }
 
 LLVMValueRef
 si_llvm_emit_fetch_64bit(struct lp_build_tgsi_context *bld_base,
 			 enum tgsi_opcode_type type,
 			 LLVMValueRef ptr,
 			 LLVMValueRef ptr2)
 {
+	struct si_shader_context *ctx = si_shader_context(bld_base);
 	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
 	LLVMValueRef result;
 
 	result = LLVMGetUndef(LLVMVectorType(LLVMIntTypeInContext(bld_base->base.gallivm->context, 32), bld_base->base.type.length * 2));
 
 	result = LLVMBuildInsertElement(builder,
 					result,
-					bitcast(bld_base, TGSI_TYPE_UNSIGNED, ptr),
+					ac_to_integer(&ctx->ac, ptr),
 					bld_base->int_bld.zero, "");
 	result = LLVMBuildInsertElement(builder,
 					result,
-					bitcast(bld_base, TGSI_TYPE_UNSIGNED, ptr2),
+					ac_to_integer(&ctx->ac, ptr2),
 					bld_base->int_bld.one, "");
 	return bitcast(bld_base, type, result);
 }
 
 static LLVMValueRef
 emit_array_fetch(struct lp_build_tgsi_context *bld_base,
 		 unsigned File, enum tgsi_opcode_type type,
 		 struct tgsi_declaration_range range,
 		 unsigned swizzle)
 {
@@ -906,21 +907,21 @@ void si_llvm_emit_store(struct lp_build_tgsi_context *bld_base,
 		if (inst->Instruction.Saturate)
 			value = ac_build_clamp(&ctx->ac, value);
 
 		if (reg->Register.File == TGSI_FILE_ADDRESS) {
 			temp_ptr = ctx->addrs[reg->Register.Index][chan_index];
 			LLVMBuildStore(builder, value, temp_ptr);
 			continue;
 		}
 
 		if (!tgsi_type_is_64bit(dtype))
-			value = bitcast(bld_base, TGSI_TYPE_FLOAT, value);
+			value = ac_to_float(&ctx->ac, value);
 
 		if (reg->Register.Indirect) {
 			unsigned file = reg->Register.File;
 			unsigned reg_index = reg->Register.Index;
 			store_value_to_array(bld_base, value, file, chan_index,
 					     reg_index, &reg->Indirect);
 		} else {
 			switch(reg->Register.File) {
 			case TGSI_FILE_OUTPUT:
 				temp_ptr = ctx->outputs[reg->Register.Index][chan_index];
@@ -946,22 +947,22 @@ void si_llvm_emit_store(struct lp_build_tgsi_context *bld_base,
 				LLVMBuildStore(builder, value, temp_ptr);
 			else {
 				LLVMValueRef ptr = LLVMBuildBitCast(builder, value,
 								    LLVMVectorType(ctx->i32, 2), "");
 				LLVMValueRef val2;
 				value = LLVMBuildExtractElement(builder, ptr,
 								ctx->i32_0, "");
 				val2 = LLVMBuildExtractElement(builder, ptr,
 							       ctx->i32_1, "");
 
-				LLVMBuildStore(builder, bitcast(bld_base, TGSI_TYPE_FLOAT, value), temp_ptr);
-				LLVMBuildStore(builder, bitcast(bld_base, TGSI_TYPE_FLOAT, val2), temp_ptr2);
+				LLVMBuildStore(builder, ac_to_float(&ctx->ac, value), temp_ptr);
+				LLVMBuildStore(builder, ac_to_float(&ctx->ac, val2), temp_ptr2);
 			}
 		}
 	}
 }
 
 static void set_basicblock_name(LLVMBasicBlockRef bb, const char *base, int pc)
 {
 	char buf[32];
 	/* Subtract 1 so that the number shown is that of the corresponding
 	 * opcode in the TGSI dump, e.g. an if block has the same suffix as
@@ -1118,25 +1119,26 @@ static void if_emit(const struct lp_build_tgsi_action *action,
 			emit_data->args[0],
 			bld_base->base.zero, "");
 
 	if_cond_emit(action, bld_base, emit_data, cond);
 }
 
 static void uif_emit(const struct lp_build_tgsi_action *action,
 		     struct lp_build_tgsi_context *bld_base,
 		     struct lp_build_emit_data *emit_data)
 {
+	struct si_shader_context *ctx = si_shader_context(bld_base);
 	struct gallivm_state *gallivm = bld_base->base.gallivm;
 	LLVMValueRef cond;
 
 	cond = LLVMBuildICmp(gallivm->builder, LLVMIntNE,
-	        bitcast(bld_base, TGSI_TYPE_UNSIGNED, emit_data->args[0]),
+	        ac_to_integer(&ctx->ac, emit_data->args[0]),
 			bld_base->int_bld.zero, "");
 
 	if_cond_emit(action, bld_base, emit_data, cond);
 }
 
 static void emit_immediate(struct lp_build_tgsi_context *bld_base,
 			   const struct tgsi_full_immediate *imm)
 {
 	unsigned i;
 	struct si_shader_context *ctx = si_shader_context(bld_base);
-- 
2.7.4



More information about the mesa-dev mailing list