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

Unexpected behaviour in gnu style inline asm

Vitaliy_Vorobyov
Beginner
665 Views
Intel c++ compiler for windows (ia-32, 11.0.72) have unexpected behaviour in gnu style inline asm blocks when "ommite frame pointer" optimization option is on.

sample code:
static void *func;

void proc(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j)
{
__asm__ volatile("pushl %0\n\t"::"rm"(a):"esp");
__asm__ volatile("pushl %0\n\t"::"rm"(b):"esp");
__asm__ volatile("pushl %0\n\t"::"rm"(c):"esp");
__asm__ volatile("pushl %0\n\t"::"rm"(d):"esp");
__asm__ volatile("pushl %0\n\t"::"rm"(e):"esp");
__asm__ volatile("pushl %0\n\t"::"rm"(f):"esp");
__asm__ volatile("pushl %0\n\t"::"rm"(g):"esp");
__asm__ volatile("pushl %0\n\t"::"rm"(h):"esp");
__asm__ volatile("pushl %0\n\t"::"rm"(i):"esp");
__asm__ volatile("pushl %0\n\t"::"rm"(j):"esp");
__asm__ volatile("lcall *%0"::"rm"(func));
}

Intel compiler incorectly adress parameters of function "proc" via esp register. It does not check that push instruction modify esp value.

Gcc compiler have the same behaviour.

Asm listings are in attachment.

Compile options:
intel: icl -Fa -c tst.c
gcc: gcc -O2 --ommite-frame-pointer -c tst.c

P.S. Expected behaviour is adress parameters of function proc whith right esp offset calculation, or adress "proc" parameters via ebp register if compiler can not calculate right esp offset in this case.
0 Kudos
8 Replies
Lingfeng_C_Intel
Employee
665 Views
Intel c++ compiler for windows (ia-32, 11.0.72) have unexpected behaviour in gnu style inline asm blocks when "ommite frame pointer" optimization option is on.

sample code:
static void *func;

void proc(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j)
{
__asm__ volatile("pushl %0nt"::"rm"(a):"esp");
__asm__ volatile("pushl %0nt"::"rm"(b):"esp");
__asm__ volatile("pushl %0nt"::"rm"(c):"esp");
__asm__ volatile("pushl %0nt"::"rm"(d):"esp");
__asm__ volatile("pushl %0nt"::"rm"(e):"esp");
__asm__ volatile("pushl %0nt"::"rm"(f):"esp");
__asm__ volatile("pushl %0nt"::"rm"(g):"esp");
__asm__ volatile("pushl %0nt"::"rm"(h):"esp");
__asm__ volatile("pushl %0nt"::"rm"(i):"esp");
__asm__ volatile("pushl %0nt"::"rm"(j):"esp");
__asm__ volatile("lcall *%0"::"rm"(func));
}

Intel compiler incorectly adress parameters of function "proc" via esp register. It does not check that push instruction modify esp value.

Gcc compiler have the same behaviour.

Asm listings are in attachment.

Compile options:
intel: icl -Fa -c tst.c
gcc: gcc -O2 --ommite-frame-pointer -c tst.c

P.S. Expected behaviour is adress parameters of function proc whith right esp offset calculation, or adress "proc" parameters via ebp register if compiler can not calculate right esp offset in this case.

Thanks for your issue submitted,
I will try to reproduce this case and report it to related team.

Thanks,
Wise
0 Kudos
Lingfeng_C_Intel
Employee
665 Views

Hi Vitaliy,

I am testing your case now and I am using 11.1 version not 11.0 version for window.
I did below command:
icl -Fa -c tst.c
i didn't find any error message during cmpiling.
Also, I am using icc 11.0.084 for linux version and type below command:
gcc -O2 --ommite-frame-pointer -c tst.c
And I got below message:
cc1: unrecognized option `-fommite-frame-pointer'
Could you tell me how I can reproduce this case?

My email address is wise.chen@intel.com if you want to communicate with me through email, please use this one.

Thanks,
Wise

0 Kudos
Om_S_Intel
Employee
665 Views

The option -fomit-frame-pointer is to be use in place -fomite-frame-pointer.
0 Kudos
Vitaliy_Vorobyov
Beginner
665 Views
Quoting - (Intel)

Also, I am using icc 11.0.084 for linux version and type below command:
gcc -O2 --ommite-frame-pointer -c tst.c
And I got below message:
cc1: unrecognized option `-fommite-frame-pointer'
Could you tell me how I can reproduce this case?

I write wrong options, the right options are:
gcc -O2 -fomit-frame-pointer -S -c tst.c
0 Kudos
Om_S_Intel
Employee
665 Views

The stack pointer register ESP and base pointer register are properly handled by Intel compiler.

The users could manupulate the registerusinginline assembly, the compiler does not have control over the assembly logic.It is users responsibilityto write proper inline assembly code.
0 Kudos
Vitaliy_Vorobyov
Beginner
665 Views

The stack pointer register ESP and base pointer register are properly handled by Intel compiler.

The users could manupulate the registerusinginline assembly, the compiler does not have control over the assembly logic.It is users responsibilityto write proper inline assembly code.
Is there any method to tell compiler to not use esp register for parameter adressing (but use ebp for example)? Compiler simply ignore esp in clobbers list. I found only solution by placing #pragma optimize("", off) around function.
0 Kudos
Dale_S_Intel
Employee
665 Views
Is there any method to tell compiler to not use esp register for parameter adressing (but use ebp for example)? Compiler simply ignore esp in clobbers list. I found only solution by placing #pragma optimize("", off) around function.

I may be a little confused, but when you say "-fomit-frame-pointer" you're specifically instructing the compiler NOT to use ebp, but to use esp instead. Perhaps what you want is "-fno-omit-frame-pointer". From "icl -help" output:

-f[no-]omit-frame-pointer
enable(DEFAULT)/disable use of EBP as general purpose register.
-fno-omit-frame-pointer replaces -fp

In any case, as Om points out, if you're doing inline asm like the above, it's the asm writer's responsibility to match what the compiler is doing, not the other way round. Modifying esp in an inline asm block is likely to mess things up because the compiler may not be aware of the change to esp.

Dale

0 Kudos
Vitaliy_Vorobyov
Beginner
665 Views

I may be a little confused, but when you say "-fomit-frame-pointer" you're specifically instructing the compiler NOT to use ebp, but to use esp instead. Perhaps what you want is "-fno-omit-frame-pointer". From "icl -help" output:

-f[no-]omit-frame-pointer
enable(DEFAULT)/disable use of EBP as general purpose register.
-fno-omit-frame-pointer replaces -fp

In any case, as Om points out, if you're doing inline asm like the above, it's the asm writer's responsibility to match what the compiler is doing, not the other way round. Modifying esp in an inline asm block is likely to mess things up because the compiler may not be aware of the change to esp.

Dale

I use "-fomit-frame-pointer" to all files in my project (this test sample is one function to show incorrect behaviour), but this function need to be compiled without frame pointer ommition, or intel compiler should check clobbers list in gnu asm block and not use esp.

Why intel compiler not analyze inline assembly blocks? At code generation step compiler have all information about instruction lengthes and about instructions/registers dependences. Under windows intel compiler does not use external assembler (like in linux), but parse assembly blocks internaly and generate whole code include any inline assembly blocks.
0 Kudos
Reply