re PR debug/83157 (gcc.dg/guality/pr41616-1.c fail, inline instances refer to concret...
authorJakub Jelinek <jakub@redhat.com>
Thu, 12 Apr 2018 19:30:00 +0000 (21:30 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 12 Apr 2018 19:30:00 +0000 (21:30 +0200)
PR debug/83157
* var-tracking.c (add_stores): Handle STRICT_LOW_PART SET_DEST.
* cselib.c (cselib_record_sets): For STRICT_LOW_PART dest,
lookup if dest in some wider mode is known to be const0_rtx and
if so, record permanent equivalence for it to be ZERO_EXTEND of
the narrower mode destination.

From-SVN: r259353

gcc/ChangeLog
gcc/cselib.c
gcc/var-tracking.c

index 6890d2a1ad4dace5bb01303f52da28cca6a4d70f..08c25401bb21053d494ba45e765b63b9732f0ec7 100644 (file)
@@ -1,3 +1,12 @@
+2018-04-12  Jakub Jelinek  <jakub@redhat.com>
+
+       PR debug/83157
+       * var-tracking.c (add_stores): Handle STRICT_LOW_PART SET_DEST.
+       * cselib.c (cselib_record_sets): For STRICT_LOW_PART dest,
+       lookup if dest in some wider mode is known to be const0_rtx and
+       if so, record permanent equivalence for it to be ZERO_EXTEND of
+       the narrower mode destination.
+
 2018-04-12  Cesar Philippidis  <cesar@codesourcery.com>
 
        * lto-streamer-out.c (output_function): Revert 259346.
index 586b8cc3a66daa087aec9afb3c881c4af9d80fc1..5a978c1f4b8a8a86a2bd9dbbd5628cd5c5f86b3d 100644 (file)
@@ -2502,6 +2502,7 @@ cselib_record_sets (rtx_insn *insn)
   rtx body = PATTERN (insn);
   rtx cond = 0;
   int n_sets_before_autoinc;
+  int n_strict_low_parts = 0;
   struct cselib_record_autoinc_data data;
 
   body = PATTERN (insn);
@@ -2556,6 +2557,7 @@ cselib_record_sets (rtx_insn *insn)
   for (i = 0; i < n_sets; i++)
     {
       rtx dest = sets[i].dest;
+      rtx orig = dest;
 
       /* A STRICT_LOW_PART can be ignored; we'll record the equivalence for
          the low part after invalidating any knowledge about larger modes.  */
@@ -2581,6 +2583,55 @@ cselib_record_sets (rtx_insn *insn)
          else
            sets[i].dest_addr_elt = 0;
        }
+
+      /* Improve handling of STRICT_LOW_PART if the current value is known
+        to be const0_rtx, then the low bits will be set to dest and higher
+        bits will remain zero.  Used in code like:
+
+        {di:SI=0;clobber flags:CC;}
+        flags:CCNO=cmp(bx:SI,0)
+        strict_low_part(di:QI)=flags:CCNO<=0
+
+        where we can note both that di:QI=flags:CCNO<=0 and
+        also that because di:SI is known to be 0 and strict_low_part(di:QI)
+        preserves the upper bits that di:SI=zero_extend(flags:CCNO<=0).  */
+      scalar_int_mode mode;
+      if (dest != orig
+         && cselib_record_sets_hook
+         && REG_P (dest)
+         && HARD_REGISTER_P (dest)
+         && is_a <scalar_int_mode> (GET_MODE (dest), &mode)
+         && n_sets + n_strict_low_parts < MAX_SETS)
+       {
+         opt_scalar_int_mode wider_mode_iter;
+         FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
+           {
+             scalar_int_mode wider_mode = wider_mode_iter.require ();
+             if (GET_MODE_PRECISION (wider_mode) > BITS_PER_WORD)
+               break;
+
+             rtx reg = gen_lowpart (wider_mode, dest);
+             if (!REG_P (reg))
+               break;
+
+             cselib_val *v = cselib_lookup (reg, wider_mode, 0, VOIDmode);
+             if (!v)
+               continue;
+
+             struct elt_loc_list *l;
+             for (l = v->locs; l; l = l->next)
+               if (l->loc == const0_rtx)
+                 break;
+
+             if (!l)
+               continue;
+
+             sets[n_sets + n_strict_low_parts].dest = reg;
+             sets[n_sets + n_strict_low_parts].src = dest;
+             sets[n_sets + n_strict_low_parts++].src_elt = sets[i].src_elt;
+             break;
+           }
+       }
     }
 
   if (cselib_record_sets_hook)
@@ -2625,6 +2676,20 @@ cselib_record_sets (rtx_insn *insn)
          || (MEM_P (dest) && cselib_record_memory))
        cselib_record_set (dest, sets[i].src_elt, sets[i].dest_addr_elt);
     }
+
+  /* And deal with STRICT_LOW_PART.  */
+  for (i = 0; i < n_strict_low_parts; i++)
+    {
+      if (! PRESERVED_VALUE_P (sets[n_sets + i].src_elt->val_rtx))
+       continue;
+      machine_mode dest_mode = GET_MODE (sets[n_sets + i].dest);
+      cselib_val *v
+       = cselib_lookup (sets[n_sets + i].dest, dest_mode, 1, VOIDmode);
+      cselib_preserve_value (v);
+      rtx r = gen_rtx_ZERO_EXTEND (dest_mode,
+                                  sets[n_sets + i].src_elt->val_rtx);
+      cselib_add_permanent_equiv (v, r, insn);
+    }
 }
 
 /* Return true if INSN in the prologue initializes hard_frame_pointer_rtx.  */
index 56a701c283e87d3636e2130447fd6320a3ffd0e5..2b21da3dfce2b12626859fcc871b2fd762d21b6b 100644 (file)
@@ -5962,7 +5962,9 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
          mo.type = MO_CLOBBER;
          mo.u.loc = loc;
          if (GET_CODE (expr) == SET
-             && SET_DEST (expr) == loc
+             && (SET_DEST (expr) == loc
+                 || (GET_CODE (SET_DEST (expr)) == STRICT_LOW_PART
+                     && XEXP (SET_DEST (expr), 0) == loc))
              && !unsuitable_loc (SET_SRC (expr))
              && find_use_val (loc, mode, cui))
            {