[PATCH] ARM: disable GCC SRA optimization

Ard Biesheuvel ard.biesheuvel at linaro.org
Wed Sep 2 09:45:24 PDT 2015


On 2 September 2015 at 18:28, Ard Biesheuvel <ard.biesheuvel at linaro.org> wrote:
> While working on the 32-bit ARM port of UEFI, I noticed a strange
> corruption in the kernel log. The following snprintf() statement
> (in drivers/firmware/efi/efi.c:efi_md_typeattr_format())
>
>         snprintf(pos, size, "|%3s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
>
> was producing the following output in the log:
>
>         |    |   |   |   |    |WB|WT|WC|UC]
>         |    |   |   |   |    |WB|WT|WC|UC]
>         |    |   |   |   |    |WB|WT|WC|UC]
>         |RUN|   |   |   |    |WB|WT|WC|UC]*
>         |RUN|   |   |   |    |WB|WT|WC|UC]*
>         |    |   |   |   |    |WB|WT|WC|UC]
>         |RUN|   |   |   |    |WB|WT|WC|UC]*
>         |    |   |   |   |    |WB|WT|WC|UC]
>         |RUN|   |   |   |    |   |   |   |UC]
>         |RUN|   |   |   |    |   |   |   |UC]
>
> As it turns out, this is caused by incorrect code being emitted for
> the string() function in lib/vsprintf.c. The following code
>
>         if (!(spec.flags & LEFT)) {
>                 while (len < spec.field_width--) {
>                         if (buf < end)
>                                 *buf = ' ';
>                         ++buf;
>                 }
>         }
>         for (i = 0; i < len; ++i) {
>                 if (buf < end)
>                         *buf = *s;
>                 ++buf; ++s;
>         }
>         while (len < spec.field_width--) {
>                 if (buf < end)
>                         *buf = ' ';
>                 ++buf;
>         }
>
> when called with len == 0, triggers an issue in the GCC SRA optimization
> pass (Scalar Replacement of Aggregates), which handles promotion of signed
> struct members incorrectly. This is a known but as yet unresolved issue.
> (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65932). In this particular
> case, it is causing the second while loop to be executed erroneously a
> single time, causing the additional space characters to be printed.
>
> So disable the optimization by passing -fno-ipa-sra.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> ---
>
> Needs to go to stable perhaps?
> The emitted asm is at the end of this patch.
>

Another report of the same issue:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66271


>  arch/arm/Makefile | 8 ++++++++
>  1 file changed, 8 insertions(+)
>
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index 7451b447cc2d..2c2b28ee4811 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -54,6 +54,14 @@ AS           += -EL
>  LD             += -EL
>  endif
>
> +#
> +# The Scalar Replacement of Aggregates (SRA) optimization pass in GCC 4.9 and
> +# later may result in code being generated that handles signed short and signed
> +# char struct members incorrectly. So disable it.
> +# (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65932)
> +#
> +KBUILD_CFLAGS  += $(call cc-option,-fno-ipa-sra)
> +
>  # This selects which instruction set is used.
>  # Note that GCC does not numerically define an architecture version
>  # macro, but instead defines a whole series of macros which makes
> --
> 1.9.1
>
>
> 000014d0 <string.isra.5>:
>     14d0:       e3520a01        cmp     r2, #4096       ; 0x1000
>     14d4:       e92d41f0        push    {r4, r5, r6, r7, r8, lr}
>     14d8:       e3007000        movw    r7, #0
>     14dc:       e3407000        movt    r7, #0
>     14e0:       21a07002        movcs   r7, r2
>     14e4:       e1a05000        mov     r5, r0
>     14e8:       e1a06001        mov     r6, r1
>     14ec:       e1a00007        mov     r0, r7
>     14f0:       e1dd11fc        ldrsh   r1, [sp, #28]
>     14f4:       e1a08003        mov     r8, r3
>     14f8:       e1dd41f8        ldrsh   r4, [sp, #24]
>     14fc:       ebfffffe        bl      0 <strnlen>
>     1500:       e3180002        tst     r8, #2
>     1504:       1a00000d        bne     1540 <string.isra.5+0x70>
>     1508:       e1500004        cmp     r0, r4
>     150c:       e2443001        sub     r3, r4, #1
>     1510:       e6bf4073        sxth    r4, r3
>     1514:       aa000009        bge     1540 <string.isra.5+0x70>
>     1518:       e3a02020        mov     r2, #32
>     151c:       e2443001        sub     r3, r4, #1
>     1520:       e1560005        cmp     r6, r5
>     1524:       85c52000        strbhi  r2, [r5]
>     1528:       e1500004        cmp     r0, r4
>     152c:       e6ff3073        uxth    r3, r3
>     1530:       e2855001        add     r5, r5, #1
>     1534:       e6bf4073        sxth    r4, r3
>     1538:       bafffff7        blt     151c <string.isra.5+0x4c>
>     153c:       e1a04003        mov     r4, r3
>     1540:       e3500000        cmp     r0, #0
>     1544:       da000016        ble     15a4 <string.isra.5+0xd4>
>     1548:       e085c000        add     ip, r5, r0
>     154c:       e1560005        cmp     r6, r5
>     1550:       e2855001        add     r5, r5, #1
>     1554:       e2877001        add     r7, r7, #1
>     1558:       85573001        ldrbhi  r3, [r7, #-1]
>     155c:       85453001        strbhi  r3, [r5, #-1]
>     1560:       e155000c        cmp     r5, ip
>     1564:       1afffff8        bne     154c <string.isra.5+0x7c>
>     1568:       e2443001        sub     r3, r4, #1
>     156c:       e1500004        cmp     r0, r4
>     1570:       e6bf3073        sxth    r3, r3
>     1574:       aa000008        bge     159c <string.isra.5+0xcc>
>     1578:       e3a01020        mov     r1, #32
>     157c:       e156000c        cmp     r6, ip
>     1580:       e1a02003        mov     r2, r3
>     1584:       85cc1000        strbhi  r1, [ip]
>     1588:       e2433001        sub     r3, r3, #1
>     158c:       e1500002        cmp     r0, r2
>     1590:       e28cc001        add     ip, ip, #1
>     1594:       e6bf3073        sxth    r3, r3
>     1598:       bafffff7        blt     157c <string.isra.5+0xac>
>     159c:       e1a0000c        mov     r0, ip
>     15a0:       e8bd81f0        pop     {r4, r5, r6, r7, r8, pc}
>     15a4:       e1a0c005        mov     ip, r5
>     15a8:       eaffffee        b       1568 <string.isra.5+0x98>
>



More information about the linux-arm-kernel mailing list