Richard,
This patch fixes the problem I described earlier about min/max generation
propagating incorrect range information
(https://gcc.gnu.org/ml/gcc/2015-08/msg00024.html).
I went with creating a new name, if the PHI being modified has more than 2
edges. I also modified the testcase that my min/max vrp patch tickled -- it
wasn't calling an init function and hence copying zeroes rather than the small
values it thought it was copying. Also added a new test to convert zeroes,
which was the failure mode I observed in the DFP lib.
This patch was tested in combination with the new min max optimization I'll
post momentarily.
ok?
nathan
2015-08-10 Nathan Sidwell <nat...@acm.org>
* tree-ssa-phiopt.c (minmax_replacement): Create new ssa name if
we're not the only contributor to target phi.
testsuite/
* c-c++-common/dfp/operator-comma.c: Call init function.
* c-c++-common/dfp/convert-dfp-2.c: New test.
Index: tree-ssa-phiopt.c
===================================================================
--- tree-ssa-phiopt.c (revision 226749)
+++ tree-ssa-phiopt.c (working copy)
@@ -1277,8 +1277,16 @@ minmax_replacement (basic_block cond_bb,
gsi_move_before (&gsi_from, &gsi);
}
+ /* Create an SSA var to hold the min/max result. If we're the only
+ things setting the target PHI, then we can clone the PHI
+ variable. Otherwise we must create a new one. */
+ result = PHI_RESULT (phi);
+ if (EDGE_COUNT (gimple_bb (phi)->preds) == 2)
+ result = duplicate_ssa_name (result, NULL);
+ else
+ result = make_ssa_name (TREE_TYPE (result));
+
/* Emit the statement to compute min/max. */
- result = duplicate_ssa_name (PHI_RESULT (phi), NULL);
new_stmt = gimple_build_assign (result, minmax, arg0, arg1);
gsi = gsi_last_bb (cond_bb);
gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
Index: testsuite/c-c++-common/dfp/convert-dfp-2.c
===================================================================
--- testsuite/c-c++-common/dfp/convert-dfp-2.c (revision 0)
+++ testsuite/c-c++-common/dfp/convert-dfp-2.c (working copy)
@@ -0,0 +1,45 @@
+/* { dg-options "-O0" } */
+
+/* Test decimal fp conversions of zero. */
+
+#include "dfp-dbg.h"
+
+volatile _Decimal32 d32a, d32c;
+volatile _Decimal64 d64a, d64c;
+volatile _Decimal128 d128a, d128c;
+
+int
+main ()
+{
+ d32a = d32c;
+ if (d32a)
+ FAILURE
+ d32a = d64c;
+ if (d32a)
+ FAILURE
+ d32a = d128c;
+ if (d32a)
+ FAILURE
+
+ d64a = d32c;
+ if (d64a)
+ FAILURE
+ d64a = d64c;
+ if (d64a)
+ FAILURE
+ d64a = d128c;
+ if (d64a)
+ FAILURE
+
+ d128a = d32c;
+ if (d128a)
+ FAILURE
+ d128a = d64c;
+ if (d128a)
+ FAILURE
+ d128a = d128c;
+ if (d128a)
+ FAILURE
+
+ FINISH
+}
Index: testsuite/c-c++-common/dfp/operator-comma.c
===================================================================
--- testsuite/c-c++-common/dfp/operator-comma.c (revision 226749)
+++ testsuite/c-c++-common/dfp/operator-comma.c (working copy)
@@ -24,6 +24,8 @@ init ()
int
main ()
{
+ init ();
+
d32a = (d32b, d32c);
if (d32a != d32c)
FAILURE