Contexte et découverte

Deux défauts d’optimisation ciblant l’architecture ARM64 ont été identifiés simultanément dans les chaînes de compilation GCC (versions 15 et 16) et le compilateur Rust. Les deux anomalies se manifestent lors de la construction de curl, l’outil de transfert HTTP largement utilisé. Les rapports indiquent des plantages ou des comportements erronés uniquement sur des processeurs ARM64, alors que les mêmes sources compilées avec d’autres versions de GCC ou avec Clang fonctionnent correctement.

Nature des bugs dans GCC

Le premier défaut concerne l’optimiseur de GCC 15/16. Une passe de vectorisation appliquée aux boucles contenant des accès mémoire non alignés génère du code où les registres SIMD sont mal initialisés. Sur ARM64, cela conduit à des lectures hors limites dans la fonction curl_easy_perform, provoquant des violations d’accès (segmentation fault). Le problème apparaît uniquement avec les options -O2 ou -O3 combinées à -march=armv8-a, ce qui explique la spécificité à l’architecture.

Défaut d’optimisation dans le compilateur Rust

Le second bug se situe dans le backend LLVM utilisé par le compilateur Rust lorsqu’il cible ARM64. Une optimisation de propagation de constantes mal appliquée à une fonction unsafe du crate curl-sys supprime une instruction de synchronisation mémoire. Le résultat est une condition de course qui se déclenche sous forte charge réseau, menant à des réponses HTTP corrompues. Le problème ne se reproduit pas avec le même code compilé en C via GCC, ce qui montre que le défaut est propre à la chaîne Rust/LLVM.

Implications et mesures correctives

Ces deux bugs soulignent la fragilité des optimisations agressives sur des architectures récentes. Les développeurs de curl ont publié des patches temporaires qui désactivent les passes incriminées via les flags -fno-tree-vectorize pour GCC et -C target-cpu=generic pour Rust. Les mainteneurs de GCC ont déjà intégré un correctif dans la branche de développement, prévu pour la version 17, tandis que l’équipe LLVM a soumis un patch qui sera intégré dans la prochaine version stable. En attendant, les équipes d’intégration continue doivent verrouiller les versions de compilateur ou ajouter les options de désactivation afin d’assurer la stabilité des builds sur ARM64.