Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -1074,6 +1074,24 @@ static rocke_status_t _op_tile_buffer_rsrc(rocke_h_lowerer_t* lw, const rocke_op
}
ptr = op->operands[0];
num_bytes = op->operands[1];
/* num_records is cast to (int), which ROCm 7.1's builtin (int num_records)
* and later clang's (a 64-bit num_records) both accept; the cast would
* truncate an i64 byte count. A constant-space ptr is kept: the HIP
* signature declares every pointer parameter the same way, and the builtin
* takes a void*. */
{
const char* nb_ty
= (num_bytes->type && num_bytes->type->name) ? num_bytes->type->name : "(null)";
if(strcmp(nb_ty, "i32") != 0)
{
return rocke_h_fail(lw,
ROCKE_ERR_VALUE,
"buffer_rsrc num_bytes must be i32 in the HIP lowering, got "
"%s; the HIP lowering casts num_records to (int), so a wider byte "
"count would be truncated; pass it as i32",
nb_ty);
}
}
/* The flags word is the rsrc DWORD3, whose format / out-of-bounds encoding
* is ISA-specific. Take it from the target's ISA backend, the same source
* the LLVM lowerer's tile.buffer_rsrc reads, so both routes agree. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1374,16 +1374,12 @@ static void _op_tile_s_buffer_prefetch_data(rocke_lower_t* L, const rocke_op_t*

static void _op_tile_global_prefetch(rocke_lower_t* L, const rocke_op_t* op)
{
const char* ty;
int64_t cp;
if(!rocke_ll_live(L))
return;
rocke_ll_require_llvm23_target_fact(L, "global_prefetch", ROCKE_LL_FACT_GLOBAL_PREFETCH);
ll_expect_operands(L, op, "global_prefetch", 1);
ty = rocke_ll_value_ptr_type(L, op->operands[0]);
if(strcmp(ty, "ptr addrspace(1)") != 0)
rocke_ll_fail(
L, ROCKE_ERR_VALUE, "global_prefetch ptr must be a global pointer, got %s", ty);
rocke_ll_require_global_header_ptr(L, "global_prefetch", op->operands[0], "ptr");
cp = ll_check_cachepolicy(L, op, "global_prefetch");
rocke_ll_need(L, "global.prefetch");
rocke_ll_emitf(L,
Expand All @@ -1394,15 +1390,12 @@ static void _op_tile_global_prefetch(rocke_lower_t* L, const rocke_op_t* op)

static void _op_tile_flat_prefetch(rocke_lower_t* L, const rocke_op_t* op)
{
const char* ty;
int64_t cp;
if(!rocke_ll_live(L))
return;
rocke_ll_require_llvm23_target_fact(L, "flat_prefetch", ROCKE_LL_FACT_GLOBAL_PREFETCH);
ll_expect_operands(L, op, "flat_prefetch", 1);
ty = rocke_ll_value_ptr_type(L, op->operands[0]);
if(strcmp(ty, "ptr") != 0)
rocke_ll_fail(L, ROCKE_ERR_VALUE, "flat_prefetch ptr must be a flat pointer, got %s", ty);
rocke_ll_require_header_ptr(L, "flat_prefetch", op->operands[0], "ptr", "flat", "ptr");
cp = ll_check_cachepolicy(L, op, "flat_prefetch");
rocke_ll_need(L, "flat.prefetch");
rocke_ll_emitf(L,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -653,24 +653,62 @@ const char* rocke_ll_param_llvm_type(rocke_lower_t* L, const rocke_param_t* p)
return rocke_ll_llvm_type(L, p->type);
}

const rocke_param_t* rocke_ll_value_param(const rocke_lower_t* L, const rocke_value_t* v)
{
if(!L || !L->kernel || !v || !v->name || v->name[0] != '%')
return NULL;
for(int i = 0; i < L->kernel->num_params; i++)
{
const rocke_param_t* p = L->kernel->params[i];
if(p && p->name && strcmp(v->name + 1, p->name) == 0)
return p;
}
return NULL;
}

const char* rocke_ll_value_ptr_type(rocke_lower_t* L, const rocke_value_t* v)
{
int i;
if(!v)
return "";
/* Python _Lowerer._ptr_llvm_type: kernel params carry the header's type. */
if(L && L->kernel && v->name)
{
for(i = 0; i < L->kernel->num_params; i++)
{
const rocke_param_t* p = L->kernel->params[i];
if(p && p->name && v->name[0] == '%' && strcmp(v->name + 1, p->name) == 0)
return rocke_ll_param_llvm_type(L, p);
}
}
const rocke_param_t* param = rocke_ll_value_param(L, v);
if(param)
return rocke_ll_param_llvm_type(L, param);
return rocke_ll_llvm_type(L, v->type);
}

