0

Can the following code:

float f = sinf(0.5f);

be optimized to the following code (actually pseudocode to give an idea):

float f = 0x1.eaee88p-2f;
feraiseexcept(FE_INEXACT);

The same principle for the other C standard library functions. As I understand, since the "whole language is based on the (rather unhelpful) concept of an "abstract machine" (link), then an "implementation is free to do anything in the ways of optimizations as long as side effects and "the observable behavior" are respected" (the same link).

pmor
  • 5,392
  • 4
  • 17
  • 36
  • I guess the compiler can't to that because it would be wrong if the function has side effects, and afaik there is no way in C to guarantee that a function has no side effects. – mkrieger1 Dec 29 '21 at 11:57
  • @pmor What a C compiler can do is make the function inline. – Vlad from Moscow Dec 29 '21 at 12:01
  • Pretty sure they can and they do. GCC even without optimizations enabled: https://godbolt.org/z/rEhYE7jvh – user17732522 Dec 29 '21 at 12:05
  • 1
    @mkrieger1: A compile can know a function has no side effects, or can know what those side effects are, if it knows the specification of the function, can see the definition of the function, or is informed of attributes of the function with an extension such as GCC’s `__attribute__((__pure__))`. The standard library`sin` is specified by the C standard and the identifier `sin` with external linkage is reserved for that purpose, so the compiler may rely on `sin` being the standard library `sin`. – Eric Postpischil Dec 29 '21 at 12:48

1 Answers1

4

Some compilers will optimize it to the simple constant expression. It is because the compiler knows how functions from the standard library work. The compiler knows that sinf does not have side effects.

int main(void)
{
    float f = sinf(0.5f);
    printf("%f\n", f);
} 
.LC1:
        .string "%f\n"
main:
        sub     rsp, 8
        mov     edi, OFFSET FLAT:.LC1
        mov     eax, 1
        movsd   xmm0, QWORD PTR .LC0[rip]
        call    printf
        xor     eax, eax
        add     rsp, 8
        ret
.LC0:
        .long   -2147483648
        .long   1071558376
0___________
  • 60,014
  • 4
  • 34
  • 74
  • Re: "The compiler knows that sinf does not have side effects.": `sinf` may raise floating-point exceptions, which is a side effect. However, `#pragma STDC FENV_ACCESS` in state `OFF` (usually by default) allows "certain optimizations that could subvert flag tests and mode changes (e.g., global common subexpression elimination, code motion, and constant folding)" (C11). – pmor Jan 10 '22 at 20:24
  • @pmor It does know in this context. When the argument is a constant expression and the compiler knows that it is not `+-inf` - no side effects. Everything is written in some context - general comments not taking this comment into the account make no sense at all – 0___________ Jan 10 '22 at 21:24
  • @pmor In the case of infinity or other potential problems, it will call the function https://godbolt.org/z/h193YYEq5 – 0___________ Jan 10 '22 at 21:30
  • Since in gcc [Pragma STDC * (C99 FP) unimplemented](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=20785) change gcc to clang and add `#pragma STDC FENV_ACCESS ON`. Result: `sinf` in `bar` is computed at run time. This is because the compiler knows that `sinf` does have side effects. – pmor Jan 11 '22 at 15:55