[llvm-dev] Comparing Clang and GCC: only clang stores updated value in each iteration.

Philip Reames via llvm-dev llvm-dev at lists.llvm.org
Thu Sep 20 16:38:24 PDT 2018



On 09/20/2018 06:52 AM, Jonas Paulsson via llvm-dev wrote:
> Hi,
>
> I have a benchmark (mcf) that is currently slower when compiled with 
> clang compared to gcc 8 (~10%). It seems that a hot loop has a few 
> differences, where one interesting one is that while clang stores an 
> incremented value in each iteration, gcc waits and just stores the 
> final value just once after the loop. The value is a global variable.
>
> I wonder if this is something clang does not do per default but can be 
> activated, similarly to the fp-contract situation?
>
> If not, is this a deficiency in clang? What pass should handle this? 
> IndVarSimplify?
>
> I have made a reduced test case which shows the same difference 
> between the compilers: clang adds 1 and stores it back to 'a' in each 
> iteration, while gcc instead figures out the value a has after the 
> loop (0) and stores it then once to 'a'.
>
> /Jonas
>
>
> int a = 1;
> void b() {
>   do
>     if (a)
>       a++;
>   while (a != 0);
> }
I think your example may be a bit over reduced.  Unless I'm misreading 
this, a starts at 1, is incremented one each iteration, and then is 
tested against zero.  The only way this loop can exit is if a has 
wrapped around and C++ states that signed integers are assumed to not 
overflow.  We can/should be replacing the whole loop with an unreachable.

Do we still fail to optimize if either a) you use an unsigned which has 
defined overflow or b) you use a non-zero exit test?  That is, change 
the example to something like:
int a = 1;
void b() {
   do
     if (a)
       a++;
   while (a != 500);
}

If so, then yes, this is probably a case where the aggressive LoopPRE 
mentioned in the other thread that Eli linked to would be useful.  Once 
we'd done the PRE, then everything else should collapse.

>
> bin/clang -O3 -march=z13 -mllvm -unroll-count=1
>
>         .text
>         .file   "testfun.i"
>         .globl  b                       # -- Begin function b
>         .p2align        4
>         .type   b, at function
> b:                                      # @b
> # %bb.0:                                # %entry
>         lrl     %r0, a
> .LBB0_1:                                # %do.body
>                                         # =>This Inner Loop Header: 
> Depth=1
>         cije    %r0, 0, .LBB0_3
> # %bb.2:                                # %if.then
>                                         #   in Loop: Header=BB0_1 Depth=1
>         ahi     %r0, 1
>         strl    %r0, a
> .LBB0_3:                                # %do.cond
>                                         #   in Loop: Header=BB0_1 Depth=1
>         cijlh   %r0, 0, .LBB0_1
> # %bb.4:                                # %do.end
>         br      %r14
> .Lfunc_end0:
>         .size   b, .Lfunc_end0-b
>                                         # -- End function
>         .type   a, at object               # @a
>         .data
>         .globl  a
>         .p2align        2
> a:
>         .long   1                       # 0x1
>         .size   a, 4
>
>
> gcc -O3 -march=z13:
>
>         .file   "testfun.i"
>         .machinemode zarch
>         .machine "z13"
> .text
>         .align  8
> .globl b
>         .type   b, @function
> b:
> .LFB0:
>         .cfi_startproc
>         larl    %r1,a
>         lt      %r1,0(%r1)
>         je      .L1
>         larl    %r1,a
>         mvhi    0(%r1),0
> .L1:
>         br      %r14
>         .cfi_endproc
> .LFE0:
>         .size   b, .-b
> .globl a
> .data
>         .align  4
>         .type   a, @object
>         .size   a, 4
> a:
>         .long   1
>         .ident  "GCC: (GNU) 8.0.1 20180324 (Red Hat 8.0.1-0.20)"
>         .section        .note.GNU-stack,"", at progbits
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev



More information about the llvm-dev mailing list