Commit 30a2c10e by Jakub Jelinek Committed by Jakub Jelinek

re PR middle-end/82004 (SPEC CPU2017 628.pop2_s miscompare)

	PR tree-optimization/82004
	* gimple-match-head.c (optimize_pow_to_exp): New function.
	* match.pd (pow(C,x) -> exp(log(C)*x)): Wrap with #if GIMPLE.
	Don't fold to exp if optimize_pow_to_exp is false.

	* gcc.dg/pr82004.c: New test.

From-SVN: r258930
parent cefc0906
2018-03-28 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/82004
* gimple-match-head.c (optimize_pow_to_exp): New function.
* match.pd (pow(C,x) -> exp(log(C)*x)): Wrap with #if GIMPLE.
Don't fold to exp if optimize_pow_to_exp is false.
2018-03-28 Martin Liska <mliska@suse.cz>
PR other/84819
......
......@@ -840,3 +840,71 @@ canonicalize_math_after_vectorization_p ()
{
return !cfun || (cfun->curr_properties & PROP_gimple_lvec) != 0;
}
/* Return true if pow(cst, x) should be optimized into exp(log(cst) * x).
As a workaround for SPEC CPU2017 628.pop2_s, don't do it if arg0
is an exact integer, arg1 = phi_res +/- cst1 and phi_res = PHI <cst2, ...>
where cst2 +/- cst1 is an exact integer, because then pow (arg0, arg1)
will likely be exact, while exp (log (arg0) * arg1) might be not.
Also don't do it if arg1 is phi_res above and cst2 is an exact integer. */
static bool
optimize_pow_to_exp (tree arg0, tree arg1)
{
gcc_assert (TREE_CODE (arg0) == REAL_CST);
if (!real_isinteger (TREE_REAL_CST_PTR (arg0), TYPE_MODE (TREE_TYPE (arg0))))
return true;
if (TREE_CODE (arg1) != SSA_NAME)
return true;
gimple *def = SSA_NAME_DEF_STMT (arg1);
gphi *phi = dyn_cast <gphi *> (def);
tree cst1 = NULL_TREE;
enum tree_code code = ERROR_MARK;
if (!phi)
{
if (!is_gimple_assign (def))
return true;
code = gimple_assign_rhs_code (def);
switch (code)
{
case PLUS_EXPR:
case MINUS_EXPR:
break;
default:
return true;
}
if (TREE_CODE (gimple_assign_rhs1 (def)) != SSA_NAME
|| TREE_CODE (gimple_assign_rhs2 (def)) != REAL_CST)
return true;
cst1 = gimple_assign_rhs2 (def);
phi = dyn_cast <gphi *> (SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def)));
if (!phi)
return true;
}
tree cst2 = NULL_TREE;
int n = gimple_phi_num_args (phi);
for (int i = 0; i < n; i++)
{
tree arg = PHI_ARG_DEF (phi, i);
if (TREE_CODE (arg) != REAL_CST)
continue;
else if (cst2 == NULL_TREE)
cst2 = arg;
else if (!operand_equal_p (cst2, arg, 0))
return true;
}
if (cst1 && cst2)
cst2 = const_binop (code, TREE_TYPE (cst2), cst2, cst1);
if (cst2
&& TREE_CODE (cst2) == REAL_CST
&& real_isinteger (TREE_REAL_CST_PTR (cst2),
TYPE_MODE (TREE_TYPE (cst2))))
return false;
return true;
}
......@@ -4006,6 +4006,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* pow(C,x) -> exp(log(C)*x) if C > 0,
or if C is a positive power of 2,
pow(C,x) -> exp2(log2(C)*x). */
#if GIMPLE
(for pows (POW)
exps (EXP)
logs (LOG)
......@@ -4035,8 +4036,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
}
}
(if (!use_exp2)
(exps (mult (logs @0) @1))
(if (optimize_pow_to_exp (@0, @1))
(exps (mult (logs @0) @1)))
(exp2s (mult (log2s @0) @1)))))))
#endif
/* pow(C,x)*expN(y) -> expN(logN(C)*x+y) if C > 0. */
(for pows (POW)
......
2018-03-28 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/82004
* gcc.dg/pr82004.c: New test.
2018-03-28 Jakub Jelinek <jakub@redhat.com>
Martin Liska <mliska@suse.cz>
PR sanitizer/85081
......
/* PR tree-optimization/82004 */
/* { dg-do run } */
/* { dg-options "-Ofast" } */
extern double log10 (double);
extern double pow (double, double);
__attribute__((noipa)) void
bar (double x)
{
if (x < 0.001)
__builtin_abort ();
asm volatile ("" : : : "memory");
}
int
main ()
{
double d = 0.001;
double e = 10.0;
double f = (log10 (e) - log10 (d)) / 400.0;
double g = log10 (d) - f;
volatile int q = 0;
int i;
if (__builtin_expect (q == 0, 0))
for (i = 0; i < 400; ++i)
{
g = g + f;
bar (pow (10.0, g));
}
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment