sdk-ng: unexpected behavior of ARCv2 memset in NEWLIB_LIBC with -Os

        printk("-- PWRCTL = 0x%08x\n", sys_read32(PWRCTL));
50030c70:       40c3 5004 31b0          mov_s   r0,0x500431b0
50030c76:       45cb f000 1d10          mov_s   r13,0xf0001d10
50030c7c:       0d1e f94f               bl      -53988  ;50023998 <printk>
50030c80:       1500 1001               ld      r1,[r13]
        printk("++ CLKCTL = 0x%08x\n", sys_read32(CLKCTL));
50030c84:       40c3 5004 31d0          mov_s   r0,0x500431d0
50030c8a:       0d12 f94f               bl      -54000  ;50023998 <printk>
        __asm__ volatile("ld    %1, %0\n"
50030c8e:       1500 1010               ld      r16,[r13]
50030c92:       2050 2050               bclr    r16,r16,0x1
50030c96:       1d00 1400               st      r16,[r13]
        __asm__ volatile("ld%U1 %0, %1;\n\t"
50030c9a:       1500 1001               ld      r1,[r13]
        printk("-- CLKCTL = 0x%08x\n", sys_read32(CLKCTL));
50030c9e:       40c3 5004 31f0          mov_s   r0,0x500431f0
50030ca4:       0cf6 f94f               bl      -54028  ;50023998 <printk>
        msg_req->msg.type = LARGE_CONFIG_GET;
50030ca8:       d843                    mov_s   r0,0x43
        memset(msg_req, 0, sizeof(msg_req_hdr_t));
50030caa:       1c08 3400               st      r16,[sp,8]
50030cae:       1c0c 3400               st      r16,[sp,12]
        msg_req->msg.type = LARGE_CONFIG_GET;
50030cb2:       1c0b 3002               stb     r0,[sp,11]
        msg_req->msg.final_block = 1 ;
50030cb6:       d830                    mov_s   r0,0x30
50030cb8:       0a32 ffef               bl.d    -1488   ;500306e8 <z_arch_is_user_context>
50030cbc:       1c0f 3002               stb     r0,[sp,15]
        LOG_INF("%s", __func__);

this is a fragment of my code, intends to do memset for a local variable which locates at current stack [sp,8] and [sp,12] as instructions located at 50030caa and 50030cae show, and it seems compiler assume the r16 is 0 on instructions located at 50030caa and 50030cae. But before that, the value of r16 is first loaded from [r13] with r13 = 0xf0001d10, and then do bclr r16,r16,0x1, I don’t know why compiler assumes r16 is 0 at current situation but it caused wrong behavior in my code.

@vonhust could you please help take a look at this? Did I miss something?

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 17 (4 by maintainers)

Most upvoted comments

@wentongwu no, but u can consider the above statement as the link, as I am the ARC GNU compiler maintainer.

    memset(msg_req, 0, sizeof(msg_req_hdr_t));

50030caa: 1c08 3400 st r16,[sp,8] 50030cae: 1c0c 3400 st r16,[sp,12]

This makes even less sense given that st 0,[sp,imm] can be encoded in the ARC ISA.

I wrote a test code and can see that the compiler generates valid instructions (tested with GCC 9.2.0):

void main(void)
{
80400a08:       c1a2                    sub_s   sp,sp,0x8
        struct rubbish_struct rubbish;

        __builtin_memset(&rubbish, 0, sizeof(rubbish));
80400a0a:       1c00 3001               st      0,[sp]
80400a0e:       1c04 3001               st      0,[sp,4]