- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If those structs are defined local to the compilation unit, it seems the compiler is justified in concluding they can't alias.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Does a memory barrier after "r=r2;" help?
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Jim. We are, in general, wondering if one could rely on the -no-ansi-alias flag, or not.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page