Comment 2 for bug 1296942

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.