Signed-off-by: Rhys Perry <pendingchao...@gmail.com> --- src/amd/common/ac_llvm_build.c | 123 ++++++++++++++++++++++++++++++-- src/amd/common/ac_llvm_build.h | 22 +++++- src/amd/common/ac_nir_to_llvm.c | 30 ++++---- 3 files changed, 154 insertions(+), 21 deletions(-)
diff --git a/src/amd/common/ac_llvm_build.c b/src/amd/common/ac_llvm_build.c index 154cc696a2..cc7c6da5a4 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; @@ -268,6 +274,110 @@ ac_to_float(struct ac_llvm_context *ctx, LLVMValueRef v) return LLVMBuildBitCast(ctx->builder, v, ac_to_float_type(ctx, type), ""); } +LLVMValueRef ac_get_zerof(struct ac_llvm_context *ctx, LLVMTypeRef t) +{ + if (t == ctx->f16) + return ctx->f16_0; + else if (t == ctx->f32) + return ctx->f32_0; + else if (t == ctx->f64) + return ctx->f64_0; + else + unreachable("Unhandled float size"); +} + +LLVMValueRef ac_get_onef(struct ac_llvm_context *ctx, LLVMTypeRef t) +{ + if (t == ctx->f16) + return ctx->f16_1; + else if (t == ctx->f32) + return ctx->f32_1; + else if (t == ctx->f64) + return ctx->f64_1; + else + unreachable("Unhandled float size"); +} + +LLVMValueRef ac_get_zero(struct ac_llvm_context *ctx, LLVMTypeRef t) +{ + if (t == ctx->i8) + return ctx->i8_0; + else if (t == ctx->i16) + return ctx->i16_0; + else if (t == ctx->i32) + return ctx->i32_0; + else if (t == ctx->i64) + return ctx->i64_0; + else + unreachable("Unhandled bit size"); +} + +LLVMValueRef ac_get_one(struct ac_llvm_context *ctx, LLVMTypeRef t) +{ + if (t == ctx->i8) + return ctx->i8_1; + else if (t == ctx->i16) + return ctx->i16_1; + else if (t == ctx->i32) + return ctx->i32_1; + else if (t == ctx->i64) + return ctx->i64_1; + else + unreachable("Unhandled bit size"); +} + +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"); + } +} + +LLVMTypeRef ac_int_of_size(struct ac_llvm_context *ctx, unsigned bit_size) +{ + switch (bit_size) { + case 8: + return ctx->i8; + case 16: + return ctx->i16; + case 32: + return ctx->i32; + case 64: + return ctx->i64; + 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, @@ -1309,15 +1419,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, @@ -1325,13 +1438,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, ac_int_of_size(ctx, size * 8), ""); } /** diff --git a/src/amd/common/ac_llvm_build.h b/src/amd/common/ac_llvm_build.h index e90c8c21ad..34622bda10 100644 --- a/src/amd/common/ac_llvm_build.h +++ b/src/amd/common/ac_llvm_build.h @@ -76,12 +76,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; @@ -132,6 +136,19 @@ 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); +LLVMValueRef ac_get_zerof(struct ac_llvm_context *ctx, LLVMTypeRef t); +LLVMValueRef ac_get_onef(struct ac_llvm_context *ctx, LLVMTypeRef t); + +LLVMValueRef ac_get_zero(struct ac_llvm_context *ctx, LLVMTypeRef t); +LLVMValueRef ac_get_one(struct ac_llvm_context *ctx, LLVMTypeRef t); + +LLVMTypeRef ac_float_of_size(struct ac_llvm_context *ctx, unsigned bit_size); +LLVMTypeRef ac_int_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, @@ -290,13 +307,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 4a4c09cf5f..2e9fd7b689 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -1652,13 +1652,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; @@ -1723,13 +1724,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.19.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev