clang bug?



  • #include <iostream>
    #include <string>
    #include <random>
    
    std::string generateRandomString(size_t len)
    {
        std::string alphabet = "ABCD";
        std::random_device rd;
        std::default_random_engine rng(rd());
        std::uniform_int_distribution<int> dist (0, alphabet.size()-1);
    
        std::string randomString;
        randomString.reserve(len);
        for(size_t i = 0; i < len; ++i)
            randomString.push_back(alphabet[dist(rng)]);
        return randomString;
    }
    
    int main()
    {
        std::cout << generateRandomString(20) << '\n';
    }
    
    clang++ -Wall -ansi -pedantic -std=c++11 -march=native -O3 -o test test.cpp
    

    Dieser Code kompiliert mit clang++ 3.5 fehlerfrei, stürzt dann aber mit dem Fehler "Ungültiger Maschinenbefehl" ab. Wenn ich ohne -O3 kompilere, läufts wunderbar. Kann das wer bestätigen?



  • Was wenn du ohne -march=native kompillierst?



  • Ups, danke, es liegt am -march=native, nicht am -O3. Trotzdem nicht schön. Wird meine CPU nicht richtig erkennt? Bzw. kann das noch jemand reproduzieren?



  • Sry für den Doppelpost, ich brauche Schlaf...

    Es liegt an der Kombination von den beiden flags. Beide einzeln funktionieren, zusammen stürzts an.



  • Na dann auf und den Fehler melden! 🙂



  • Entweder deine CPU wird falsch erkannt oder llvm glaubt, sie haette ein feature, das aber fehlt.



  • Also wenn das jemand auf seinem PC reproduzieren kann, dann würde ich den Fehler melden gehen.


  • Mod

    derUser schrieb:

    Also wenn das jemand auf seinem PC reproduzieren kann, dann würde ich den Fehler melden gehen.

    Dann nenn doch erst einmal dein System und die genaue Bezeichnung deiner CPU! Und warum so schüchtern? Das ist eindeutig ein Bug (oder du hast eine gefälschte CPU aus China, wo so eine alte CPU genommen haben und die CPUID geändert haben :p ).



  • Compilier zusätzlich mit der Option -v . In der Consolenausgabe sollte dann '-target-cpu XXX' erscheinen und zu deiner CPU passen.



  • Sollte der Output moderner Compiler nicht auf sämtlichen CPUs seit sagen-wir-mal Core2 laufen?

    Intel C++ und MSVC machen das auf jeden Fall über dynamische Abfragen. Also bei Optimierungen die ein bestimmtes Feature erfordern, was nicht auch allen CPUs vorhanden ist, werden zwei (oder mehr) Varianten generiert, und dann zur Laufzeit anhand der vorhandenen CPU entschieden welche verwendet wird.

    Die diversen -target-cpu Switches sollten dann bloss noch ändern auf welcher CPU der Code besonders schnell läuft.


  • Mod

    hustbaer schrieb:

    Sollte der Output moderner Compiler nicht auf sämtlichen CPUs seit sagen-wir-mal Core2 laufen?

    Intel C++ und MSVC machen das auf jeden Fall über dynamische Abfragen.

    Anscheinend nicht, sonst würde es beim TE ja funktionieren. Da der Intel-Compiler das als Feature anpreist, ging ich bisher auch davon aus, dass andere Compiler (zumindest für unixoide Plattformen) das nicht so machen (und ich kann zumindest beim GCC keinen Hinweis auf ein solches Feature finden). Dieses Feature bläht schließlich die Executable ganz erheblich auf, daher ist es durchaus eine nachvollziehbare Designentscheidung, das nicht standardmäßig zu aktivieren. Als ich das letzte Mal geguckt habe (ist ein paar Jahre her), war es bei Intel auch noch ein optionales Feature.



  • Ich kann den Fehler unter Linux 3.18, Intel Core i5, Clang 3.5.1 nicht reproduzieren.
    -target-cpu ergibt aber "corei7". Naja, scheint nicht zu stoeren, ich kenne die Architektur der beiden Prozessoren nicht.

    Ich hatte den selben Bug aber vor ein paar Wochen, ich hatte da aber keine Zeit den Code zu reduzieren. Daher kann ich auch kein Beispiel dazu geben.


  • Mod

    osdt schrieb:

    Compilier zusätzlich mit der Option -v . In der Consolenausgabe sollte dann '-target-cpu XXX' erscheinen und zu deiner CPU passen.

    Dazu die Ausgabe von /proc/cpuinfo und dann könne wir weitersehen.



  • hustbaer schrieb:

    Sollte der Output moderner Compiler nicht auf sämtlichen CPUs seit sagen-wir-mal Core2 laufen?

    Intel C++ und MSVC machen das auf jeden Fall über dynamische Abfragen. Also bei Optimierungen die ein bestimmtes Feature erfordern, was nicht auch allen CPUs vorhanden ist, werden zwei (oder mehr) Varianten generiert, und dann zur Laufzeit anhand der vorhandenen CPU entschieden welche verwendet wird.

    Die diversen -target-cpu Switches sollten dann bloss noch ändern auf welcher CPU der Code besonders schnell läuft.

    Dafür gibt es bei GCC und Clang -mtune=[arch]. Mit -march=[arch] sagt man: "Bitte lieber Compiler, optimiere hart für [arch], egal ob es dann noch wo anders läuft, oder nicht."
    -march=native sagt zudem, dass der Compiler DEINEN Prozessor selber ermitteln soll und NUR für diesen optimieren soll.

    Es liegt also nahe, dass entweder der Prozessor falsch erkannt wird, oder ein Feature erwartet wird, dass der Prozessor eigentlich gar nicht hat.



  • OK, danke für die Erklärung.

    Ein Bug ist es auf jeden Fall - es sei denn man hätte selbst eine unpassende Architektur angegeben, und das hat der OP ja nicht.


Log in to reply