gallium: Fix LLVMpipe function parameter of Vector type call load mismatch

When using vector parameter type in Rusticl with LLVMpipe backend, the
generated LLVM IR function definition part uses an Array of Vector
(correct type) LLVM type, but the caller generates a Vector of Vector
(invalid type). This mismatch causes three problems:

1. Type check fails in debug build;
2. The dumped LLVM BC cannot be disassembled due to Invalid Type;
3. Potential faulty JIT code.

This bugfix construct an Array of Vector for NIR function call by a new
`lp_build_gather_array` function. Special thanks to Zhichao Guan
<vbcpascal@outlook.com> for the joint effort in this bugfix, and
Jose Fonseca for sggestions.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36287>
This commit is contained in:
Bohan Yu 2025-07-22 19:39:43 +08:00 committed by Marge Bot
parent b572bd9b91
commit 778b8600d5
3 changed files with 28 additions and 1 deletions

View file

@ -599,6 +599,28 @@ lp_build_gather_values(struct gallivm_state * gallivm,
return vec;
}
/**
* `lp_build_gather_array` has the same function as `lp_build_gather_values`,
* but gathers values into an Array instead of a Vector. This function can be
* used for values that are not valid Vector element types.
*/
LLVMValueRef
lp_build_gather_array(struct gallivm_state * gallivm,
LLVMValueRef * values,
unsigned value_count)
{
LLVMTypeRef arr_type = LLVMArrayType(LLVMTypeOf(values[0]), value_count);
LLVMBuilderRef builder = gallivm->builder;
LLVMValueRef arr = LLVMGetUndef(arr_type);
unsigned i;
for (i = 0; i < value_count; i++) {
arr = LLVMBuildInsertValue(builder, arr, values[i], i, "");
}
return arr;
}
LLVMValueRef
lp_build_masked_gather(struct gallivm_state *gallivm,
unsigned length,

View file

@ -66,6 +66,11 @@ lp_build_gather_values(struct gallivm_state * gallivm,
LLVMValueRef * values,
unsigned value_count);
LLVMValueRef
lp_build_gather_array(struct gallivm_state * gallivm,
LLVMValueRef * values,
unsigned value_count);
LLVMValueRef
lp_build_masked_gather(struct gallivm_state *gallivm,
unsigned length,

View file

@ -5631,7 +5631,7 @@ visit_call(struct lp_build_nir_soa_context *bld,
LLVMValueRef packed_arg = arg[0];
if (nir_src_num_components(instr->params[i]) > 1)
packed_arg = lp_build_gather_values(bld->base.gallivm, arg, nir_src_num_components(instr->params[i]));
packed_arg = lp_build_gather_array(bld->base.gallivm, arg, nir_src_num_components(instr->params[i]));
args[i + LP_RESV_FUNC_ARGS] = packed_arg;
}