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

            Bug ID: 80153
           Summary: ivopt generate wrong code
           Product: gcc
           Version: 7.0.1
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: npickito at gmail dot com
                CC: amker.cheng at gmail dot com, andrew at sifive dot com,
                    palmer at dabbelt dot com
  Target Milestone: ---
            Target: riscv32-unknown-elf

Created attachment 41021
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41021&action=edit
test.c

GCC configure: --target=riscv32-elf

What's happen:

IVOPT seen optimize induction variable into wrong thins and then make program
became a infinite loop. 

How to reproduce:

riscv32-elf-gcc test.c -Os


Before ivopt (test.c.161t.cunroll):

main ()
{
  int c;
  int i;
  unsigned int ivtmp_1;
  char _2;
  const char * _4;
  char _5;
  int _6;
  _Bool _7;
  int _8;
  unsigned int ivtmp_9;
  unsigned int i.13_11;

  <bb 2> [15.00%]:
  _fputs ("oops!\n");
  goto <bb 4>; [100.00%]

  <bb 3> [85.00%]:
  _2 = _fgetc ();
  c_17 = (int) _2;
  _4 = "oops!\n" + i.13_11;
  _5 = *_4;
  _6 = (int) _5;
  _7 = _2 == _5;
  _8 = (int) _7;
  check (c_17, _6, _8);
  i_19 = i_12 + 1;

  <bb 4> [100.00%]:
  # i_12 = PHI <0(2), i_19(3)>
  # ivtmp_9 = PHI <7(2), ivtmp_1(3)>
  i.13_11 = (unsigned int) i_12;
  ivtmp_1 = ivtmp_9 - 1;
  if (ivtmp_1 != 0)
    goto <bb 3>; [85.00%]
  else
    goto <bb 5>; [15.00%]

  <bb 5> [15.00%]:
  return 0;

}

After ivopt (test.c.164t.ivopts):

main ()
{
...
  <bb 3> [85.00%]:
  _2 = _fgetc ();
  c_17 = (int) _2;
  _24 = (void *) ivtmp.37_10;
  _5 = MEM[base: _24, offset: 0B];
  _6 = (int) _5;
  _7 = _2 == _5;
  _8 = (int) _7;
  check (c_17, _6, _8);
  ivtmp.37_3 = ivtmp.37_10 + 1;

  <bb 4> [100.00%]:
  # ivtmp.37_10 = PHI <ivtmp.37_20(2), ivtmp.37_3(3)>
  _21 = 6 - ivtmp.37_10;
  _22 = "oops!\n" + _21;    ***** IVOPT optimize i to to this
  _23 = (unsigned int) _22; ***** and just cast pointer to unsigned int
  if (_23 != 0)             ***** and compare to 0
    goto <bb 3>; [85.00%]
  else
    goto <bb 5>; [15.00%]

  <bb 5> [15.00%]:
  return 0;

}

And then forwprop optimize to infinite loop (test.c.185t.forwprop4):
...
;; Function main (main, funcdef_no=3, decl_uid=1434, cgraph_uid=3,
symbol_order=7) (executed once)

  Replaced '_22 != 0B' with '1'
Removing basic block 5
Merging blocks 4 and 3
main ()
...
  <bb 3> [100.00%]:
  # ivtmp.37_10 = PHI <ivtmp.37_20(2), ivtmp.37_3(3)>
  _21 = 6 - ivtmp.37_10;
  _22 = "oops!\n" + _21;
  _23 = (unsigned int) _22;
  _2 = _fgetc ();
  c_17 = (int) _2;
  _24 = (void *) ivtmp.37_10;
  _5 = MEM[base: _24, offset: 0B];
  _6 = (int) _5;
  _7 = _2 == _5;
  _8 = (int) _7;
  check (c_17, _6, _8);
  ivtmp.37_3 = ivtmp.37_10 + 1;
  goto <bb 3>; [100.00%]

Reply via email to