On Tue, 17 Jan 2017, Senthil Kumar Selvaraj wrote: > Hi, > > For this (reduced) test case > > > extern int x, y, z; > void foo(void); > void bar(void); > void blah(void); > > void test (void) > { > int flag = 0; > flag = ((x && y) || z); > > if (flag && x && y) { > bar(); > } > } > > I expected gcc -Os (x86_64, if it matters) to generate code equivalent to > > if (x && y) > bar(); > > > Instead, I get > > test(): > mov eax, DWORD PTR x[rip] > test eax, eax > je .L2 > cmp DWORD PTR y[rip], 0 > jne .L3 > .L2: > cmp DWORD PTR z[rip], 0 > je .L1 > test eax, eax > je .L1 > .L3: > cmp DWORD PTR y[rip], 0 > je .L1 > jmp bar() > .L1: > ret > > At -O1 and above though, I get what I expected. At -O3 > test(): > mov edx, DWORD PTR x[rip] > test edx, edx > je .L1 > mov eax, DWORD PTR y[rip] > test eax, eax > je .L1 > jmp bar() > .L1: > rep ret > > > Tracing through the dumps, I see that dom2 is where the gimple starts > diverging. At -O3, dom2 clones the bb that tests z into two copies, and > I guess that enables jump threading and subsequent dse to optimize away the > second (redundant) check for x and y, as also the check for z. At -Os, > dom2 doesn't attemp the bb clone as it thinks it would increase code > size. > > I have two questions. > > 1. Is the analysis right? Is there anything that can be done to fix this? > > 2. If nothing can be done to fix this, is there some pass that can > rewire goto <bb 5> in <bb 3> to goto <bb 6>?
We're missing a pass that does predicate simplification combining both CFG and stmt form. if-combine is supposed to catch some cases, reassoc catches some others. Richard. > Regards > Senthil > > > .dom2 at Os > > > test () > { > int x.1_1; > int y.2_2; > int z.3_3; > int y.5_4; > _Bool _8; > _Bool _9; > _Bool _10; > > <bb 2> [100.00%]: > x.1_1 = x; > if (x.1_1 != 0) > goto <bb 3>; [50.00%] > else > goto <bb 4>; [50.00%] > > <bb 3> [50.00%]: > y.2_2 = y; > if (y.2_2 != 0) > goto <bb 5>; [50.00%] > else > goto <bb 4>; [50.00%] > > <bb 4> [75.00%]: > z.3_3 = z; > _8 = x.1_1 != 0; > _9 = z.3_3 != 0; > _10 = _8 & _9; > if (_10 != 0) > goto <bb 5>; [25.60%] > else > goto <bb 7>; [74.40%] > > <bb 5> [35.37%]: > y.5_4 = y; > if (y.5_4 != 0) > goto <bb 6>; [48.99%] > else > goto <bb 7>; [51.01%] > > <bb 6> [17.33%]: > bar (); > > <bb 7> [100.00%]: > return; > > } > > .dom2 at O3 > > > test () > { > int x.1_1; > int y.2_2; > int z.3_11; > _Bool _12; > _Bool _13; > _Bool _14; > int y.5_15; > int z.3_16; > _Bool _17; > _Bool _18; > _Bool _19; > int y.5_20; > > <bb 2> [100.00%]: > x.1_1 = x; > if (x.1_1 != 0) > goto <bb 3>; [50.00%] > else > goto <bb 5>; [50.00%] > > <bb 3> [50.00%]: > y.2_2 = y; > if (y.2_2 != 0) > goto <bb 8>; [50.00%] > else > goto <bb 7>; [50.00%] > > <bb 4> [100.00%]: > return; > > <bb 5> [50.00%]: > z.3_11 = z; > _12 = x.1_1 != 0; > _13 = z.3_11 != 0; > _14 = _12 & _13; > goto <bb 4>; [100.00%] > > <bb 6> [18.04%]: > y.5_15 = y; > goto <bb 4>; [100.00%] > > <bb 7> [25.00%]: > z.3_16 = z; > _17 = x.1_1 != 0; > _18 = z.3_16 != 0; > _19 = _17 & _18; > if (_19 != 0) > goto <bb 6>; [72.17%] > else > goto <bb 4>; [27.83%] > > <bb 8> [25.00%]: > y.5_20 = y; > bar (); > goto <bb 4>; [100.00%] > > } > > > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)