[Bug rtl-optimization/70222] Test miscompiled with -O1

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Mar 15 09:40:00 GMT 2016


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70222

--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The #c6 patch bootstrapped/regtested fine on x86_64-linux and i686-linux.  I've
additionally gathered statistics using:
--- gcc/combine.c.jj    2016-03-14 14:00:24.000000000 +0100
+++ gcc/combine.c       2016-03-14 18:05:47.401401665 +0100
@@ -10838,6 +10838,19 @@ simplify_shift_const_1 (enum rtx_code co
      turn off all the bits that the shift would have turned off.
      Similarly do this if if we've optimized varop so that we don't perform
      any shift.  */
+if (orig_code == LSHIFTRT && (mode != result_mode || result_mode !=
shift_mode)
+&& ((orig_varop != varop && !rtx_equal_p (orig_varop, varop)) || orig_count !=
count || result_mode != shift_mode))
+{
+FILE *f = fopen ("/tmp/shifts", "a");
+fprintf (f, "@@@ %d %s %s %s %s %s %s %d %d\n--- ", (int) BITS_PER_WORD,
main_input_filename ? main_input_filename : "-",
+current_function_name (), GET_RTX_NAME (code), GET_MODE_NAME (result_mode),
GET_MODE_NAME (mode), GET_MODE_NAME (shift_mode),
+orig_count, count);
+print_inline_rtx (f, orig_varop, 0);
+fprintf (f, "\n+++ ");
+print_inline_rtx (f, varop, 0);
+fprintf (f, "\n");
+fclose (f);
+}
   if (orig_code == LSHIFTRT
       && (result_mode != shift_mode
          || (result_mode != mode && count == 0)))
across the two bootstraps/regtests.  Out of 25808 records, the most common last
5 columns are (first number is from sort | uniq -c | sort -n, then code,
result_mode, mode, shift_mode, orig_count, count):
    112 QI SI SI 1 1
    131 SI DI DI 8 8
    170 QI HI HI 3 3
    182 QI HI HI 1 1
    189 HI DI DI 8 0
    196 QI HI HI 4 4
    200 HI SI SI 3 3
    204 HI SI HI 8 8
    216 HI SI SI 4 4
    234 QI SI SI 7 7
    250 SI DI DI 15 15
    479 HI SI SI 8 8
    599 SI DI DI 24 16
    755 SI DI DI 16 0
    816 HI SI SI 15 0
   1372 HI SI SI 2 2
   1673 HI SI SI 1 1
   2509 SI DI DI 24 0
   2743 SI DI SI 24 24
   2839 SI DI DI 24 24
   8238 HI SI SI 8 0

In addition, those where orig_count != count && count != 0 are (the 599 line
above and):
      2 HI SI SI 12 3
      2 SI DI DI 21 20
      3 SI DI SI 30 31
      4 HI DI DI 15 1
      4 SI DI DI 24 8
      4 SI DI DI 28 16
      4 SI DI DI 29 2
      4 SI DI DI 3 1
      4 SI DI DI 31 7
      5 SI DI DI 16 8
      7 HI SI SI 5 3
      7 HI SI SI 6 2
      9 HI SI SI 12 6
      9 HI SI SI 12 9
      9 SI DI DI 27 3
     10 SI DI SI 28 31
     12 SI DI SI 24 16
     15 HI DI DI 14 2
     15 HI DI DI 14 4
     18 HI SI SI 11 8
     34 HI SI SI 8 2
     34 HI SI SI 8 3
     35 SI DI SI 21 31
     48 HI SI SI 15 8
     91 HI SI SI 8 1

If (shift_mode != result_mode), combine.c used to do the masking already
previously, so for us it is interesting only if shift_mode == result_mode (and
mode != result_mode).
Those are:
      3 HI DI HI 15 15
      3 SI DI SI 30 31
      8 HI DI HI 8 8
     10 SI DI SI 28 31
     12 SI DI SI 24 16
     15 SI DI SI 31 31
     17 QI SI QI 7 7
     24 QI DI QI 2 2
     26 SI DI SI 6 6
     32 HI SI HI 15 15
     35 SI DI SI 21 31
     48 QI SI QI 2 2
     57 SI DI SI 31 0
    204 HI SI HI 8 8
   2743 SI DI SI 24 24
If the count is non-zero, then we've supposedly only changed the varop, but are
shifting in the narrower mode anyway (will look at one or two examples just to
be sure), so the interesting cases are:
     57 SI DI SI 31 0
(this pr70222.c testcase (45 times, plus some LTO unidentifiable ones, bet this
testcase with -flto)), and also interesting are ones where the shift count is
different:
      3 SI DI SI 30 31
     10 SI DI SI 28 31
     12 SI DI SI 24 16
     35 SI DI SI 21 31
Will look at those now.


More information about the Gcc-bugs mailing list