Войти
ПрограммированиеФорумОбщее

Помогите настроить таргеты компиляции Clang (8 стр)

Страницы: 13 4 5 6 7 8
#105
11:17, 8 ноя. 2019

CgReligion

Я бы с тобой согласился, если бы при атрибуте ms_abi они показывали одинаковый результат:
https://godbolt.org/z/q6MyvQ


#106
(Правка: 18:12) 12:17, 8 ноя. 2019

DevilDevil

Можно предположить, что причина различия здесь совсем в другом. Проведённые некоторые исследования только подтверждают то, что написано выше. Кстати, если компилировать пример GCC, то для всех версий последнего получится идентичный код. Значение выталкивается из st(0) и сохраняется в памяти. При компиляции clang с таргетом смотрящим в сторону Linux такого не происходит, даже, при использовании атрибута __attribute__ ((ms_abi)).

сlang для передачи из функции значения long double задействует регистр st(0), то есть использует специальное соглашение для типа long double. И здесь вроде бы происходит нарушение соглашения о вызовах Windows x64. При этом там тип long double точно не определен, но в большинстве случаев он трактуется, как double. сlang же генерирует код со своим собственным специальным соглашение для long double с которым он (и только он) знает, как работать. Это особенность компилятора в рамках выбранной реализации в полном соответствии со Стандартом языка. И вообще, компилятор не обязан создавать совместимый код для двоично несовместимых с OC типов. При этом сlang будет генерировать  полностью ABI-совместимый код для Windows x64,  если long double мутанта спрятать так, чтобы он его не видел: 

typedef struct b16
{
    char        s[16];
} b16;

__attribute__ ((ms_abi)) b16 test()
{
    long double x = 0;

    return *(b16*)&x;
}

Можно так же добавить, что long double прямо не отображается ни в один из известных типов IEEE 754. Поэтому он определятся компилятором и в разных ситуация это определение может отличаться.

#107
16:49, 8 ноя. 2019

CgReligion

Я не знаю, офтоп это или нет, но если есть какой-то таргет, которым можно убрать дефолтное выравнивание функций - я с удовольствием выслушаю. По крайней мере флаг -falign-functions=4 не работает.

Описание проблемы: https://stackoverflow.com/questions/58754551/clang-functions-aligning

#108
(Правка: 18:10) 17:48, 8 ноя. 2019

DevilDevil

Указанный флаг компиляции -falign-functions к таргету вообще никакого отношения не имеет. Это флаг, который просит компилятор сделать что-то, если тот предоставляет такую возможность. Обращение к невыровненным данным приводит к задержке исполнения, а на некоторых архитектурах к возникновению аппаратного исключения. Поэтому обычно требуется выравнивание, а не его отсутствие. Если компилятор не поддерживает флаг -falign-functions, значит у него есть основания так поступать. И вообще он лучше знает, что, как, в каком порядке и где расставлять. Конкретные адреса размещения функций и выравнивание особенно, относятся к конкретной реализации и от них ничего не должно зависеть. Контроль над ними находится точно уровнем ниже.

#109
18:34, 8 ноя. 2019

CgReligion

Просто на GCC можно сделать выравнивание, а на Clang не понятно, как это сделать )

#110
(Правка: 21:33) 19:24, 8 ноя. 2019

DevilDevil

В сlang функции выравниваются на границу 16 байт и это нельзя изменить. Это связанно с особенностями реализации указателей на функции-члены класса в C++ ABI. Они определяются двум указателями. Выравнивание адресов функций С, по всей видимости, было захвачено заодно. Но в этом ничего плохого нет, потому как выравнивание — это хорошо.

#111
20:08, 8 ноя. 2019

CgReligion

Я привёл пример, когда выравнивание это плохо. И очень жаль. Может быть придётся мучать GCC )

#112
(Правка: 9 ноя. 2019, 0:46) 21:07, 8 ноя. 2019

DevilDevil

Здесь внезапно обнаружилось заклинание, которое воздействует на адреса функций:

-mllvm -align-all-functions=n                 где alignment = 2^n, n >= 1

Но полагаться на всё это в длительной перспективе вряд ли стоит.

#113
13:25, 9 ноя. 2019

CgReligion

Да
Сделал параметр 16 и офигел :)
Выравнивание на 4 байта получилось при параметре 2

Ок
А можно как-то это применить локально для определённого набора функций?

#114
(Правка: 16:10) 15:57, 9 ноя. 2019

DevilDevil

Можно. Тогда определённый набор функций нужно разместить локально в одном файле и откомпилировать, с заданными флагами или без, в зависимости от того к какому множеству он относится.

#115
16:16, 9 ноя. 2019

CgReligion

Не, у меня один скрипт на все файлы
Я имел ввиду через атрибуты или прагму как-то

#116
23:33, 15 апр. 2020

Друзья, тут всплыла ещё одна особенность, которую хотелось бы устранить
Допустим, у нас платформа Win32, есть функция, которая возвращает 8 байт
Когда возвращается int64_t - нормально возвращаться в паре EAX:EDX
Но если это структура - результат должен передаваться через скрытый указатель

В нашем же примере это условие не только не выполняется, но ещё и зависит от состава структуры. Что с этим можно сделать? На уровне опций компилятора имею ввиду :)

typedef struct {
    char values[8];
} char_struct;

typedef struct {
    double value;
} double_struct;

char_struct char_test()
{
    char_struct ret;
    ret.values[0] = sizeof(int_struct);
    ret.values[1] = sizeof(double_struct);
    ret.values[2] = sizeof(char_struct);
    return ret;
}

double_struct double_test()
{
    double_struct ret;
    ret.value = 1;
    return ret;
}

Дизасм:

_char_test:                             # @char_test
        mov     eax, 526344
        xor     edx, edx
        ret
_double_test:                           # @double_test
        fld1
        ret

#117
23:41, 15 апр. 2020

Кстати на линуксе работает правильно, а вот на винде и маке нет:
https://godbolt.org/z/CZmQAY

#118
0:35, 23 мая 2020

Всем привет

Возникли ещё вопросы по таргетам
На текущий момент использую следующие опции компилятора:

-target i386-windows-gnu -mno-sse -c -O3
-target x86_64-windows-gnu -mcx16 -c -O3
-target i386-linux-gnu -mno-sse -c -O3
-target x86_64-linux-gnu -mcx16 -c -O3
-target i386-darwin-gnu -mno-sse -fomit-frame-pointer -c -O3
-target x86_64-macos-gnu -fomit-frame-pointer -c -O3
-target armv7-none-linux-androideabi -mfpu=neon -mfloat-abi=hard -mthumb -fPIC -c -O3
-target aarch64-linux-android -c -O3
-target armv7m-none-ios-gnueabi -mfpu=neon -mfloat-abi=hard -mthumb -c -O3
-target arm64-darwin-gnu -fno-stack-protector -c -O3

Нареканий нет только по Линуксу/Андроиду. Для остальных платформ выдаёт ворнинг (https://godbolt.org/z/YhZ5uc). Раньше я думал, что дело в других аргументах кроме -target, но если их убрать - ничего не меняется:

clang-9: warning: argument unused during compilation: '--gcc-toolchain=/opt/compiler-explorer/gcc-9.2.0' [-Wunused-command-line-argument]
Compiler returned: 0

Эта история хотя бы компилится. Для Mac/iOS начинается история с неподдержкой TLS-переменных (https://godbolt.org/z/6bqjby):

:2:1: error: thread-local storage is not supported for the current target

Чё с этим делать?

#119
21:15, 28 мая 2020

up? )

Страницы: 13 4 5 6 7 8
ПрограммированиеФорумОбщее