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)

Reply via email to