[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