https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61409
--- Comment #14 from Manuel López-Ibáñez <manu at gcc dot gnu.org> ---
And even simpler testcase:
void *init(void);
struct window
{
int line_height;
int pixel_width;
int pixel_height;
int column_width;
int text_cols;
int internal_border_width;
int left_fringe_width, right_fringe_width;
} *rw;
void bar() __attribute__((noreturn));
void f(int i, int j) {
void *ptr;
if (i)
{
if (j)
return; /* bar(); */
ptr = init();
}
rw->pixel_width = ((rw->text_cols * (rw->column_width))
+ (rw->left_fringe_width + (rw->right_fringe_width)) + 2
* (rw->internal_border_width));
rw->pixel_height = ((rw->text_cols * (rw->line_height)));
if (i)
{
rw=ptr;
}
}
And the dump:
f (intD.6 iD.1843, intD.6 jD.1844)
{
voidD.41 * ptrD.1847;
struct window * rw.0_10;
intD.6 _11;
intD.6 _12;
intD.6 _13;
intD.6 _14;
intD.6 _15;
intD.6 _16;
intD.6 _17;
intD.6 _18;
intD.6 _19;
intD.6 _20;
intD.6 _22;
intD.6 _23;
;; basic block 2, loop depth 0, count 0, freq 10000, maybe hot
;; prev block 0, next block 9, flags: (NEW, REACHABLE)
;; pred: ENTRY [100.0%] (FALLTHRU,EXECUTABLE)
;; starting at line 17
[test.c:17:8] if (i_4(D) != 0)
goto <bb 3>;
else
goto <bb 9>;
;; succ: 3 [50.0%] (TRUE_VALUE,EXECUTABLE)
;; 9 [50.0%] (FALSE_VALUE,EXECUTABLE)
;; basic block 9, loop depth 0, count 0, freq 5000, maybe hot
;; prev block 2, next block 3, flags: (NEW)
;; pred: 2 [50.0%] (FALSE_VALUE,EXECUTABLE)
;;
goto <bb 6>;
;; succ: 6 [100.0%] (FALLTHRU)
;; basic block 3, loop depth 0, count 0, freq 5000, maybe hot
;; prev block 9, next block 10, flags: (NEW, REACHABLE)
;; pred: 2 [50.0%] (TRUE_VALUE,EXECUTABLE)
;; starting at line 19
[test.c:19:5] if (j_7(D) != 0)
goto <bb 10>;
else
goto <bb 5>;
;; succ: 10 [61.0%] (TRUE_VALUE,EXECUTABLE)
;; 5 [39.0%] (FALSE_VALUE,EXECUTABLE)
;; basic block 10, loop depth 0, count 0, freq 3051, maybe hot
;; prev block 3, next block 4, flags: (NEW)
;; pred: 3 [61.0%] (TRUE_VALUE,EXECUTABLE)
;;
;; succ: 4 [100.0%] (FALLTHRU)
;; basic block 4, loop depth 0, count 0, freq 5761, maybe hot
;; prev block 10, next block 5, flags: (NEW)
;; pred: 10 [100.0%] (FALLTHRU)
;; 11 [100.0%] (FALLTHRU)
;;
# .MEM_47 = PHI <.MEM_6(D)(10), .MEM_24(11)>
goto <bb 8>;
;; succ: 8 [100.0%] (FALLTHRU,EXECUTABLE)
;; basic block 5, loop depth 0, count 0, freq 1949, maybe hot
;; prev block 4, next block 6, flags: (NEW, REACHABLE)
;; pred: 3 [39.0%] (FALSE_VALUE,EXECUTABLE)
;; starting at line 21
[test.c:21:6] # .MEM_8 = VDEF <.MEM_6(D)>
# PT = nonlocal escaped
# USE = nonlocal
# CLB = nonlocal
ptr_9 = initD.1831 ();
;; succ: 6 [100.0%] (FALLTHRU,EXECUTABLE)
;; basic block 6, loop depth 0, count 0, freq 6949, maybe hot
;; prev block 5, next block 11, flags: (NEW, REACHABLE)
;; pred: 9 [100.0%] (FALLTHRU)
;; 5 [100.0%] (FALLTHRU,EXECUTABLE)
;; starting at line 23
# PT = nonlocal escaped
# ptr_1 = PHI <ptr_5(D)(9), [test.c:21:6] ptr_9(5)>
# .MEM_2 = PHI <.MEM_6(D)(9), .MEM_8(5)>
[test.c:23:27] # VUSE <.MEM_2>
# PT = nonlocal escaped
rw.0_10 = rwD.1841;
[test.c:23:27] # VUSE <.MEM_2>
_11 = [test.c:23:27] rw.0_10->text_colsD.1837;
[test.c:23:44] # VUSE <.MEM_2>
_12 = [test.c:23:44] rw.0_10->column_widthD.1836;
[test.c:23:39] _13 = _11 * _12;
[test.c:24:15] # VUSE <.MEM_2>
_14 = [test.c:24:15] rw.0_10->left_fringe_widthD.1839;
[test.c:24:40] # VUSE <.MEM_2>
_15 = [test.c:24:40] rw.0_10->right_fringe_widthD.1840;
[test.c:24:35] _16 = _14 + _15;
[test.c:24:10] _17 = _13 + _16;
[test.c:24:72] # VUSE <.MEM_2>
_18 = [test.c:24:72] rw.0_10->internal_border_widthD.1838;
[test.c:24:67] # RANGE [-2147483648, 2147483647] NONZERO 4294967294
_19 = _18 * 2;
[test.c:24:63] _20 = _17 + _19;
[test.c:23:21] # .MEM_21 = VDEF <.MEM_2>
[test.c:23:7] rw.0_10->pixel_widthD.1834 = _20;
[test.c:25:43] # VUSE <.MEM_21>
_22 = [test.c:25:43] rw.0_10->line_heightD.1833;
[test.c:25:38] _23 = _11 * _22;
[test.c:25:20] # .MEM_24 = VDEF <.MEM_21>
[test.c:25:5] rw.0_10->pixel_heightD.1835 = _23;
[test.c:26:6] if (i_4(D) != 0)
goto <bb 7>;
else
goto <bb 11>;
;; succ: 7 [61.0%] (TRUE_VALUE,EXECUTABLE)
;; 11 [39.0%] (FALSE_VALUE,EXECUTABLE)
;; basic block 11, loop depth 0, count 0, freq 2710, maybe hot
;; prev block 6, next block 7, flags: (NEW)
;; pred: 6 [39.0%] (FALSE_VALUE,EXECUTABLE)
;;
goto <bb 4>;
;; succ: 4 [100.0%] (FALLTHRU)
;; basic block 7, loop depth 0, count 0, freq 4239, maybe hot
;; prev block 11, next block 8, flags: (NEW, REACHABLE)
;; pred: 6 [61.0%] (TRUE_VALUE,EXECUTABLE)
;; starting at line 28
[test.c:28:9] # .MEM_25 = VDEF <.MEM_24>
rwD.1841 = ptr_1;
;; succ: 8 [100.0%] (FALLTHRU,EXECUTABLE)
;; basic block 8, loop depth 0, count 0, freq 10000, maybe hot
;; prev block 7, next block 1, flags: (NEW, REACHABLE)
;; pred: 4 [100.0%] (FALLTHRU,EXECUTABLE)
;; 7 [100.0%] (FALLTHRU,EXECUTABLE)
;; starting at line -1, discriminator 1
# .MEM_3 = PHI <.MEM_47(4), .MEM_25(7)>
# VUSE <.MEM_3>
return;
;; succ: EXIT [100.0%]
}
I don't really understand how the uninit pass computes the predicates, but when
replacing the "return" with "bar()", it is able to see that "j != 0" is not
part of the predicate guarding the def of ptr. Thus, somehow the analysis that
works for a noreturn function fails for a normal return.