amd/common: handle nir_deref_cast for shared memory from integers.
authorBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Thu, 24 Jan 2019 00:25:50 +0000 (01:25 +0100)
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Wed, 6 Feb 2019 21:36:02 +0000 (22:36 +0100)
Can happen e.g. after a phi.

Fixes: a2b5cc3c399 "radv: enable variable pointers"
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
src/amd/common/ac_nir_to_llvm.c

index ab3db270f0c025e0348b481b2423a4d1b72865a6..b24f2d59fde0357695ddc6d02f30df8cfaed876a 100644 (file)
@@ -3823,6 +3823,73 @@ static void visit_jump(struct ac_llvm_context *ctx,
        }
 }
 
+static LLVMTypeRef
+glsl_base_to_llvm_type(struct ac_llvm_context *ac,
+                      enum glsl_base_type type)
+{
+       switch (type) {
+       case GLSL_TYPE_INT:
+       case GLSL_TYPE_UINT:
+       case GLSL_TYPE_BOOL:
+       case GLSL_TYPE_SUBROUTINE:
+               return ac->i32;
+       case GLSL_TYPE_INT16:
+       case GLSL_TYPE_UINT16:
+               return ac->i16;
+       case GLSL_TYPE_FLOAT:
+               return ac->f32;
+       case GLSL_TYPE_FLOAT16:
+               return ac->f16;
+       case GLSL_TYPE_INT64:
+       case GLSL_TYPE_UINT64:
+               return ac->i64;
+       case GLSL_TYPE_DOUBLE:
+               return ac->f64;
+       default:
+               unreachable("unknown GLSL type");
+       }
+}
+
+static LLVMTypeRef
+glsl_to_llvm_type(struct ac_llvm_context *ac,
+                 const struct glsl_type *type)
+{
+       if (glsl_type_is_scalar(type)) {
+               return glsl_base_to_llvm_type(ac, glsl_get_base_type(type));
+       }
+
+       if (glsl_type_is_vector(type)) {
+               return LLVMVectorType(
+                  glsl_base_to_llvm_type(ac, glsl_get_base_type(type)),
+                  glsl_get_vector_elements(type));
+       }
+
+       if (glsl_type_is_matrix(type)) {
+               return LLVMArrayType(
+                  glsl_to_llvm_type(ac, glsl_get_column_type(type)),
+                  glsl_get_matrix_columns(type));
+       }
+
+       if (glsl_type_is_array(type)) {
+               return LLVMArrayType(
+                  glsl_to_llvm_type(ac, glsl_get_array_element(type)),
+                  glsl_get_length(type));
+       }
+
+       assert(glsl_type_is_struct(type));
+
+       LLVMTypeRef member_types[glsl_get_length(type)];
+
+       for (unsigned i = 0; i < glsl_get_length(type); i++) {
+               member_types[i] =
+                       glsl_to_llvm_type(ac,
+                                         glsl_get_struct_field(type, i));
+       }
+
+       return LLVMStructTypeInContext(ac->context, member_types,
+                                      glsl_get_length(type), false);
+}
+
 static void visit_deref(struct ac_nir_context *ctx,
                         nir_deref_instr *instr)
 {
@@ -3848,9 +3915,23 @@ static void visit_deref(struct ac_nir_context *ctx,
                result = ac_build_gep_ptr(&ctx->ac, get_src(ctx, instr->parent),
                                          get_src(ctx, instr->arr.index));
                break;
-       case nir_deref_type_cast:
+       case nir_deref_type_cast: {
                result = get_src(ctx, instr->parent);
+
+               LLVMTypeRef pointee_type = glsl_to_llvm_type(&ctx->ac, instr->type);
+               LLVMTypeRef type = LLVMPointerType(pointee_type, AC_ADDR_SPACE_LDS);
+
+               if (LLVMTypeOf(result) != type) {
+                       if (LLVMGetTypeKind(LLVMTypeOf(result)) == LLVMVectorTypeKind) {
+                               result = LLVMBuildBitCast(ctx->ac.builder, result,
+                                                         type, "");
+                       } else {
+                               result = LLVMBuildIntToPtr(ctx->ac.builder, result,
+                                                          type, "");
+                       }
+               }
                break;
+       }
        default:
                unreachable("Unhandled deref_instr deref type");
        }
@@ -3999,73 +4080,6 @@ ac_handle_shader_output_decl(struct ac_llvm_context *ctx,
        }
 }
 
-static LLVMTypeRef
-glsl_base_to_llvm_type(struct ac_llvm_context *ac,
-                      enum glsl_base_type type)
-{
-       switch (type) {
-       case GLSL_TYPE_INT:
-       case GLSL_TYPE_UINT:
-       case GLSL_TYPE_BOOL:
-       case GLSL_TYPE_SUBROUTINE:
-               return ac->i32;
-       case GLSL_TYPE_INT16:
-       case GLSL_TYPE_UINT16:
-               return ac->i16;
-       case GLSL_TYPE_FLOAT:
-               return ac->f32;
-       case GLSL_TYPE_FLOAT16:
-               return ac->f16;
-       case GLSL_TYPE_INT64:
-       case GLSL_TYPE_UINT64:
-               return ac->i64;
-       case GLSL_TYPE_DOUBLE:
-               return ac->f64;
-       default:
-               unreachable("unknown GLSL type");
-       }
-}
-
-static LLVMTypeRef
-glsl_to_llvm_type(struct ac_llvm_context *ac,
-                 const struct glsl_type *type)
-{
-       if (glsl_type_is_scalar(type)) {
-               return glsl_base_to_llvm_type(ac, glsl_get_base_type(type));
-       }
-
-       if (glsl_type_is_vector(type)) {
-               return LLVMVectorType(
-                  glsl_base_to_llvm_type(ac, glsl_get_base_type(type)),
-                  glsl_get_vector_elements(type));
-       }
-
-       if (glsl_type_is_matrix(type)) {
-               return LLVMArrayType(
-                  glsl_to_llvm_type(ac, glsl_get_column_type(type)),
-                  glsl_get_matrix_columns(type));
-       }
-
-       if (glsl_type_is_array(type)) {
-               return LLVMArrayType(
-                  glsl_to_llvm_type(ac, glsl_get_array_element(type)),
-                  glsl_get_length(type));
-       }
-
-       assert(glsl_type_is_struct(type));
-
-       LLVMTypeRef member_types[glsl_get_length(type)];
-
-       for (unsigned i = 0; i < glsl_get_length(type); i++) {
-               member_types[i] =
-                       glsl_to_llvm_type(ac,
-                                         glsl_get_struct_field(type, i));
-       }
-
-       return LLVMStructTypeInContext(ac->context, member_types,
-                                      glsl_get_length(type), false);
-}
-
 static void
 setup_locals(struct ac_nir_context *ctx,
             struct nir_function *func)