- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This code:
#include <stdio.h>
#include <stdint.h>
#include <fenv.h>
#include <math.h>
#pragma STDC FENV_ACCESS ON
int main (void)
{
#if __STDC_IEC_559__ == 1
typedef union
{
uint32_t u;
float v;
} u_t;
u_t snan = { .u = 0x7FA00000 };
float f = snan.v - snan.v;
if ((fetestexcept(FE_INVALID) & FE_INVALID) == 0)
{
printf("error: no FE_INVALID raised\n");
return 1;
}
(void)f;
#endif
return 0;
}
compiled with: icc -std=c11 -pedantic -Wall -Wextra
leads to: error: no FE_INVALID raised
which is expected because __STDC_IEC_559__ is 1.
This is because subss is not generated.
Version: x86-64 icc 2021.1.2 on Linux
Notes:
1. Yes, the __SUPPORT_SNAN__ is not defined.
2. The -fp-model=strict solves the issue.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Thanks for posting in Intel Communities.
Yes, you are absolutely right.
By using -fp-model=strict, the code works fine because strict enables pragma stdc fenv_access.
For more information, please refer to the link mentioned below.
Thanks & Regards,
Ditipriya.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Why under -fp-model= ! strict (non-strict) __STDC_IEC_559__ is 1?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
The flag (-fp-model=strict) being used here to compile the code is disabling optimization, thus, giving us the exact values as the output. There is no direct relation between the macro and the flag being used here. The value of __STDC_IEC_559__ depends on the host platform, by default, it is 0 for windows and 1 for Linux. Please check the attachments for more information.
While executing the code on Visual Studios (using -fp-model=strict), the value of the macro is set to 0 by default during compilation and thus, it is not satisfying the if condition (#if __STDC_IEC_559__ == 1), thereby, not executing the statements within the if block. As for Linux, the value of the macro is set to 1 and it is satisfying the if condition and hence, executing the statements within the if block (using -fp-model=strict).
Please let us know whether the information provided above was helpful in resolving your issue.
Thanks & Regards,
Ditipriya.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If Intel C compiler under non-strict floating-point models does not conform to the specifications in the Annex F, then for which purpose it defines __STDC_IEC_559__ to 1?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It seems that there is a typo.
Before: "which is expected because __STDC_IEC_559__ is 1".
After: "which is unexpected because __STDC_IEC_559__ is 1".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
We are working on this issue and we will get back to you soon.
Thanks and Regards,
Ditipriya.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don’t think this issue is related to __STDC_IEC_559__, but rather related to floating-point computations.
When come to floating-point calculations, we optimize more aggressively at default. These optimizations increase speed but may affect the accuracy or reproducibility of floating-point computations.
Let’s look at your example after removed #if __STDC_IEC_559__ and #endif
$cat t.c
#include <stdio.h>
#include <stdint.h>
#include <fenv.h>
#include <math.h>
#pragma STDC FENV_ACCESS ON
int main (void)
{
typedef union
{
uint32_t u;
float v;
} u_t;
u_t snan = { .u = 0x7FA00000 };
float f = snan.v - snan.v;
if ((fetestexcept(FE_INVALID) & FE_INVALID) == 0)
{
printf("error: no FE_INVALID raised\n");
return 1;
}
else
{
printf ("hello \n");
}
(void)f;
return 0;
}
$ rm a.out; icc t.c -c ;icc t.o &&./a.out
error: no FE_INVALID raised
$ rm a.out; icc t.c -c -fp-model precise;icc t.o &&./a.out
hello
=== gcc at default has the same output as icc and -fp-model precise/strict
$ rm a.out; gcc t.c -c ;g++ t.o &&./a.out
hello
=== icc at default has the same output as gcc and -ffast-math
$ rm a.out; gcc t.c -c -ffast-math ;g++ t.o &&./a.out
error: no FE_INVALID raised
$
So, depending on which compilers and options you select, the floating-point calculation’s results might be different. More info about Intel floating point calculations can be seen https://www.intel.com/content/www/us/en/develop/documentation/oneapi-dpcpp-cpp-compiler-dev-guide-an...
Thanks,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If Intel C compiler under non-strict floating-point models does not conform to the specifications in the Annex F, then for which purpose it defines __STDC_IEC_559__ to 1?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can you elaborate why you think Intel C compiler under non-strict floating-point models does not conform to the specifications in the Annex F? What the differences you see between ICC vs. GCC wrt __STDC_IEC_559__ ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Because the documentation says so (one example):
> These optimizations increase speed, but may affect the accuracy or reproducibility of floating-point computations.
As I understand, the Annex F does not allow to "affect the accuracy or reproducibility of floating-point computations".
Another example:
#include <stdio.h>
#if __STDC_IEC_559__ == 1
float f(float a, float b, float c) __attribute__((noinline));
float f(float a, float b, float c)
{
return a * c + b * c;
}
int main(void)
{
void* p = f;
printf("%a\n", f(4476.0f, 20439.0f, 4915.0f));
return 0;
}
#endif
gcc -std=c11
0x1.d32324p+26
icc -std=c11 -fp-model=fast -O0
0x1.d32324p+26
icc -std=c11 -fp-model=fast -O1
0x1.d32322p+26
Here we see that icc:
- produces different results
- __STDC_IEC_559__ is 1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As I understand, the Annex F does not allow to "affect the accuracy or reproducibility of floating-point computations"
If you can send a link to show that the above statement is true at the default (no other options are needed), then I can forward it to our the developer.
As I've mentioned you can use -fp-model precise to get the same output as gcc.
Thanks,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
C11, F.3 Operators and functions, 1:
> C operators and functions provide IEC 60559 required and recommended facilities as listed below.
> — The +, −, *, and / operators provide the IEC 60559 add, subtract, multiply, and divide operations.
If Intel C compiler under non-strict floating-point models does not conform to the specifications in the Annex F, then for which purpose it defines __STDC_IEC_559__ to 1?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I see what you meant. icc somehow always defines this macro whereas gcc isn't.
Let me work with our Front End team and get back to you.
Thanks,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Looks like there is an issue on how icc defines _STDC_IEC_559__.
I've reported this bug to our Front End team and will keep you updated once I hear from them.
Thanks,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Classic Compiler (icc) will be end of life by end of 2023. Therefore, this issue won't be fixed in Classic Compiler. Please migrate to Intel oneAPI DPC++/C++ Compiler (icx).
We will close it as "will not fix"
Thanks,
Viet
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page