[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