gcc-4.9 errors out on valid inline asm

Bug #1296942 reported by Arnd Bergmann
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Linaro GCC
Fix Released
Undecided
Michael Collison
gcc
Fix Released
Medium

Bug Description

Found while building an arm32 kernel

~/cross/bin/arm-linux-gnueabihf-gcc-4.9.0 -march=armv7-a -O2 -c -x c - <<< 'int g(void) { unsigned i, j; asm("// %0 %1" : "=r" (i), "=r"(j)); return i; }'
<stdin>: In function 'g':
<stdin>:1:30: error: invalid 'asm': operand number out of range

~/cross/bin/arm-linux-gnueabihf-gcc-4.9.0 --version
arm-linux-gnueabihf-gcc-4.9.0 (GCC) 4.9.0 20140324 (experimental)

description: updated
Revision history for this message
Zhenqiang Chen (zhenqiang-chen) wrote :

I can confirm it with trunk. There is no issue for Linaro 4.8 release.

Root cause: rtx_cost change in trunk triggers the bug. The check of check_asm_operands should be enhanced.

I will raise it to upstream and try to fix it.

Changed in gcc-linaro:
status: New → Triaged
assignee: nobody → Zhenqiang Chen (zhenqiang-chen)
Revision history for this message
In , Zhenqiang Chen (zhenqiang-chen) wrote :

Found while building an arm32 kernel

//fail.c
int g(void)
{
  unsigned i, j;
  asm("// %0 %1" : "=r" (i), "=r"(j));
  return i;
}

arm-linux-gnueabihf-gcc -march=armv7-a -O2 -c fail.c
fail.c: In function ‘g’:
fail.c:4:3: error: invalid 'asm': operand number out of range

Root cause: "cse1" generates illegal asm instruction since check_asm_operands does not check the number of expected operands.

i.e. "cse1" changes code from
(insn 5 2 6 2 (parallel [
            (set (reg:SI 114 [ i ])
                (asm_operands:SI ("// %0 %1") ("=r") 0 []
                     []
                     [] fail.c:4))
            (set (reg:SI 115 [ j ])
                (asm_operands:SI ("// %0 %1") ("=r") 1 []
                     []
                     [] fail.c:4))
        ]) fail.c:4 -1
     (nil))
(insn 6 5 8 2 (set (reg/v:SI 110 [ i ])
        (reg:SI 114 [ i ])) fail.c:4 664 {*thumb2_movsi_vfp}
     (nil))
to

(insn 12 2 13 2 (set (reg/i:SI 0 r0)
        (asm_operands:SI ("// %0 %1") ("=r") 0 []
             []
             [] fail.c:4)) fail.c:6 -1
     (nil))

No error for x86-64 and arm gcc-4.8. ARM rtx_cost changes in 4.9 trigger this optimization.

A patch to enhance check_asm_operands is sent out for review.

Changed in gcc:
importance: Unknown → Medium
status: Unknown → New
Revision history for this message
In , Jakub-gcc (jakub-gcc) wrote :

Supposedly introduced by r203160 which made inline asm with no input operands appear as having zero cost.

Alternate patch posted at http://gcc.gnu.org/ml/gcc-patches/2014-04/msg00512.html

Revision history for this message
In , Jakub-gcc (jakub-gcc) wrote :

Author: jakub
Date: Fri Apr 11 10:11:01 2014
New Revision: 209293

URL: http://gcc.gnu.org/viewcvs?rev=209293&root=gcc&view=rev
Log:
 PR rtl-optimization/60663
 * cse.c (cse_insn): Set src_volatile on ASM_OPERANDS in
 PARALLEL.

 * gcc.target/arm/pr60663.c: New test.

Added:
    trunk/gcc/testsuite/gcc.target/arm/pr60663.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/cse.c
    trunk/gcc/testsuite/ChangeLog

Revision history for this message
In , Jakub-gcc (jakub-gcc) wrote :

Should be fixed now.

Changed in gcc:
status: New → Fix Released
Revision history for this message
Arnd Bergmann (arnd-arndb) wrote :

Fix tested successfully

Revision history for this message
In , Arnd Bergmann (arnd-arndb) wrote :

Looks good now, I have resumed ARM kernel build testing with gcc-4.9 now and don't see this any more. There is one new bug that came up instead but it seems unrelated. I'll open a new ticket for that.

Revision history for this message
In , Ktkachov (ktkachov) wrote :

Author: ktkachov
Date: Tue Apr 15 14:04:06 2014
New Revision: 209419

URL: http://gcc.gnu.org/viewcvs?rev=209419&root=gcc&view=rev
Log:

 PR rtl-optimization/60663
 * config/arm/arm.c (arm_new_rtx_costs): Improve ASM_OPERANDS case,
 avoid 0 cost.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/arm/arm.c

Revision history for this message
In , Yroux (yroux) wrote :

Author: yroux
Date: Thu Jun 12 09:13:57 2014
New Revision: 211497

URL: http://gcc.gnu.org/viewcvs?rev=211497&root=gcc&view=rev
Log:
2014-05-23 Yvan Roux <email address hidden>

       Backport from trunk r209419.
       2014-04-15 Kyrylo Tkachov <email address hidden>

       PR rtl-optimization/60663
       * config/arm/arm.c (arm_new_rtx_costs): Improve ASM_OPERANDS case,
       avoid 0 cost.

Modified:
    branches/linaro/gcc-4_9-branch/gcc/ChangeLog.linaro
    branches/linaro/gcc-4_9-branch/gcc/config/arm/arm.c

Revision history for this message
Michael Collison (michael-collison) wrote :

Fixed in June release of Linaro GCC 4.9

Changed in gcc-linaro:
assignee: Zhenqiang Chen (zhenqiang-chen) → Michael Collison (michael-collison)
status: Triaged → Fix Released
Revision history for this message
In , Jakub-gcc (jakub-gcc) wrote :

Author: jakub
Date: Fri Jan 23 19:55:16 2015
New Revision: 220059

URL: https://gcc.gnu.org/viewcvs?rev=220059&root=gcc&view=rev
Log:
 PR rtl-optimization/63637
 PR rtl-optimization/60663
 * cse.c (merge_equiv_classes): Set new_elt->cost to MAX_COST
 if elt->cost is MAX_COST for ASM_OPERANDS.
 (find_sets_in_insn): Fix up comment typo.
 (cse_insn): Don't set src_volatile for all non-volatile
 ASM_OPERANDS in PARALLELs, but just those with multiple outputs
 or with "memory" clobber. Set elt->cost to MAX_COST
 for ASM_OPERANDS in PARALLEL. Set src_elt->cost to MAX_COST
 if new_src is ASM_OPERANDS and elt->cost is MAX_COST.

 * gcc.dg/pr63637-1.c: New test.
 * gcc.dg/pr63637-2.c: New test.
 * gcc.dg/pr63637-3.c: New test.
 * gcc.dg/pr63637-4.c: New test.
 * gcc.dg/pr63637-5.c: New test.
 * gcc.dg/pr63637-6.c: New test.
 * gcc.target/i386/pr63637-1.c: New test.
 * gcc.target/i386/pr63637-2.c: New test.
 * gcc.target/i386/pr63637-3.c: New test.
 * gcc.target/i386/pr63637-4.c: New test.
 * gcc.target/i386/pr63637-5.c: New test.
 * gcc.target/i386/pr63637-6.c: New test.

Added:
    trunk/gcc/testsuite/gcc.dg/pr63637-1.c
    trunk/gcc/testsuite/gcc.dg/pr63637-2.c
    trunk/gcc/testsuite/gcc.dg/pr63637-3.c
    trunk/gcc/testsuite/gcc.dg/pr63637-4.c
    trunk/gcc/testsuite/gcc.dg/pr63637-5.c
    trunk/gcc/testsuite/gcc.dg/pr63637-6.c
    trunk/gcc/testsuite/gcc.target/i386/pr63637-1.c
    trunk/gcc/testsuite/gcc.target/i386/pr63637-2.c
    trunk/gcc/testsuite/gcc.target/i386/pr63637-3.c
    trunk/gcc/testsuite/gcc.target/i386/pr63637-4.c
    trunk/gcc/testsuite/gcc.target/i386/pr63637-5.c
    trunk/gcc/testsuite/gcc.target/i386/pr63637-6.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/cse.c
    trunk/gcc/testsuite/ChangeLog

Revision history for this message
In , Jakub-gcc (jakub-gcc) wrote :

Author: jakub
Date: Sun Feb 1 17:33:19 2015
New Revision: 220323

URL: https://gcc.gnu.org/viewcvs?rev=220323&root=gcc&view=rev
Log:
 Backported from mainline
 2015-01-23 Jakub Jelinek <email address hidden>

 PR rtl-optimization/63637
 PR rtl-optimization/60663
 * cse.c (merge_equiv_classes): Set new_elt->cost to MAX_COST
 if elt->cost is MAX_COST for ASM_OPERANDS.
 (find_sets_in_insn): Fix up comment typo.
 (cse_insn): Don't set src_volatile for all non-volatile
 ASM_OPERANDS in PARALLELs, but just those with multiple outputs
 or with "memory" clobber. Set elt->cost to MAX_COST
 for ASM_OPERANDS in PARALLEL. Set src_elt->cost to MAX_COST
 if new_src is ASM_OPERANDS and elt->cost is MAX_COST.

 * gcc.dg/pr63637-1.c: New test.
 * gcc.dg/pr63637-2.c: New test.
 * gcc.dg/pr63637-3.c: New test.
 * gcc.dg/pr63637-4.c: New test.
 * gcc.dg/pr63637-5.c: New test.
 * gcc.dg/pr63637-6.c: New test.
 * gcc.target/i386/pr63637-1.c: New test.
 * gcc.target/i386/pr63637-2.c: New test.
 * gcc.target/i386/pr63637-3.c: New test.
 * gcc.target/i386/pr63637-4.c: New test.
 * gcc.target/i386/pr63637-5.c: New test.
 * gcc.target/i386/pr63637-6.c: New test.

Added:
    branches/gcc-4_9-branch/gcc/testsuite/gcc.dg/pr63637-1.c
    branches/gcc-4_9-branch/gcc/testsuite/gcc.dg/pr63637-2.c
    branches/gcc-4_9-branch/gcc/testsuite/gcc.dg/pr63637-3.c
    branches/gcc-4_9-branch/gcc/testsuite/gcc.dg/pr63637-4.c
    branches/gcc-4_9-branch/gcc/testsuite/gcc.dg/pr63637-5.c
    branches/gcc-4_9-branch/gcc/testsuite/gcc.dg/pr63637-6.c
    branches/gcc-4_9-branch/gcc/testsuite/gcc.target/i386/pr63637-1.c
    branches/gcc-4_9-branch/gcc/testsuite/gcc.target/i386/pr63637-2.c
    branches/gcc-4_9-branch/gcc/testsuite/gcc.target/i386/pr63637-3.c
    branches/gcc-4_9-branch/gcc/testsuite/gcc.target/i386/pr63637-4.c
    branches/gcc-4_9-branch/gcc/testsuite/gcc.target/i386/pr63637-5.c
    branches/gcc-4_9-branch/gcc/testsuite/gcc.target/i386/pr63637-6.c
Modified:
    branches/gcc-4_9-branch/gcc/ChangeLog
    branches/gcc-4_9-branch/gcc/cse.c
    branches/gcc-4_9-branch/gcc/testsuite/ChangeLog

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.