-
Notifications
You must be signed in to change notification settings - Fork 14.7k
Closed
Description
Please consider:
#include <stdio.h>
typedef unsigned long ul;
typedef float f;
typedef unsigned long ul1 __attribute__((ext_vector_type(1)));
typedef float f1 __attribute__((ext_vector_type(1)));
__attribute__((noinline))
f converts(ul v) { return (f)v; }
__attribute__((noinline))
f1 convertv(ul1 v) { return __builtin_convertvector(v, f1); }
int main(void) {
ul s = 0xffffff7fffffffff;
ul1 v = 0xffffff7fffffffff;
printf("%A %A\n", converts(s), convertv(v)[0]);
}
Expected output, and actual output with clang -O0
:
0X1.FFFFFEP+63 0X1.FFFFFEP+63
Actual output with clang -O3
:
0X1.FFFFFEP+63 0X1P+64
This happens because the vector conversion from i64 to f32 is performed as a vector conversion from i64 to f64, and then a conversion from f64 to f32. But both of these conversions round, and the first conversion does not preserve enough information for the second conversion to produce the correct result.