GCC 7.3 и 8.2 (ubuntu18.04) проблема с вызовом sqrt ()

Вот простой код C:

#include <math.h>

float f( float x ) { return sqrtf( x ); }

GCC 7.3 и 8.2 (amd64, ubuntu 18.04) генерирует очень странный код:

f:
  pxor xmm2,xmm2
  sqrtss xmm1,xmm0
  ucomiss xmm2,xmm0
  ja .L8    ; 0 < x? then, jump to .L8.
  movaps xmm0,xmm1
  ret
.L8:
  sub rsp,24
  movss [rsp+12],xmm1  ; save sqrtss result.
  call sqrtf
  movss xmm1,[rsp+12]  ; restore sqrtss result.
  add rsp,24
  movaps xmm0,xmm1
  ret

Такое поведение я вижу на GCC 7.3 8.2 из репозиториев ubuntu-18.04 и также на MinGW-w64. Я не смог найти эту ошибку в GCC Bugzilla (и не могу сообщить о ней).

Есть мысли?

0
задан 13 April 2019 в 21:49

1 ответ

GCC генерирует строго совместимые вычисления математических операций с плавающей точкой с кодом, который Вы скомпилировали (я подозреваю с-O2 или-O3). Я предполагаю, что Вы ожидали, что это скомпилирует его вниз во что-то как следующее (в газовом ассемблере формата):

f:
.LFB9:
        .cfi_startproc
        sqrtss  %xmm0, %xmm0
        ret
        .cfi_endproc
.LFE9:

Необходимо отключить строгие математические правила соответствия при помощи -ffast-math сгенерировать быстрее "оптимизированный" код. Обратите внимание, что эта опция включает

-fno-math-errno
-funsafe-math-optimizations
-ffinite-math-only
-fno-rounding-math
-fno-signaling-nans
-fcx-limited-range
-fexcess-precision=fast

Опции GCC, поэтому остерегайтесь потери точности и потери математических ошибок.

1
ответ дан 13 April 2019 в 21:49

Другие вопросы по тегам:

Похожие вопросы: