optimizes out arguments when values are the same

Bug #1305042 reported by vinayak menon
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Linaro GCC
Invalid
Undecided
Michael Collison

Bug Description

Toolchain: gcc-linaro-aarch64-linux-gnu-4.8-2014.01_linux

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,
                                         unsigned long 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;
}

The .s file shows this,

XXX.constprop.1:
.LFB592:
        .loc 1 131 0
        .cfi_startproc
.LVL40:
        .loc 1 134 0
        mov x0, 0 // a,
#APP
// 134 "arch/arm64/kernel/psci.c" 1
        @ 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)
Revision history for this message
Michael Collison (michael-collison) wrote :

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;
}

Changed in gcc-linaro:
status: New → Invalid
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.