From 9e6a14a4ee8825697eed6fe29800f2abb16713cb Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Sat, 13 Sep 2008 08:47:41 -0700 Subject: [PATCH] re PR rtl-optimization/37489 (const_true_rtx returned for float compare) gcc/ 2008-09-13 H.J. Lu PR rtl-optimization/37489 * cse.c (fold_rtx): Don't return const_true_rtx for float compare if FLOAT_STORE_FLAG_VALUE is undefined. gcc/testsuite/ 2008-09-13 Raksit Ashok PR rtl-optimization/37489 * g++.dg/opt/cse3.C: New. From-SVN: r140344 --- gcc/ChangeLog | 6 +++++ gcc/cse.c | 26 ++++++++++++++---- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/opt/cse3.C | 48 +++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/opt/cse3.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1f07adadeb9..73750417c4e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2008-09-13 H.J. Lu + + PR rtl-optimization/37489 + * cse.c (fold_rtx): Don't return const_true_rtx for float + compare if FLOAT_STORE_FLAG_VALUE is undefined. + 2008-09-13 Jan Hubicka PR tree-optimization/37392 diff --git a/gcc/cse.c b/gcc/cse.c index c1effee8f03..b911879bf79 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -3214,17 +3214,24 @@ fold_rtx (rtx x, rtx insn) if (const_arg0 == 0 || const_arg1 == 0) { struct table_elt *p0, *p1; - rtx true_rtx = const_true_rtx, false_rtx = const0_rtx; + rtx true_rtx, false_rtx; enum machine_mode mode_arg1; -#ifdef FLOAT_STORE_FLAG_VALUE if (SCALAR_FLOAT_MODE_P (mode)) { +#ifdef FLOAT_STORE_FLAG_VALUE true_rtx = (CONST_DOUBLE_FROM_REAL_VALUE (FLOAT_STORE_FLAG_VALUE (mode), mode)); +#else + true_rtx = NULL_RTX; +#endif false_rtx = CONST0_RTX (mode); } -#endif + else + { + true_rtx = const_true_rtx; + false_rtx = const0_rtx; + } code = find_comparison_args (code, &folded_arg0, &folded_arg1, &mode_arg0, &mode_arg1); @@ -3332,8 +3339,17 @@ fold_rtx (rtx x, rtx insn) const_arg1)) || (REG_P (folded_arg1) && (REG_QTY (REGNO (folded_arg1)) == ent->comparison_qty)))) - return (comparison_dominates_p (ent->comparison_code, code) - ? true_rtx : false_rtx); + { + if (comparison_dominates_p (ent->comparison_code, code)) + { + if (true_rtx) + return true_rtx; + else + break; + } + else + return false_rtx; + } } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5d65d979ac3..09b19726087 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-09-13 Raksit Ashok + + PR rtl-optimization/37489 + * g++.dg/opt/cse3.C: New. + 2008-09-13 H.J. Lu PR testsuite/37495 diff --git a/gcc/testsuite/g++.dg/opt/cse3.C b/gcc/testsuite/g++.dg/opt/cse3.C new file mode 100644 index 00000000000..a6328071680 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/cse3.C @@ -0,0 +1,48 @@ +// This testcase resulted in invalid code generation on x86_64 targets +// due to a bug in fold_rtx. For a "true" value, fold_rtx represented it +// as const_true_rtx in floating-point mode, if the FLOAT_STORE_FLAG_VALUE +// macro is not defined. + +// { dg-do run } +// { dg-options "-O1 -fno-guess-branch-probability -fcse-follow-jumps -fgcse -frerun-cse-after-loop" } + +class StatVal { + + public: + + StatVal(double ev, double va) + : m(ev), + v(va) {} + + StatVal(const StatVal& other) + : m(other.m), + v(other.v) {} + + StatVal& operator*=(const StatVal& other) { + double A = m == 0 ? 1.0 : v / (m * m); + double B = other.m == 0 ? 1.0 : other.v / (other.m * other.m); + m = m * other.m; + v = m * m * (A + B); + return *this; + } + + double m; + double v; +}; + +extern "C" void abort (void); + +const StatVal two_dot_three(2, 0.3); + +int main(int argc, char **argv) { + + StatVal product3(two_dot_three); + + product3 *= two_dot_three; + + if (product3.v > 2.5) + { + abort(); + } + return 0; +} -- 2.30.2