void rocke_ll_require_header_ptr(rocke_lower_t* L,
const char* op_name,
const rocke_value_t* ptr,
const char* operand,
const char* space,
const char* expected)
{
const char* header = rocke_ll_value_ptr_type(L, ptr);
if(strcmp(header, expected) == 0)
return;
const rocke_param_t* param = rocke_ll_value_param(L, ptr);
const bool moved
= param
&& strcmp(rocke_ll_param_llvm_type(L, param), rocke_ll_llvm_type(L, param->type)) != 0;
rocke_ll_fail(L,
ROCKE_ERR_TYPE,
"%s %s must be a %s pointer, got %s%s",
op_name,
operand,
space,
header,
moved ? " (its parameter's addr_space)" : "");
}

void rocke_ll_require_global_header_ptr(rocke_lower_t* L,
const char* op_name,
const rocke_value_t* ptr,
const char* operand)
{
rocke_ll_require_header_ptr(L, op_name, ptr, operand, "global", "ptr addrspace(1)");
}

int rocke_ll_anyptr_space(rocke_lower_t* L,
const char* op,
const rocke_value_t* ptr,
Expand Down Expand Up @@ -700,12 +738,8 @@ int rocke_ll_anyptr_space(rocke_lower_t* L,
break;
used += (size_t)n;
}
rocke_ll_fail(L,
ROCKE_ERR_VALUE,
"%s: pointer operand is %s, but the intrinsic accepts only %s",
op,
ty,
list);
rocke_ll_fail(
L, ROCKE_ERR_TYPE, "%s: pointer operand is %s, but the op accepts only %s", op, ty, list);
}

const char* rocke_ll_smem_storage_type(rocke_lower_t* L, const rocke_type_t* smem)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,16 @@ const rocke_ll_anyptr_space_t ROCKE_LL_AV_B128_PTR_TYPES[] = {
const int ROCKE_LL_AV_B128_PTR_TYPES_COUNT
= (int)(sizeof(ROCKE_LL_AV_B128_PTR_TYPES) / sizeof(ROCKE_LL_AV_B128_PTR_TYPES[0]));

/* A memref.global_load* is a plain load, which reads through a global pointer
* or through a parameter declared addr_space="constant". It names the
* pointer's own type, so no entry needs a declare. */
const rocke_ll_anyptr_space_t ROCKE_LL_GLOBAL_LOAD_PTR_TYPES[] = {
{1, "ptr addrspace(1)"},
{4, "ptr addrspace(4)"},
};
const int ROCKE_LL_GLOBAL_LOAD_PTR_TYPES_COUNT
= (int)(sizeof(ROCKE_LL_GLOBAL_LOAD_PTR_TYPES) / sizeof(ROCKE_LL_GLOBAL_LOAD_PTR_TYPES[0]));

/* ---------------------------------------------------------------------- */
/* Per-generation overrides. Each array holds only the entries whose text */
/* changed AT that declaration ABI generation; a generation inherits every */
Expand Down
Loading
Loading