Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

470
Vistas
Posible error de GCC al devolver una estructura desde una función

Creo que encontré un error en GCC al implementar PCG PRNG de O'Neill. ( Código inicial en Compiler Explorer de Godbolt )

Después de multiplicar oldstate por MULTIPLIER (resultado almacenado en rdi), GCC no agrega ese resultado a INCREMENT , sino que mueve INCREMENT a rdx, que luego se usa como el valor de retorno de rand32_ret.state

Un ejemplo mínimo reproducible ( Compiler Explorer ):

 #include <stdint.h> struct retstruct { uint32_t a; uint64_t b; }; struct retstruct fn(uint64_t input) { struct retstruct ret; ret.a = 0; ret.b = input * 11111111111 + 111111111111; return ret; }

Asamblea generada (GCC 9.2, x86_64, -O3):

 fn: movabs rdx, 11111111111 # multiplier constant (doesn't fit in imm32) xor eax, eax # ret.a = 0 imul rdi, rdx movabs rdx, 111111111111 # add constant; one more 1 than multiplier # missing add rdx, rdi # ret.b=... that we get with clang or older gcc ret # returns RDX:RAX = constant 111111111111 : 0 # independent of input RDI, and not using the imul result it just computed

Curiosamente, modificar la estructura para tener uint64_t como el primer miembro produce el código correcto , al igual que cambiar ambos miembros para que sean uint64_t

x86-64 System V devuelve estructuras de menos de 16 bytes en RDX:RAX, cuando son trivialmente copiables. En este caso, el segundo miembro está en RDX porque la mitad superior de RAX es el relleno para la alineación o .b cuando .a es un tipo más estrecho. ( sizeof(retstruct) es 16 de cualquier manera; no estamos usando __attribute__((packed)) por lo que respeta alignof(uint64_t) = 8.)

¿Este código contiene algún comportamiento indefinido que permitiría a GCC emitir el ensamblado "incorrecto"?

De lo contrario, esto debería informarse en https://gcc.gnu.org/bugzilla/

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

¿Este código contiene algún comportamiento indefinido que permitiría a GCC emitir el ensamblado "incorrecto"?

El comportamiento del código presentado en la pregunta está bien definido con respecto a los estándares del lenguaje C C99 y posteriores. En particular, C permite que las funciones devuelvan valores de estructura sin restricciones.

over 4 years ago · Santiago Trujillo Denunciar

0

No veo ningún UB aquí; sus tipos no están firmados, por lo que el UB de desbordamiento firmado es imposible, y no hay nada extraño. (E incluso si está firmado, tendría que producir salidas correctas para las entradas que no causen un desbordamiento de UB, como rdi=1 ). También está roto con el front-end C++ de GCC.

Además, GCC8.2 lo compila correctamente para AArch64 y RISC-V (a una instrucción madd después de usar movk para construir constantes, o RISC-V mul y agregar después de cargar las constantes). Si GCC estaba encontrando UB, generalmente esperaríamos que lo encontrara y rompiera su código para otros ISA también, al menos aquellos que tienen anchos de tipo y anchos de registro similares.

Clang también lo compila correctamente.

Esto parece ser una regresión de GCC 5 a 6; GCC5.4 compila correctamente, 6.1 y versiones posteriores no. ( Golpe de Dios ).

Puede informar esto en bugzilla de GCC usando el MCVE de su pregunta.

Realmente parece que es un error en el manejo de retorno de estructura x86-64 System V, tal vez de estructuras que contienen relleno. Eso explicaría por qué funciona cuando se inserta y cuando se amplía a uint64_t (evitando el relleno).

over 4 years ago · Santiago Trujillo Denunciar

0

Esto ha sido corregido en trunk / master .

Aquí está el compromiso relevante .

Y este es un parche para solucionar el problema.

Basado en un comentario en el parche, la función reload_combine_recognize_pattern intentaba ajustar USE insns .

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda