Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

icc-16.0.3 not respecting no-ansi-alias flag?

Sorav_B_
Beginner
1,094 Views

Compiling a.c with icc -O2 results in reordering of memory accesses, even when -no-ansi-alias flag is used.

We are using icc version 16.0.3

$ cat a.c

#include "stdlib.h"

char *foo(size_t size);

struct list { int hd; struct list * tl; };

struct list * reverselist (struct list * l) {

    struct list * r, * r2;

    for (r = NULL; l != NULL; l = l->tl) {

        r2 = (struct list *)foo(sizeof(struct list));

        r2->hd = l->hd;

        r2->tl = r;

        r = r2;

    }

    return r;

}

$ icc -O2 -m32 -S -falias -no-ansi-alias -fargument-alias a.c

# Showing the compiled assembly for the loop body generated in a.s

..B1.3: # Preds ..B1.2 ..B1.4

addl $4, %esp #9.25

pushl $8 #9.25

# foo(size_t) call foo #9.25

..B1.4: # Preds ..B1.3

movl %edi, 4(%eax) #11.5

movl %eax, %edi #12.5

movl (%esi), %ecx #10.14

movl 4(%esi), %esi #8.33

testl %esi, %esi #8.23

movl %ecx, (%eax) #10.5

jne ..B1.3 # Prob 82% #8.23

The write to r2->hd (instruction 10.5) has been reordered after the read from l->tl (instruction 8.33). Based on the documentation of no-ansi-alias, this should not be possible, as r2->hd could potentially alias with l->tl in the loop body. Are we missing something?

Thanks in advance, for your help.

0 Kudos
6 Replies
TimP
Honored Contributor III
1,094 Views

If those structs are defined local to the compilation unit, it seems the compiler is justified in concluding they can't alias.

0 Kudos
Sorav_B_
Beginner
1,094 Views

Hi Tim,

Thanks for your response.

We are not clear, what you mean by "If those structs are defined local to the compilation unit".  The structure "struct list" is declared in the same compilation unit. But as is evident from a.c, the function 'foo()' and the caller of the function 'reverselist()' are not defined in the same compilation unit.  As far as we know, it is legal for r2->hd and l->tl to alias.

We are a bit stuck due to this issue. FWIW, gcc and clang do not perform this reordering when compiled with -fno-strict-aliasing flag.

Any help on this would be great! Thanks again!

Regards,

Sorav

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,094 Views

Does a memory barrier after "r=r2;" help?

Jim Dempsey

0 Kudos
Sorav_B_
Beginner
1,094 Views

Thanks Jim.  We are, in general, wondering if one could rely on the -no-ansi-alias flag, or not.

0 Kudos
TimP
Honored Contributor III
1,094 Views

I'd be leary of expecting the flag to make wrong code work "in general."  Maybe at -O0, where the compiler probably doesn't undertake any such optimization.

In case you find it relevant, even though the default setting is supposed to differ between linux and Windows, since the linux default was changed, I don't find my Windows builds needing /Qansi-alias. I believe the compiler is finding optimizations which used to depend on asserting standard compliance.

0 Kudos
Yuan_C_Intel
Employee
1,094 Views

Hi, Sorav

The "-no-ansi-alias" flag declares your program does not adhere to the ANSI aliasability rules, which may allows alias between r2->hd and value of pointer l.

I have escalated your issue and recorded this in problem-tracking system. I will let you know when I have an update on this issue.

Thanks.

 

Reply