<div dir="ltr"><div><div><div>Hi Kevin,<br><br></div>your C program invokes undefined behavior when it dereferences pointers that have been converted to other types. See for example <a href="http://stackoverflow.com/questions/4810417/c-when-is-casting-between-pointer-types-not-undefined-behavior" target="_blank">http://stackoverflow.com/questions/4810417/c-when-is-casting-between-pointer-types-not-undefined-behavior</a><br>
<br></div>Because of this, the program could do anything... in particular, you can expect the output of different compilers to be different.<br><br>Cheers,<br></div>Jonas<br><div class="gmail_extra"><br><br><div class="gmail_quote">
On Thu, Jul 31, 2014 at 8:38 AM, Kevin Qin <span dir="ltr"><<a href="mailto:kevinqindev@gmail.com" target="_blank">kevinqindev@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">Hi all,<div><br></div><div>Recently, I found gcc can generate faster codes by localizing global variable inside loop and only write back once before function return. Gcc can do this because its alias analysis think it's safe. But for below case, gcc gives different result from -O0 and -O2.</div>
<div><br></div><div><div>#include <stdio.h></div><div>struct heap {int index; int b;};</div><div>struct heap **ptr;</div><div>int aa;</div><div><br></div><div>int main() {</div><div> struct heap element;<br></div>
<div>
struct heap *array[2];</div><div> array[0] = (struct heap *)&aa;</div><div> array[1] = &element;</div><div> ptr = array;</div><div> aa = 1;</div><div> int i;</div><div> for (i =0; i< 2; i++) {</div><div>
printf("i is %d, aa is %d\n", i, aa);</div><div> ptr[i]->index = 0;</div><div> }</div><div> return 0;</div><div>}</div></div><div><br></div><div>$gcc test.c -O0<br></div><div>$./a.out</div><div><div>
i is 0, aa is 1</div><div>i is 1, aa is 0</div></div><div><br></div><div><div>$gcc test.c -O2<br></div><div>$./a.out</div><div><div>i is 0, aa is 1</div><div>i is 1, aa is 1</div></div></div><div><br></div><div>The version of gcc I tried this is 4.8.2 (Ubuntu 4.8.2-19ubuntu1).</div>
<div><br></div><div>On Clang side, it always give the expected result(as the result of gcc -O0) no matter with the optimization level. But it also lose the opportunity to localize variable aa and introduced extra load instruction inside loop because LLVM alias analysis think aa are not independent with the value ptr point to.</div>
<div><br></div><div>Then my question is,</div><div><br></div><div>1. Is this C program legal or not? Especially the type conversion between int pointer and struct pointer. But at least there's no warning or error posted during compiling time on both Clang and gcc side.</div>
<div><br></div><div>2. What we should do in LLVM side? LLVM gives correct result on this corner case no matter it's legal or not, but <span style="color:rgb(50,50,50);font-family:Arial,宋体,微软雅黑;font-size:14px;line-height:16px;white-space:nowrap">sacrifices performance on most generic cases. Did this need a improvement?</span></div>
<span><font color="#888888">
<div><br></div><div><br></div><div><br clear="all"><div><br></div>-- <br><div dir="ltr">Best Regards,<div><br></div><div>Kevin Qin</div></div>
</div></font></span></div>
<br>_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a> <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
<br></blockquote></div><br></div></div>