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%]