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 <[email protected]>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB
21284 (AG Nuernberg)