> > We have wrong code with LTO, too.
> 
> I know.
> 
> > The problem is that IPA passes (and
> > not only that, loop analysis too) does analysis at compile time (with
> > value numbers in) and streams the info separately.
> 
> And that is desirable, because otherwise it simply couldn't derive any
> ranges.
> 
> >  Removal of value ranges
> > (either by LTO or by your patch) happens between computing these
> > summaries and using them, so this can be used to trigger wrong code,
> > sadly.
> 
> Yes.  But with LTO, I don't see how the IPA ICF comparison whether
> two functions are the same or not could be done with the
> SSA_NAME_{RANGE,PTR}_INFO in, otherwise it could only ICF merge functions
> from the same TUs.  So the comparison IMHO (and the assert checks in my
> patch prove that) is done when the SSA_NAME_{RANGE,PTR}_INFO aren't in
> anymore.  So, one just needs to compare and punt or union whatever
> is or could be influenced in the IPA streamed data from the ranges etc.
> And because one has to do it for LTO, doing it for non-LTO should be
> sufficient too.

Sorry, this was bit of a misunderstanding: I tought you still considered
the original patch to be full fix, while I tought I should look into it
more and dig out more issues.  This is bit of can of worms.  Overall I
think the plan is:

This stage4
1) fix VR divergences by either comparing or droping them
2) fix jump function differences by comparing them
   (I just constructed a testcase showing that jump functions can
    diverge for other reasons than just VR, so this is deeper problem,
    too)
3) try to construct aditional wrong code testcases (finite_p
   divergences, trapping)
Next stage1
4) implement VR and PTR info streaming
5) make ICF to compare VRs and punt otherwise
6) implement optimize_size feature to ICF that will not punt on
   diverging TBAA or value ranges and do merging instead.
   We need some extra infrastructure for that, being able to keep the
   maps between basic blocks and SSA names from comparsion stage to
   merging stage
7) measure how effective ICF becomes in optimize_size mode and implement
   heuristics on how much metadata merging we want to do with -O2/-O3 as
   well.
   Based on older data Martin collected for his thesis, ICF used to be
   must more effective on libreoffice then it is today, so hopefully we
   can recover 10-15% binary size improvmeents here.
8) General ICF TLC.  There are many half finished things for a while in
   this pass (such as merging with different BB or stmt orders).

I am attaching the compare patch which also fixes the original wrong
code. If you preffer your version, just go ahead to commit it. Otherwise
I will add your testcase for this patch and commit this one.
Statistically we almost never merge functions with different value
ranges (three in testsuite, 0 during bootstrap, 1 during LTO bootstrap
and probably few in LLVM build - there are 15 cases reported, but some
are false positives caused by hash function conflicts).

Honza

gcc/ChangeLog:

        * ipa-icf-gimple.cc (func_checker::compare_ssa_name): Compare value 
ranges.

diff --git a/gcc/ipa-icf-gimple.cc b/gcc/ipa-icf-gimple.cc
index 8c2df7a354e..37c416d777d 100644
--- a/gcc/ipa-icf-gimple.cc
+++ b/gcc/ipa-icf-gimple.cc
@@ -39,9 +39,11 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfgloop.h"
 #include "attribs.h"
 #include "gimple-walk.h"
+#include "value-query.h"
+#include "value-range-storage.h"
 
 #include "tree-ssa-alias-compare.h"
 #include "ipa-icf-gimple.h"
 
 namespace ipa_icf_gimple {
 
@@ -109,6 +116,35 @@ func_checker::compare_ssa_name (const_tree t1, const_tree 
t2)
   else if (m_target_ssa_names[i2] != (int) i1)
     return false;
 
+  if (POINTER_TYPE_P (TREE_TYPE (t1)))
+    {
+      if (SSA_NAME_PTR_INFO (t1))
+       {
+         if (!SSA_NAME_PTR_INFO (t2)
+             || SSA_NAME_PTR_INFO (t1)->align != SSA_NAME_PTR_INFO (t2)->align
+             || SSA_NAME_PTR_INFO (t1)->misalign != SSA_NAME_PTR_INFO 
(t2)->misalign)
+           return false;
+       }
+      else if (SSA_NAME_PTR_INFO (t2))
+       return false;
+    }
+  else
+    {
+      if (SSA_NAME_RANGE_INFO (t1))
+       {
+         if (!SSA_NAME_RANGE_INFO (t2))
+           return false;
+         Value_Range r1 (TREE_TYPE (t1));
+         Value_Range r2 (TREE_TYPE (t2));
+         SSA_NAME_RANGE_INFO (t1)->get_vrange (r1, TREE_TYPE (t1));
+         SSA_NAME_RANGE_INFO (t2)->get_vrange (r2, TREE_TYPE (t2));
+         if (r1 != r2)
+           return false;
+       }
+      else if (SSA_NAME_RANGE_INFO (t2))
+       return false;
+    }
+
   if (SSA_NAME_IS_DEFAULT_DEF (t1))
     {
       tree b1 = SSA_NAME_VAR (t1);

Reply via email to