radeon/llvm: Allocate space for kernel metadata operands
authorAaron Watry <awatry@gmail.com>
Wed, 2 Jul 2014 21:27:31 +0000 (16:27 -0500)
committerAaron Watry <awatry@gmail.com>
Thu, 3 Jul 2014 20:18:03 +0000 (15:18 -0500)
Previously, we were assuming that kernel metadata nodes only had 1 operand.

Kernels which have attributes can have more than 1, e.g.:
!0 = metadata !{void (i32 addrspace(1)*)* @testKernel, metadata !1}
!1 = metadata !{metadata !"work_group_size_hint", i32 4, i32 1, i32 1}

Attempting to get the kernel without the correct number of attributes led
to memory corruption and luxrays crashing out.

Fixes the cl/program/execute/attributes.cl piglit test.

Signed-off-by: Aaron Watry <awatry@gmail.com>
Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=76223
CC: "10.2" <mesa-stable@lists.freedesktop.org>
src/gallium/drivers/radeon/radeon_llvm_util.c

index 2ace91ff4dc413102a38b5409fe88fb14c435b5b..ec1155923fede0ff038a96518adfff15e7da11a2 100644 (file)
@@ -100,13 +100,17 @@ LLVMModuleRef radeon_llvm_get_kernel_module(LLVMContextRef ctx, unsigned index,
        kernel_metadata = MALLOC(num_kernels * sizeof(LLVMValueRef));
        LLVMGetNamedMetadataOperands(mod, "opencl.kernels", kernel_metadata);
        for (i = 0; i < num_kernels; i++) {
-               LLVMValueRef kernel_signature, kernel_function;
+               LLVMValueRef kernel_signature, *kernel_function;
+               unsigned num_kernel_md_operands;
                if (i == index) {
                        continue;
                }
                kernel_signature = kernel_metadata[i];
-               LLVMGetMDNodeOperands(kernel_signature, &kernel_function);
-               LLVMDeleteFunction(kernel_function);
+               num_kernel_md_operands = LLVMGetMDNodeNumOperands(kernel_signature);
+               kernel_function = MALLOC(num_kernel_md_operands * sizeof (LLVMValueRef));
+               LLVMGetMDNodeOperands(kernel_signature, kernel_function);
+               LLVMDeleteFunction(*kernel_function);
+               FREE(kernel_function);
        }
        FREE(kernel_metadata);
        radeon_llvm_optimize(mod);