optimizes out arguments when values are the same
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Linaro GCC |
Invalid
|
Undecided
|
Michael Collison |
Bug Description
Toolchain: gcc-linaro-
It is expected that a, b, c and d of function XXX below are stored in x0,x1,x2 and x3 respectively. But if I call XXX with same argument values, then only x0 gets used. This results in a failure when smc call is made.
XXX(0, 0, 0, 0);
static noinline int XXX(unsigned long a, unsigned long b, unsigned long c,
{
asm volatile(
: "+r" (a)
: "r" (b), "r" (c), "r" (d));
return a;
}
The .s file shows this,
XXX.constprop.1:
.LFB592:
.loc 1 131 0
.LVL40:
.loc 1 134 0
mov x0, 0 // a,
#APP
// 134 "arch/arm64/
@ a = x0 (should be x0) // a
@ b = x0 (should be x1) // a
@ c = x0 (should be x2) // a
@ d = x0 (should be x3) // a
smc #0
Changed in gcc-linaro: | |
assignee: | nobody → Michael Collison (michael-collison) |
Changed in gcc-linaro: | |
status: | New → Invalid |
The asm volatile is not a function call and therefore does not have to follow ABI calling convention. Additionally the contstraints ("r") allow the compiler to allocate any register it desires. You must indicate to the compiler that the arguments are required to be in registers x0-x3 like so:
static __attribute__ ((noinline)) int XXX(unsigned long a, unsigned long b, unsigned long c,
unsigned long d)
{
register unsigned long _a asm ("x0") = a;
register unsigned long _b asm ("x1") = b;
register unsigned long _c asm ("x2") = c;
register unsigned long _d asm ("x3") = d;
asm volatile(
"@ a = %0 (should be x0)\n\t"
"@ b = %1 (should be x1)\n\t"
"@ c = %2 (should be x2)\n\t"
"@ d = %3 (should be x3)\n\t"
"smc #0\n"
: "+r" (_a)
: "r" (_b), "r" (_c), "r" (_d));
return a;
}