https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120660

--- Comment #1 from Zdenek Sojka <zsojka at seznam dot cz> ---
The difference between OK and BAD is:

$ diff -u OK.S BAD.S
--- OK.S        2025-07-15 16:39:49.437945918 +0200
+++ BAD.S       2025-07-15 16:39:53.377945956 +0200
@@ -14,7 +14,7 @@
 @ GNU C23 (GCC) version 16.0.0 20250714 (experimental)
(armv7a-hardfloat-linux-gnueabi)
 @      compiled by GNU C version 14.3.0, GMP version 6.3.0, MPFR version
4.2.2, MPC version 1.3.1, isl version none
 @ GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
-@ options passed: -mfloat-abi=hard -mfpu=vfpv4 -mtls-dialect=gnu -marm
-march=armv7-a+vfpv4 -O
+@ options passed: -mfloat-abi=hard -mfpu=vfpv4 -mtls-dialect=gnu -marm
-march=armv7-a+vfpv4 -O -favoid-store-forwarding
        .text
        .align  2
        .global foo
@@ -26,14 +26,14 @@
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        sub     sp, sp, #8      @,,
-       strh    r0, [sp, #6]    @ movhi @ s, s
 @ testcase.c:6:   __builtin_memset (&s, c, 1);
        movw    r3, #:lower16:.LANCHOR0 @ tmp99,
        movt    r3, #:upper16:.LANCHOR0 @ tmp99,
        ldr     r3, [r3]        @ c, c
-       strb    r3, [sp, #6]    @ c, MEM <char[1:1]> [(void *)&s]
 @ testcase.c:8: }
-       ldrsh   r0, [sp, #6]    @, s
+       strh    r0, [sp, #6]    @ movhi @ tmp109, s
+       strb    r3, [sp, #6]    @ tmp108, MEM <char[1:1]> [(void *)&s]
+       sxth    r0, r3  @, tmp107
        add     sp, sp, #8      @,,
        @ sp needed     @
        bx      lr      @


eg. (r0 = 's', r3 = 'c'), OK:

        strh    r0, [sp, #6]    @ movhi @ s, s
        strb    r3, [sp, #6]    @ c, MEM <char[1:1]> [(void *)&s]
        ldrsh   r0, [sp, #6]    @, s

BAD:

        strh    r0, [sp, #6]    @ movhi @ tmp109, s
        strb    r3, [sp, #6]    @ tmp108, MEM <char[1:1]> [(void *)&s]
        sxth    r0, r3  @, tmp107

the difference is the last instruction. BAD just sign-extends (16-bit) 'c' to
(32-bit) 's' as return value (zero). OK correctly reads 's' as (16-bit) value
from stack, sign-extended to 32-bit.

Reply via email to