[Mesa-dev] [PATCH v2 03/41] ac: add various helpers for float16/int16/int8
Rhys Perry
pendingchaos02 at gmail.com
Sat Feb 16 00:21:52 UTC 2019
v2: remove ac_get_one(), ac_get_zero(), ac_get_onef() and ac_get_zerof()
v2: remove ac_int_of_size()
Signed-off-by: Rhys Perry <pendingchaos02 at gmail.com>
---
src/amd/common/ac_llvm_build.c | 55 ++++++++++++++++++++++++++++++---
src/amd/common/ac_llvm_build.h | 15 +++++++--
src/amd/common/ac_nir_to_llvm.c | 30 +++++++++---------
3 files changed, 79 insertions(+), 21 deletions(-)
diff --git a/src/amd/common/ac_llvm_build.c b/src/amd/common/ac_llvm_build.c
index 9395bd1bbda..b53d9c7ff8c 100644
--- a/src/amd/common/ac_llvm_build.c
+++ b/src/amd/common/ac_llvm_build.c
@@ -87,12 +87,16 @@ ac_llvm_context_init(struct ac_llvm_context *ctx,
ctx->v4f32 = LLVMVectorType(ctx->f32, 4);
ctx->v8i32 = LLVMVectorType(ctx->i32, 8);
+ ctx->i8_0 = LLVMConstInt(ctx->i8, 0, false);
+ ctx->i8_1 = LLVMConstInt(ctx->i8, 1, false);
ctx->i16_0 = LLVMConstInt(ctx->i16, 0, false);
ctx->i16_1 = LLVMConstInt(ctx->i16, 1, false);
ctx->i32_0 = LLVMConstInt(ctx->i32, 0, false);
ctx->i32_1 = LLVMConstInt(ctx->i32, 1, false);
ctx->i64_0 = LLVMConstInt(ctx->i64, 0, false);
ctx->i64_1 = LLVMConstInt(ctx->i64, 1, false);
+ ctx->f16_0 = LLVMConstReal(ctx->f16, 0.0);
+ ctx->f16_1 = LLVMConstReal(ctx->f16, 1.0);
ctx->f32_0 = LLVMConstReal(ctx->f32, 0.0);
ctx->f32_1 = LLVMConstReal(ctx->f32, 1.0);
ctx->f64_0 = LLVMConstReal(ctx->f64, 0.0);
@@ -201,7 +205,9 @@ ac_get_type_size(LLVMTypeRef type)
static LLVMTypeRef to_integer_type_scalar(struct ac_llvm_context *ctx, LLVMTypeRef t)
{
- if (t == ctx->f16 || t == ctx->i16)
+ if (t == ctx->i8)
+ return ctx->i8;
+ else if (t == ctx->f16 || t == ctx->i16)
return ctx->i16;
else if (t == ctx->f32 || t == ctx->i32)
return ctx->i32;
@@ -281,6 +287,42 @@ ac_to_float(struct ac_llvm_context *ctx, LLVMValueRef v)
return LLVMBuildBitCast(ctx->builder, v, ac_to_float_type(ctx, type), "");
}
+LLVMTypeRef ac_float_of_size(struct ac_llvm_context *ctx, unsigned bit_size)
+{
+ switch (bit_size) {
+ case 16:
+ return ctx->f16;
+ case 32:
+ return ctx->f32;
+ case 64:
+ return ctx->f64;
+ default:
+ unreachable("Unhandled bit size");
+ }
+}
+
+LLVMValueRef ac_build_ui_cast(struct ac_llvm_context *ctx, LLVMValueRef v, LLVMTypeRef t)
+{
+ unsigned new_bit_size = ac_get_elem_bits(ctx, t);
+ unsigned old_bit_size = ac_get_elem_bits(ctx, LLVMTypeOf(v));
+ if (new_bit_size > old_bit_size)
+ return LLVMBuildZExt(ctx->builder, v, t, "");
+ else if (new_bit_size < old_bit_size)
+ return LLVMBuildTrunc(ctx->builder, v, t, "");
+ else
+ return v;
+}
+
+LLVMValueRef ac_build_reinterpret(struct ac_llvm_context *ctx, LLVMValueRef v, LLVMTypeRef t)
+{
+ if (LLVMTypeOf(v) == t)
+ return v;
+
+ v = ac_to_integer(ctx, v);
+ v = ac_build_ui_cast(ctx, v, ac_to_integer_type(ctx, t));
+ return LLVMBuildBitCast(ctx->builder, v, t, "");
+}
+
LLVMValueRef
ac_build_intrinsic(struct ac_llvm_context *ctx, const char *name,
@@ -1338,15 +1380,18 @@ LLVMValueRef ac_build_buffer_load_format_gfx9_safe(struct ac_llvm_context *ctx,
}
LLVMValueRef
-ac_build_tbuffer_load_short(struct ac_llvm_context *ctx,
+ac_build_tbuffer_load_short_byte(struct ac_llvm_context *ctx,
LLVMValueRef rsrc,
LLVMValueRef vindex,
LLVMValueRef voffset,
LLVMValueRef soffset,
LLVMValueRef immoffset,
- LLVMValueRef glc)
+ LLVMValueRef glc,
+ unsigned size)
{
+ assert(size == 1 || size == 2);
const char *name = "llvm.amdgcn.tbuffer.load.i32";
+ int data_format = size == 1 ? V_008F0C_BUF_DATA_FORMAT_8 : V_008F0C_BUF_DATA_FORMAT_16;
LLVMTypeRef type = ctx->i32;
LLVMValueRef params[] = {
rsrc,
@@ -1354,13 +1399,13 @@ ac_build_tbuffer_load_short(struct ac_llvm_context *ctx,
voffset,
soffset,
immoffset,
- LLVMConstInt(ctx->i32, V_008F0C_BUF_DATA_FORMAT_16, false),
+ LLVMConstInt(ctx->i32, data_format, false),
LLVMConstInt(ctx->i32, V_008F0C_BUF_NUM_FORMAT_UINT, false),
glc,
ctx->i1false,
};
LLVMValueRef res = ac_build_intrinsic(ctx, name, type, params, 9, 0);
- return LLVMBuildTrunc(ctx->builder, res, ctx->i16, "");
+ return LLVMBuildTrunc(ctx->builder, res, LLVMIntTypeInContext(ctx->context, size * 8), "");
}
/**
diff --git a/src/amd/common/ac_llvm_build.h b/src/amd/common/ac_llvm_build.h
index f218eaf2832..61c9b5e4b6c 100644
--- a/src/amd/common/ac_llvm_build.h
+++ b/src/amd/common/ac_llvm_build.h
@@ -74,12 +74,16 @@ struct ac_llvm_context {
LLVMTypeRef v4f32;
LLVMTypeRef v8i32;
+ LLVMValueRef i8_0;
+ LLVMValueRef i8_1;
LLVMValueRef i16_0;
LLVMValueRef i16_1;
LLVMValueRef i32_0;
LLVMValueRef i32_1;
LLVMValueRef i64_0;
LLVMValueRef i64_1;
+ LLVMValueRef f16_0;
+ LLVMValueRef f16_1;
LLVMValueRef f32_0;
LLVMValueRef f32_1;
LLVMValueRef f64_0;
@@ -130,6 +134,12 @@ LLVMValueRef ac_to_integer_or_pointer(struct ac_llvm_context *ctx, LLVMValueRef
LLVMTypeRef ac_to_float_type(struct ac_llvm_context *ctx, LLVMTypeRef t);
LLVMValueRef ac_to_float(struct ac_llvm_context *ctx, LLVMValueRef v);
+LLVMTypeRef ac_float_of_size(struct ac_llvm_context *ctx, unsigned bit_size);
+
+LLVMValueRef ac_build_ui_cast(struct ac_llvm_context *ctx, LLVMValueRef v, LLVMTypeRef t);
+
+LLVMValueRef ac_build_reinterpret(struct ac_llvm_context *ctx, LLVMValueRef v, LLVMTypeRef t);
+
LLVMValueRef
ac_build_intrinsic(struct ac_llvm_context *ctx, const char *name,
LLVMTypeRef return_type, LLVMValueRef *params,
@@ -293,13 +303,14 @@ LLVMValueRef ac_build_buffer_load_format_gfx9_safe(struct ac_llvm_context *ctx,
bool can_speculate);
LLVMValueRef
-ac_build_tbuffer_load_short(struct ac_llvm_context *ctx,
+ac_build_tbuffer_load_short_byte(struct ac_llvm_context *ctx,
LLVMValueRef rsrc,
LLVMValueRef vindex,
LLVMValueRef voffset,
LLVMValueRef soffset,
LLVMValueRef immoffset,
- LLVMValueRef glc);
+ LLVMValueRef glc,
+ unsigned size);
LLVMValueRef
ac_get_thread_id(struct ac_llvm_context *ctx);
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index 54559b19f02..bed52490bad 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -1677,13 +1677,14 @@ static LLVMValueRef visit_load_buffer(struct ac_nir_context *ctx,
LLVMValueRef ret;
if (load_bytes == 2) {
- ret = ac_build_tbuffer_load_short(&ctx->ac,
- rsrc,
- vindex,
- offset,
- ctx->ac.i32_0,
- immoffset,
- glc);
+ ret = ac_build_tbuffer_load_short_byte(&ctx->ac,
+ rsrc,
+ vindex,
+ offset,
+ ctx->ac.i32_0,
+ immoffset,
+ glc,
+ 2);
} else {
const char *load_name;
LLVMTypeRef data_type;
@@ -1748,13 +1749,14 @@ static LLVMValueRef visit_load_ubo_buffer(struct ac_nir_context *ctx,
if (instr->dest.ssa.bit_size == 16) {
LLVMValueRef results[num_components];
for (unsigned i = 0; i < num_components; ++i) {
- results[i] = ac_build_tbuffer_load_short(&ctx->ac,
- rsrc,
- ctx->ac.i32_0,
- offset,
- ctx->ac.i32_0,
- LLVMConstInt(ctx->ac.i32, 2 * i, 0),
- ctx->ac.i1false);
+ results[i] = ac_build_tbuffer_load_short_byte(&ctx->ac,
+ rsrc,
+ ctx->ac.i32_0,
+ offset,
+ ctx->ac.i32_0,
+ LLVMConstInt(ctx->ac.i32, 2 * i, 0),
+ ctx->ac.i1false,
+ 2);
}
ret = ac_build_gather_values(&ctx->ac, results, num_components);
} else {
--
2.20.1
More information about the mesa-dev
mailing list