Je crois que tu n'as pas vraiment compris le problème. Si dans l'ir tu lui donnes un "i32*" ou "i8*" alors llc à la compilation demande aux classes qui encapsulent les target-datalayout quelle est la taille d'un pointeur.
Et effectivement en changeant l'architecture avec -march=XXX, tu changes le target-datalayout utilisé.
Le problème vient du fait qu'un "long" (le type c) n'a pas la même taille sur 32 et 64 bits.
Si tu prends le code suivant :
int main() {
printf("%d\n", sizeof(long)/sizeof(int));
}
Sur 32 bits tu vas avoir le résultat "1" sur 64 bits le résultat sera "2".
En générant l'ir, clang | opt résumera l'appel à
printf("%d\n" , 1); sur 32 bits
et
printf("%d\n" , 2); sur 64 bits
Donc clang lors de la génération de l'ir prend les dimensions de la plateforme (long=4 ou long=8) et génère l'ir. Ca veut dire que l'ir qu'il soit généré avec clang sur 32 ou 64 bits n'aura pas la même tête si il y a des "long" ou autres trucs de ce genre dans ton code.
Le premier exemple que j'ai donné est un bon exemple : il est portable en c et pas en llvm.
[^] # Re: LLVM IR n'est pas portable
Posté par meuh31 . En réponse au journal LLVM dans un gestionnaire de paquets ?. Évalué à 1.
Et effectivement en changeant l'architecture avec -march=XXX, tu changes le target-datalayout utilisé.
Le problème vient du fait qu'un "long" (le type c) n'a pas la même taille sur 32 et 64 bits.
Si tu prends le code suivant :
int main() {
printf("%d\n", sizeof(long)/sizeof(int));
}
Sur 32 bits tu vas avoir le résultat "1" sur 64 bits le résultat sera "2".
En générant l'ir, clang | opt résumera l'appel à
printf("%d\n" , 1); sur 32 bits
et
printf("%d\n" , 2); sur 64 bits
Donc clang lors de la génération de l'ir prend les dimensions de la plateforme (long=4 ou long=8) et génère l'ir. Ca veut dire que l'ir qu'il soit généré avec clang sur 32 ou 64 bits n'aura pas la même tête si il y a des "long" ou autres trucs de ce genre dans ton code.
Le premier exemple que j'ai donné est un bon exemple : il est portable en c et pas en llvm.