public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-9328] dwarf2out: Fix up CONST_WIDE_INT handling once more [PR103046]
@ 2021-11-29  8:49 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2021-11-29  8:49 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:41db2576afc4f3bf993778ad80529f2bf4ddd6cf

commit r11-9328-g41db2576afc4f3bf993778ad80529f2bf4ddd6cf
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Fri Nov 5 10:20:10 2021 +0100

    dwarf2out: Fix up CONST_WIDE_INT handling once more [PR103046]
    
    My last change to CONST_WIDE_INT handling in add_const_value_attribute broke
    handling of CONST_WIDE_INT constants like ((__uint128_t) 1 << 120).
    wi::min_precision (w1, UNSIGNED) in that case 121, but wide_int::from
    creates a wide_int that has 0 and 0xff00000000000000ULL in its elts and
    precision 121.  When we output that, we output both elements and thus emit
    0, 0xff00000000000000 instead of the desired 0, 0x0100000000000000.
    
    IMHO we should actually pass machine_mode to add_const_value_attribute from
    callers, so that we know exactly what precision we want.  Because
    hypothetically, if say mode is OImode and the CONST_WIDE_INT value fits into
    128 bits or 192 bits, we'd emit just those 128 or 192 bits but debug info
    users would expect 256 bits.
    
    On
    typedef unsigned __int128 U;
    
    int
    main ()
    {
      U a = (U) 1 << 120;
      U b = 0xffffffffffffffffULL;
      U c = ((U) 0xffffffff00000000ULL) << 64;
      return 0;
    }
    vanilla gcc incorrectly emits 0, 0xff00000000000000 for a,
    0xffffffffffffffff alone (DW_FORM_data8) for b and 0, 0xffffffff00000000
    for c.  gcc with the previously posted PR103046 patch emits
    0, 0x0100000000000000 for a, 0xffffffffffffffff alone for b and
    0, 0xffffffff00000000 for c.  And with this patch we emit
    0, 0x0100000000000000 for a, 0xffffffffffffffff, 0 for b and
    0, 0xffffffff00000000 for c.
    So, the patch below certainly causes larger debug info (well, 128-bit
    integers are pretty rare), but in this case the question is if it isn't
    more correct, as debug info consumers generally will not know if they
    should sign or zero extend the value in DW_AT_const_value.
    The previous code assumes they will always zero extend it...
    
    2021-11-05  Jakub Jelinek  <jakub@redhat.com>
    
            PR debug/103046
            * dwarf2out.c (add_const_value_attribute): Add MODE argument, use it
            in CONST_WIDE_INT handling.  Adjust recursive calls.
            (add_location_or_const_value_attribute): Pass DECL_MODE (decl) to
            new add_const_value_attribute argument.
            (tree_add_const_value_attribute): Pass TYPE_MODE (type) to new
            add_const_value_attribute argument.
    
    (cherry picked from commit 155f6b2be421b0f84e478e34fbf72ee0bb9e36bc)

Diff:
---
 gcc/dwarf2out.c | 32 +++++++++++++++++---------------
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 7296cdb52fb..ae25eaccf70 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -3828,7 +3828,7 @@ static void add_AT_location_description	(dw_die_ref, enum dwarf_attribute,
 					 dw_loc_list_ref);
 static void add_data_member_location_attribute (dw_die_ref, tree,
 						struct vlr_context *);
-static bool add_const_value_attribute (dw_die_ref, rtx);
+static bool add_const_value_attribute (dw_die_ref, machine_mode, rtx);
 static void insert_int (HOST_WIDE_INT, unsigned, unsigned char *);
 static void insert_wide_int (const wide_int &, unsigned char *, int);
 static unsigned insert_float (const_rtx, unsigned char *);
@@ -19875,8 +19875,10 @@ insert_float (const_rtx rtl, unsigned char *array)
    constants do not necessarily get memory "homes".  */
 
 static bool
-add_const_value_attribute (dw_die_ref die, rtx rtl)
+add_const_value_attribute (dw_die_ref die, machine_mode mode, rtx rtl)
 {
+  scalar_mode int_mode;
+
   switch (GET_CODE (rtl))
     {
     case CONST_INT:
@@ -19891,15 +19893,15 @@ add_const_value_attribute (dw_die_ref die, rtx rtl)
       return true;
 
     case CONST_WIDE_INT:
-      {
-	wide_int w1 = rtx_mode_t (rtl, MAX_MODE_INT);
-	unsigned int prec = MIN (wi::min_precision (w1, UNSIGNED),
-				 (unsigned int) CONST_WIDE_INT_NUNITS (rtl)
-				 * HOST_BITS_PER_WIDE_INT);
-	wide_int w = wide_int::from (w1, prec, UNSIGNED);
-	add_AT_wide (die, DW_AT_const_value, w);
-      }
-      return true;
+      if (is_int_mode (mode, &int_mode)
+	  && (GET_MODE_PRECISION (int_mode)
+	      & (HOST_BITS_PER_WIDE_INT - 1)) == 0)
+	{
+	  wide_int w = rtx_mode_t (rtl, int_mode);
+	  add_AT_wide (die, DW_AT_const_value, w);
+	  return true;
+	}
+      return false;
 
     case CONST_DOUBLE:
       /* Note that a CONST_DOUBLE rtx could represent either an integer or a
@@ -19984,7 +19986,7 @@ add_const_value_attribute (dw_die_ref die, rtx rtl)
 
     case CONST:
       if (CONSTANT_P (XEXP (rtl, 0)))
-	return add_const_value_attribute (die, XEXP (rtl, 0));
+	return add_const_value_attribute (die, mode, XEXP (rtl, 0));
       /* FALLTHROUGH */
     case SYMBOL_REF:
       if (!const_ok_for_output (rtl))
@@ -20497,7 +20499,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, bool cache_p)
 
   rtl = rtl_for_decl_location (decl);
   if (rtl && (CONSTANT_P (rtl) || GET_CODE (rtl) == CONST_STRING)
-      && add_const_value_attribute (die, rtl))
+      && add_const_value_attribute (die, DECL_MODE (decl), rtl))
     return true;
 
   /* See if we have single element location list that is equivalent to
@@ -20518,7 +20520,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, bool cache_p)
       if (GET_CODE (rtl) == EXPR_LIST)
 	rtl = XEXP (rtl, 0);
       if ((CONSTANT_P (rtl) || GET_CODE (rtl) == CONST_STRING)
-	  && add_const_value_attribute (die, rtl))
+	  && add_const_value_attribute (die, DECL_MODE (decl), rtl))
 	 return true;
     }
   /* If this decl is from BLOCK_NONLOCALIZED_VARS, we might need its
@@ -20593,7 +20595,7 @@ tree_add_const_value_attribute (dw_die_ref die, tree t)
      symbols.  */
   rtl = rtl_for_decl_init (init, type);
   if (rtl && !early_dwarf)
-    return add_const_value_attribute (die, rtl);
+    return add_const_value_attribute (die, TYPE_MODE (type), rtl);
   /* If the host and target are sane, try harder.  */
   if (CHAR_BIT == 8 && BITS_PER_UNIT == 8
       && initializer_constant_valid_p (init, type))


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-11-29  8:49 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-29  8:49 [gcc r11-9328] dwarf2out: Fix up CONST_WIDE_INT handling once more [PR103046] Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).