From 880098158d393afeafc844c70c678d9de5b3b99e Mon Sep 17 00:00:00 2001 From: Simon Perretta Date: Wed, 20 Aug 2025 11:17:42 +0100 Subject: [PATCH] nir/nir_lower_calls_to_builtins: trivially handle IA64 mangled functions Using __attribute__((overloadable)) when declaring nir ops with variable-width params in clc results in their symbol names being (IA64) mangled; this change enables the mangled names to be handled when later lowering the calls. Signed-off-by: Simon Perretta Acked-by: Alyssa Rosenzweig Part-of: --- .../nir/nir_lower_calls_to_builtins.c | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/compiler/nir/nir_lower_calls_to_builtins.c b/src/compiler/nir/nir_lower_calls_to_builtins.c index a881582abf9..f6f0e7d43cc 100644 --- a/src/compiler/nir/nir_lower_calls_to_builtins.c +++ b/src/compiler/nir/nir_lower_calls_to_builtins.c @@ -3,6 +3,7 @@ * SPDX-License-Identifier: MIT */ +#include #include "nir.h" #include "nir_builder.h" @@ -18,7 +19,7 @@ * * Mangling allows for multiple definitions of the same instruction with * different vector lengths and bit sizes. This could be combined with - * __attribute_((overloadable)) for seamless overloads. + * __attribute__((overloadable)) for seamless overloads. * * In effect, this pass re-implements nir_builder dynamically. This exposes * low-level hardware intrinsics to internal driver programs. It is intended for @@ -97,9 +98,23 @@ lower(nir_builder *b, nir_instr *instr, void *data) nir_call_instr *call = nir_instr_as_call(instr); nir_function *func = call->callee; + const char *intr_name = func->name; + unsigned len = strlen(intr_name); + + /* If the function name has been (IA64) mangled, + * parse out its length and unmangled name. + */ + if (!strncmp("_Z", intr_name, strlen("_Z")) && isdigit(intr_name[2])) { + char *endptr; + len = strtol(&intr_name[2], &endptr, 10); + intr_name = endptr; + } + + const char *nir_prefix = "nir_"; + const unsigned nir_prefix_len = strlen(nir_prefix); /* We reserve all functions prefixed nir_* as builtins needing lowering. */ - if (strncmp("nir_", func->name, strlen("nir_")) != 0) + if (strncmp(nir_prefix, intr_name, nir_prefix_len) != 0) return false; /* Strip the nir_ prefix to give the name of an ALU opcode or intrinsic. Also @@ -107,9 +122,9 @@ lower(nir_builder *b, nir_instr *instr, void *data) * can recover vector lengths / bit sizes from the NIR. This implements a * crude form of function overloading. */ - const char *intr_name = func->name + strlen("nir_"); + intr_name += nir_prefix_len; const char *suffix = strstr(intr_name, "__"); - unsigned len = (suffix != NULL) ? (suffix - intr_name) : strlen(intr_name); + len = (suffix != NULL) ? (suffix - intr_name) : (len - nir_prefix_len); /* From this point on, we must not fail. Remove the call. */ b->cursor = nir_instr_remove(&call->instr); @@ -135,7 +150,7 @@ lower(nir_builder *b, nir_instr *instr, void *data) } /* We must have matched something! */ - fprintf(stderr, "unknown opcode %s\n", func->name); + fprintf(stderr, "unknown opcode %.*s\n", len, intr_name); UNREACHABLE("invalid nir opcode/intrinsic"); }