Target: x86_64-pc-linux-gnu typedef __SIZE_TYPE__ size_t; double pow (double x, double y); double log2 (double x); int main () { size_t a = 1024; size_t b = 16 * 1024; size_t c = pow (2, (log2 (a) + log2 (b)) / 2); if (c != 4 * 1024) __builtin_abort (); return 0; } $ xgcc x.c -lm; ./a.out $ xgcc x.c -lm -ffast-math; ./a.out Aborted (core dumped)
Started with r251230.
Isn't this just an invalid test? I mean, when working with floating point, especially when using -ffast-math, one needs to accept some inaccuracy. Here we compute 0x1.ffffffffffff9p+11 which is 7ulps from the correct result, I'd say for -ffast-math that is within the acceptability limit.
Created attachment 43387 [details] gcc8-pr84309.patch That said, if the target has c99 runtime and the constant is a power of 2, I can't imagine why exp2 (log2 (C) * x) wouldn't be faster and more precise than exp (log (C) * x).
(In reply to Jakub Jelinek from comment #2) > Isn't this just an invalid test? I mean, when working with floating point, > especially when using -ffast-math, one needs to accept some inaccuracy. > Here we compute > 0x1.ffffffffffff9p+11 > which is 7ulps from the correct result, I'd say for -ffast-math that is > within the acceptability limit. There's some warnings for it: $ /usr/local/bin/gcc -o 84309.exe -ffast-math -Wall -Wextra -pedantic -Wconversion -Wfloat-equal -Wdouble-promotion -Wtraditional-conversion -Wunsuffixed-float-constants 84309.c 84309.c: In function 'main': 84309.c:10:29: warning: passing argument 1 of 'log2' as floating rather than integer due to prototype [-Wtraditional-conversion] size_t c = pow (2, (log2 (a) + log2 (b)) / 2); ^ 84309.c:10:40: warning: passing argument 1 of 'log2' as floating rather than integer due to prototype [-Wtraditional-conversion] size_t c = pow (2, (log2 (a) + log2 (b)) / 2); ^ 84309.c:10:19: warning: passing argument 1 of 'pow' as floating rather than integer due to prototype [-Wtraditional-conversion] size_t c = pow (2, (log2 (a) + log2 (b)) / 2); ^ 84309.c:10:14: warning: conversion from 'double' to 'size_t' {aka 'long unsigned int'} may change value [-Wfloat-conversion] size_t c = pow (2, (log2 (a) + log2 (b)) / 2); ^~~ $ Often times -Wconversion warnings are just noise, but in this case it seems as if they might actually be relevant.
(In reply to Eric Gallager from comment #4) > (In reply to Jakub Jelinek from comment #2) > > Isn't this just an invalid test? I mean, when working with floating point, > > especially when using -ffast-math, one needs to accept some inaccuracy. > > Here we compute > > 0x1.ffffffffffff9p+11 > > which is 7ulps from the correct result, I'd say for -ffast-math that is > > within the acceptability limit. > > There's some warnings for it: The warnings are completely useless.
Author: jakub Date: Tue Feb 13 08:34:42 2018 New Revision: 257617 URL: https://gcc.gnu.org/viewcvs?rev=257617&root=gcc&view=rev Log: PR middle-end/84309 * match.pd (pow(C,x) -> exp(log(C)*x)): Optimize instead into exp2(log2(C)*x) if C is a power of 2 and c99 runtime is available. * generic-match-head.c (canonicalize_math_after_vectorization_p): New inline function. * gimple-match-head.c (canonicalize_math_after_vectorization_p): New inline function. * omp-simd-clone.h: New file. * omp-simd-clone.c: Include omp-simd-clone.h. (expand_simd_clones): No longer static. * tree-vect-patterns.c: Include fold-const-call.h, attribs.h, cgraph.h and omp-simd-clone.h. (vect_recog_pow_pattern): Optimize pow(C,x) to exp(log(C)*x). (vect_recog_widen_shift_pattern): Formatting fix. (vect_pattern_recog_1): Don't check optab for calls. * gcc.dg/pr84309.c: New test. * gcc.target/i386/pr84309.c: New test. Added: trunk/gcc/omp-simd-clone.h trunk/gcc/testsuite/gcc.dg/pr84309.c trunk/gcc/testsuite/gcc.target/i386/pr84309.c Modified: trunk/gcc/ChangeLog trunk/gcc/generic-match-head.c trunk/gcc/gimple-match-head.c trunk/gcc/match.pd trunk/gcc/omp-simd-clone.c trunk/gcc/testsuite/ChangeLog trunk/gcc/tree-vect-patterns.c
Fixed.
Author: jakub Date: Tue Feb 13 20:22:50 2018 New Revision: 257634 URL: https://gcc.gnu.org/viewcvs?rev=257634&root=gcc&view=rev Log: PR middle-end/84309 * match.pd (pow(C,x) -> exp(log(C)*x)): Use exp2s and log2s instead of exps and logs in the use_exp2 case. * gcc.dg/pr84309-2.c: New test. Added: trunk/gcc/testsuite/gcc.dg/pr84309-2.c Modified: trunk/gcc/ChangeLog trunk/gcc/match.pd trunk/gcc/testsuite/ChangeLog