El 26 de junio de 2026, el devlog de Zig publicó una entrada titulada “SPIR-V Backend Progress”. El autor es Ali Cheraghi, contribuidor principal del backend SPIR-V del compilador Zig. No es un artículo que anuncie “el backend SPIR-V ya está listo” — al contrario, dedica párrafos enteros a reconocer el bitrot, la limitación a un solo hilo y una tasa de solo el 49% de tests de comportamiento superados. Y sin embargo, ese mismo día la entrada trepó a la portada de Lobsters con 28 puntos, y los tres comentarios que recibió eran todos de puro entusiasmo.
Intento entender de dónde viene ese entusiasmo. Un backend de compilador autohospedado, sin llegar a la mitad de los tests de comportamiento, que tras fusionarse en la rama principal se rompió por varios sitios y necesitó semanas de reparación — según cualquier estándar convencional de entrega de software, esto se clasifica como “experimento temprano”. La comunidad, sin embargo, leyó una señal completamente distinta: un lenguaje de sistemas está empezando a establecer una cabeza de puente en el dominio de la GPU.
Dónde se sitúa SPIR-V
Para entender esa señal, hay que volver primero al lugar que ocupa SPIR-V en el ecosistema GPU.
SPIR-V es la representación intermedia binaria (IR) definida por el grupo Khronos, al servicio de Vulkan, OpenCL, OpenGL y, en un futuro próximo, también consumida por DirectX. Su objetivo central de diseño es simple: sacar la compilación de shaders y kernels de computación del driver y ponerla del lado de la aplicación. Antes de SPIR-V, el camino estándar para programar la GPU era: escribir el código fuente en GLSL o HLSL y dárselo al driver para que lo compile en tiempo de ejecución. La calidad del compilador dentro del driver era irregular y los resultados podían variar entre fabricantes y versiones de driver. SPIR-V cambió esa división del trabajo: el frontend del lenguaje se encarga de generar un binario SPIR-V conforme a la especificación; el driver solo tiene que traducirlo al ISA de la GPU. La responsabilidad del compilador se desplazó del driver a la cadena de herramientas del lenguaje.
Este movimiento implica una consecuencia: cualquier frontend de compilador capaz de emitir SPIR-V conforme puede ser una puerta de entrada a la programación de GPU. Sin GLSL. Sin HLSL. A la especificación de Vulkan le da igual si tu binario SPIR-V viene de una traducción de GLSL o de una compilación directa desde C++, Rust, Julia — o Zig.
Por eso es tan importante que el backend de un compilador emita SPIR-V. Un compilador de un lenguaje de propósito general puede generar directamente código de GPU — la frontera entre lenguaje de shaders y lenguaje de propósito general empieza a difuminarse.
Hasta dónde ha llegado el backend de Zig
El devlog del 26 de junio de 2026 cubre avances en cinco dimensiones. Las ordeno por importancia ingenieril:
Primero, la builtin @SpirvType. SPIR-V tiene tipos que no tienen correspondencia directa con el sistema de tipos de Zig: sampler, image, sampled image, runtime array. Hasta ahora, estos tipos solo podían expresarse mediante ensamblador inline escribiendo instrucciones SPIR-V a mano, algo que figuraba crónicamente como “el mayor obstáculo para escribir shaders”. @SpirvType eleva los tipos específicos de GPU a conceptos de primera clase reconocidos por el compilador: puedes declarar un sampler en sintaxis Zig, enlazarlo a un descriptor set y un punto de binding. Es el salto decisivo desde “poder emitir instrucciones SPIR-V” hacia “poder escribir shaders con naturalidad en Zig”.
Segundo, los modos de ejecución pasan a expresarse mediante convenciones de llamada. El tamaño del workgroup, el origen de los fragmentos, los parámetros de los mesh shaders — esta información se insertaba antes manualmente mediante ensamblador inline con OpExecutionMode. En el nuevo diseño, declaras la convención de llamada de una función como callconv(.{ .spirv_kernel = .{ .x = 8, .y = 8, .z = 1 } }) y el compilador deduce automáticamente el modo de ejecución correcto. Se añaden además dos convenciones nuevas, spirv_task y spirv_mesh, para dar soporte al pipeline de mesh shading. Del lado del usuario, declarar la función de entrada de un compute shader se vuelve tan natural como declarar una función Zig exportada cualquiera.
Tercero, generación de código multihilo. Desde el primer día, el backend SPIR-V corría en un solo hilo dentro del hilo del enlazador. Esta refactorización lo integra en el pipeline unificado MIR → generación de código del compilador: cada tarea de generación de código se despacha al pool de hilos igual que cualquier otro backend autohospedado. También regresan los pases de ISel dedup_types (fusión de instrucciones de tipo duplicadas) y prune_unused (eliminación de código muerto), que se habían perdido en la refactorización anterior al monohilo y que ahora se recuperan gracias a la mejora arquitectónica. Para el usuario, el impacto inmediato es la velocidad de compilación. Para el juicio ingenieril, significa que el backend SPIR-V sale del estatus de “régimen especial” en la arquitectura y se convierte en una unidad de compilación al mismo nivel que los demás targets.
Cuarto, enlazado de archivos objeto. Los archivos .spv se reconocen ahora como formato de archivo objeto. Varios archivos .zig (u objetos .spv externos) pueden compilarse y luego ser unidos por el enlazador SPIR-V en un solo módulo. Esto implica que los proyectos grandes de shaders pueden dividirse en múltiples unidades de compilación y, en teoría, admiten compilación incremental y distribución de librerías — aunque estos flujos de trabajo avanzados aún no están listos, los cimientos a nivel de formato ya están puestos.
Quinto, las capacidades y extensiones pasan a gobernarse desde el conjunto de features de la CPU. Antes, OpCapability y OpExtension se insertaban ad hoc desde la generación de código o el ensamblador inline. Ahora se extrae la cadena de dependencias desde SPIRV-Headers y se gestiona unificadamente mediante el conjunto de features de la CPU. El ensamblador rechaza cualquier intento de insertar manualmente estas instrucciones — el compilador empieza a asumir responsabilidad sistémica sobre la corrección de la salida, en lugar de delegar la validación en la herramienta externa spirv-val.
Comparado con cuatro semanas atrás, la tasa de tests de comportamiento ha pasado de ~39% a ~49% (target spirv64-vulkan), se han corregido decenas de bugs y std.gpu ha pasado a llamarse std.spirv. El propio Cheraghi se expresa con contención: “el backend SPIR-V es significativamente más usable que hace un mes, pero aún le queda mucho.”
Situado en el mapa de la competencia
Zig no es el único proyecto que intenta tender un puente desde un lenguaje de propósito general hacia la GPU. Poner juntos los principales competidores ayuda a ubicar con más precisión el backend SPIR-V de Zig.
Rust GPU (rust-gpu) es el referente más directo. Basado en rustc_codegen_spirv, compila Rust a shaders SPIR-V. El proyecto arrancó hacia 2019, pasó por el apoyo de Embark Studios y luego fue transferido a la comunidad. Actualmente cuenta con un subconjunto usable de la librería estándar (spirv-std), demos ejecutables en el navegador con SHADERed y un framework experimental SPIR-T para optimización en tiempo de enlace. Pero a juzgar por los issues de GitHub y la discusión comunitaria, las actualizaciones del compilador de Rust suelen forzar al plugin de codegen a adaptaciones de mantenimiento, y todavía no hay versión estable.
Circle C++ Shader Compiler permite escribir shaders en C++ estándar, con atributos que marcan los puntos de entrada a la GPU y compilación directa a SPIR-V. A nivel sintáctico recuerda a CUDA — fuente única, superconjunto de C++. Pero Circle es un compilador de código cerrado mantenido por una sola persona, Sean Baxter, lo que limita el alcance de su ecosistema.
Julia GPU, a través de CUDA.jl y AMDGPU.jl, ofrece capacidad de programación de GPU saltándose SPIR-V y generando directamente instrucciones PTX o AMDGCN. Su ventaja está en el desarrollo interactivo — escribes un kernel en el REPL y lo ejecutas al instante. La desventaja también es clara: la portabilidad entre fabricantes depende del ecosistema de paquetes, no de un IR estándar.
El backend SPIR-V de Zig ocupa un lugar muy concreto en este mapa: es el único backend SPIR-V autohospedado dentro de un compilador de lenguaje de sistemas. Rust-gpu es un plugin externo de codegen para el compilador de Rust, no un componente de primera clase del proyecto Rust. Circle es un proyecto personal de código cerrado. Julia sortea SPIR-V. El backend SPIR-V de Zig se mantiene en el mismo repositorio, con el mismo sistema de build y es revisado por el mismo grupo de contribuidores principales que los backends x86, ARM y RISC-V.
Es un arma de doble filo. Compartir repositorio con la rama principal del compilador implica que el backend SPIR-V evoluciona pasivamente con cada ajuste arquitectónico del compilador Zig — el bitrot es el precio de ese acoplamiento estrecho. Pero también implica que cualquier mejora en la infraestructura del compilador (sistema de tipos, pipeline de generación de código, enlazador) puede beneficiar automáticamente al backend SPIR-V. La recuperación de la generación de código multihilo que relata el devlog del 26 de junio es un ejemplo concreto de este mecanismo: la decisión arquitectónica de unificar el pipeline MIR le “regaló” al backend SPIR-V la capacidad de despacho al pool de hilos.
Los verdaderos obstáculos no están dentro del compilador
Visto desde la hoja de ruta técnica, los mayores obstáculos que tiene por delante el backend SPIR-V de Zig no están del todo dentro del compilador.
El primer obstáculo son los espacios de direcciones. El modelo de memoria de la GPU distingue varios espacios (global, local, private, constant), mientras que los punteros de Zig asumen por defecto un espacio de direcciones genérico. El blog de Cheraghi menciona que Vulkan no soporta OpPtrCastToGeneric, así que la implementación actual asigna todos los punteros a la clase de almacenamiento Function como solución provisional. Esto implica que las operaciones complejas con punteros (como pasar referencias entre espacios de direcciones) estarán limitadas en el target Vulkan. En el target OpenCL la situación es algo mejor, porque el entorno base de OpenCL garantiza más capacidades, y la tasa de tests de comportamiento es más alta (~75%).
El segundo obstáculo son las diferencias de semántica numérica. En el entorno Vulkan, instrucciones como fma, sqrt, exp y log no garantizan redondeo correcto, lo que entra en conflicto con las asunciones por defecto de semántica numérica del compilador Zig. Zig exige más determinismo del que los lenguajes de shaders toleran típicamente en precisión numérica. No es necesariamente un problema irresoluble — tanto Rust GPU como los compiladores de GLSL se han enfrentado a la misma brecha semántica —, pero requiere decisiones de diseño explícitas y documentación, y ese trabajo aún está en curso.
El tercer obstáculo está en la capa del ecosistema: la adaptación de la librería estándar. En la GPU no hay sistema operativo, no hay sistema de archivos, no hay asignador de heap (al menos no en el sentido tradicional). Una gran cantidad de código de la librería estándar de Zig depende de esos supuestos. Migrar std.math, std.sort y las estructuras de datos y algoritmos más comunes a un subconjunto compatible con GPU es un trabajo de una envergadura comparable a la del propio backend del compilador. En su lista de “próximos pasos”, Cheraghi menciona algoritmos básicos como suma de prefijos, reducción y multiplicación de matrices — los ladrillos fundamentales de las cargas de trabajo de HPC y ML. El criterio de priorización es correcto, pero también indica que el progreso está aún en fase temprana.
Por qué esta entrada del devlog llamó la atención
Volvamos a aquel post de 28 puntos en Lobsters. Más allá de los detalles técnicos, el entusiasmo tiene dos fuentes.
Una fuente es la marca temporal. Ese mismo día, el devlog de Zig traía otra actualización — “New @bitCast Semantics and LLVM Backend Improvements”, de Matthew Lugg — que en Lobsters generó 16 comentarios por separado. Dos entradas del compilador Zig en portada el mismo día no es lo normal en una comunidad como Lobsters. Lo que señala es la vitalidad del ecosistema del lenguaje: el compilador Zig avanza simultáneamente en varios frentes — degradación de enteros, semántica de bitCast, optimizaciones del backend LLVM, reparaciones del backend SPIR-V. No es un proyecto que itere en una sola dirección.
La otra fuente es la señal de dirección. La mera existencia del backend SPIR-V está diciendo: los maintainers de Zig consideran que un lenguaje de sistemas debe poder compilar código de GPU. Es una declaración de que la GPU es territorio legítimo de la programación de sistemas — un 49% de tests superados aún no permite decir “también damos soporte a GPU”.
Esta dirección difiere de la historia de Rust en GPU. La propuesta de valor de la filosofía de seguridad de Rust en GPU es clara: el sistema de ownership puede prevenir data races en tiempo de compilación, una ventaja natural en el modelo de programación masivamente paralelo de la GPU. La propuesta de valor de Zig es distinta: cero asignación implícita, la computación en tiempo de compilación es el mismo lenguaje, gestión explícita del flujo de control. En GPU, que no haya asignación implícita significa que no vas a invocar accidentalmente un asignador de heap que no existe. Comptime significa que la estrategia de distribución de workgroups, el layout de memoria y los factores de unrolling pueden decidirse dinámicamente en tiempo de compilación con base en las capacidades del target GPU — sin macros, sin scripts de generación de código.
¿Cuál es mejor para programar GPUs? No tengo criterio para responder. Ambos lenguajes están aún en fase demasiado temprana en su andadura sobre GPU; la escasez de datos no permite ninguna conclusión comparativa. Pero desde la óptica de la diversidad del ecosistema, que dos lenguajes de sistemas con filosofías distintas estén atacando SPIR-V al mismo tiempo es mejor que tener solo uno.
Declaración de humildad
El análisis de este artículo se basa en el devlog de Zig del 26 de junio de 2026, el artículo del blog de Ali Cheraghi “Zig and GPUs”, la discusión de la comunidad de Lobsters y la documentación pública de la especificación SPIR-V de Khronos. El autor no ha contribuido al compilador Zig ni ha compilado y ejecutado shaders personalmente bajo el target spirv64-vulkan. Los datos citados en el texto, como la tasa del 49% de tests de comportamiento, proceden de lo declarado por el autor del devlog y no han sido verificados de forma independiente. Las descripciones del estado actual de Rust GPU, Circle y Julia GPU se basan en repositorios públicos, discusiones comunitarias y artículos académicos; la usabilidad real de cada proyecto puede variar significativamente según el caso de uso. Si tienes experiencia directa de ingeniería en cualquiera de estos campos, las precisiones son bienvenidas.