2016-03-05 1 views
-1

J'ai 3 versions de gcc installées sur ma machine linux bits 64Est-ce que le flag -fixed- <reg> est toujours buggé dans GCC?

  • gcc 4.9.2
  • gcc 5.3.0
  • gcc 6 [une construction d'un instantané svn]

tous les 3 compilateurs me donnent la même erreur quand j'essaie de réserver explicitement xmm registres avec

et l'erreur est une erreur du compilateur

internal compiler error: in copy_to_mode_reg, at explow.c:595 
    return (__m128i)__builtin_ia32_paddsw128 ((__v8hi)__A, (__v8hi)__B); 
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
Please submit a full bug report, 
with preprocessed source if appropriate. 

dois-je déposer un bug? J'ai remarqué que clang ne supporte pas un drapeau similaire pour contrôler la génération de code, alors peut-être que le gcc a créé ce drapeau il y a longtemps et maintenant ça ne vaut pas le coup?

Quand je regarde le code assembleur généré à partir de ma fonction C en utilisant clang il n'y a pas eu de déversement d'octets et il ressemble à tous les registres XMM sont utilisés comme instruncted, mais gcc d'autre part ne génère pas vraiment propre assemblage et je voudrais toujours imposer ce comportement.

Il existe une autre façon de forcer une utilisation donnée des registres SSE et AVX? Il est possible d'obtenir un avertissement quand il y a une mauvaise utilisation des registres?

Merci.

fonction factice à des fins de test

#include <stdio.h> 
#include <stdint.h> 
#include <malloc.h> 
#include <emmintrin.h> 

typedef int32_t T; 

void foo(T * ptr) { 
    __m128i v0 = _mm_load_si128((__m128i *) (&ptr[0])); 
    __m128i v1 = _mm_load_si128((__m128i *) (&ptr[4])); 
    __m128i v2 = _mm_load_si128((__m128i *) (&ptr[8])); 
    __m128i v3 = _mm_load_si128((__m128i *) (&ptr[12])); 
    __m128i v4 = _mm_load_si128((__m128i *) (&ptr[16])); 
    __m128i v5 = _mm_load_si128((__m128i *) (&ptr[20])); 
    __m128i v6 = _mm_load_si128((__m128i *) (&ptr[24])); 
    __m128i v7 = _mm_load_si128((__m128i *) (&ptr[28])); 
    __m128i v8 = _mm_load_si128((__m128i *) (&ptr[32])); 
    __m128i v9 = _mm_load_si128((__m128i *) (&ptr[36])); 
    __m128i v10 = _mm_load_si128((__m128i *) (&ptr[40])); 
    __m128i v11 = _mm_load_si128((__m128i *) (&ptr[44])); 
    __m128i v12 = _mm_load_si128((__m128i *) (&ptr[48])); 
    __m128i v13 = _mm_load_si128((__m128i *) (&ptr[52])); 
    __m128i v14 = _mm_load_si128((__m128i *) (&ptr[56])); 
    __m128i v15 = _mm_load_si128((__m128i *) (&ptr[60])); 
    v0   = _mm_adds_epi16(v0, v1); 
    v0   = _mm_adds_epi16(v0, v2); 
    v0   = _mm_adds_epi16(v0, v3); 
    v0   = _mm_adds_epi16(v0, v4); 
    v0   = _mm_adds_epi16(v0, v5); 
    v0   = _mm_adds_epi16(v0, v6); 
    v0   = _mm_adds_epi16(v0, v7); 
    v0   = _mm_adds_epi16(v0, v8); 
    v0   = _mm_adds_epi16(v0, v9); 
    v0   = _mm_adds_epi16(v0, v10); 
    v0   = _mm_adds_epi16(v0, v11); 
    v0   = _mm_adds_epi16(v0, v12); 
    v0   = _mm_adds_epi16(v0, v13); 
    v0   = _mm_adds_epi16(v0, v14); 
    v0   = _mm_adds_epi16(v0, v15); 
    _mm_store_si128((__m128i *) ptr, v0); 
} 
+0

@PeterCordes J'interprétais cela comme une politique pour le pipeline de génération de code de 'gcc' lui-même, pas comme une politique qui change ce que je peux accéder avec mon propre code. Je pense qu'il est un peu trompeur de mettre cette option dans la section _code generation_. À ce stade, je ne peux pas non plus voir le scénario d'utilisation pour ce genre d'options. – xelp

+1

Vous pouvez accéder à tous les registres que vous voulez avec asm inline, et c'est précisément lorsque vous * voudriez * que gcc garde ses mains sur un registre ou deux. Mais nulle part dans ces appels intrinsèques je ne vois le nom d'un registre matériel, il doit donc être rempli lors de la * génération de code *. – rici

+0

@rici Je sais l'obtenir, merci – xelp

Répondre

3

Vous pourriez écrire cet ensemble d'options de ligne de commande beaucoup plus que lisiblement -ffixed-xmm{0..15} (bash syntaxe).

Je ne suis pas surpris qu'il casse le compilateur quand vous lui dites que tous les regs xmm sont réservés, puis vous essayez d'utiliser intrinsèques. La page de manuel gcc indique que -ffixed-reg signifie:

Traiter le registre nommé reg comme un registre fixe; code généré ne doit jamais se référer à elle (sauf peut-être comme un pointeur de pile ...


En outre, gcc 4.9.2, 5.x et instantané gcc6 tous make perfectly find code. Ils se replient toutes les charges alignées dans opérandes de mémoire pour paddsw, de sorte que la fonction est un movdqa et quinze paddsw (tous xmm0).

Avez-vous compilez sans optimisation? Bien sûr que asm sera terrible, parce que -O0 exige chaque local en mémoire après jamais Déclaration C.

+0

sur ma machine asm code généré par clang est juste plus lisible, même en utilisant 'alloca', il semble que' clang' est capable de générer une séquence d'opérations plus propre et de regrouper les mêmes genre d'opérations ensemble. Mais en termes de performances, je ne peux rien dire car je suis toujours en train d'écrire des intrinsèques et je n'ai aucune bibliothèque à tester. – xelp

+0

aussi, qu'en est-il des déversements d'octets et d'une mauvaise utilisation générale des intrinsèques? Il y a des avertissements ou des drapeaux intéressants pour ça? – xelp

+0

@xelp: J'oublie s'il y a des options pour recevoir un avertissement quand gcc sait qu'il fait du mauvais code. Dans ce cas, gcc fait du code idéal. Il ne renverse rien et ne gaspille aucune instruction. Lisez la 2ème partie de ma réponse. –

1

presque chaque fois que gcc affiche un message commençant par internal compiler error, vous devez générer un bogue. le message d'erreur inclut généralement un lien vers le site Web où vous pouvez les classer (par exemple avec votre distribution ou avec gcc en amont).

du haut de ma tête, il y a deux exceptions à cette règle:

  1. si elle dit quelque chose comme internal compiler error: Killed (program xxx) - la plupart du temps, cela est dû à votre système à court de RAM. ajoutez plus de RAM, ou augmentez l'échange, ou faites quelque chose d'autre sur votre système pour améliorer ceci.
  2. si vous réessayez la commande de compilation et cela fonctionne - la plupart du temps, c'est un bogue dans votre ordinateur plutôt que gcc (par exemple, le système d'exploitation est bogué, ou le matériel est floconneux).

votre exemple ici ne semble pas être l'un de ces cas, si ça se passe toujours avec gcc-5.3 & gcc-6 actuels instantanés, ce serait bien si vous pouviez déposer un bug. Puisque vous utilisez les snapsus gcc-6, je suppose que vous l'avez construit vous-même, donc vous pouvez aller directement à gcc's bugzilla.