Why ret disappear with optimization?

亡梦爱人 提交于 2020-01-14 10:36:08

问题


int suma(int* array, int len)
{
    asm("    xor %eax, %eax           # resultado = 0   \n"
        "    xor %edx, %edx           # i = 0           \n"
        "1:  add (%rdi,%rdx,4), %eax  # res += array[i] \n"
        "    inc %edx                 # ++i             \n"
        "    cmp %edx,%esi            # i < len?        \n"
        "    jne 1b                   # repetir         \n"
//      "    ret                                        \n"
       );
}

int main()
{
    int v[100];
    return suma(v, 100);
}

Why is it that gcc inserts ret at the end of suma() on -O0, but I have to add it myself on -O3?

From gcc -v:

gcc version 8.2.1 20181011 (Red Hat 8.2.1-4) (GCC) 

回答1:


I assume 64bit..., array in rdi, len in esi.

You're using inline asm, and not in a __attribute__((naked,noinline)) function, so the compiler can use the inline asm template block in any context it wants. Since you failed to use any input/output constraints, and you clobber registers without telling the compiler, it will just totally break unless you disable optimization.

To answer the main question, the compiler simply inlines suma into main. It's implicitly volatile (because it's a basic asm statement) so it isn't optimized away.

But execution falls off the end of a non-void function (suma), which is undefined behaviour, so modern GCC just gives up and omits the ret instruction. It assumes that execution can never take that path (because of the undefined behaviour), and doesn't bother generating code for it.

If you add a return 0; to the end of suma, then main will end with a ret instruction.

Surprisingly, gcc only gives one warning on the Godbolt compiler explorer with -O3 -Wall:

<source>: In function 'int suma(int*, int)':
<source>:13:1: warning: no return statement in function returning non-void [-Wreturn-type]
 }
 ^

The resulting asm output for main is this, which is of course totally broken because RDI is argc; it never reserved space for int v[100] because its unused in the C source or did anything.

main:
            xor %eax, %eax           # resultado = 0   
    xor %edx, %edx           # i = 0           
1:  add (%rdi,%rdx,4), %eax  # res += array[i] 
    inc %edx                 # ++i             
    cmp %edx,%esi            # i < len?        
    jne 1b                   # repetir         

With a return 0; at the end of suma, it and main end with xorl %eax, %eax ; ret, but of course main is still totally broken because the inline asm doesn't use any input constraints.



来源:https://stackoverflow.com/questions/52966290/why-ret-disappear-with-optimization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!