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

            Bug ID: 113985
           Summary: redundant copy of return values at O0
           Product: gcc
           Version: 13.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: absoler at smail dot nju.edu.cn
  Target Milestone: ---

hi, I found with -O0 flag, there are redundant operations on return values of
structure type.

```
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int int16_t;
typedef unsigned short int uint16_t;
typedef signed int int32_t;
typedef unsigned int uint32_t;
typedef signed long int int64_t;
typedef unsigned long int uint64_t;

struct S0 {
   int32_t  f0;
   uint8_t  f1;
   int32_t  f2;
};

struct S0 g_91 = {0x6732C952L,0x6BL,6L};
int64_t g_205[9] =
{0L,0L,0x47DC22DBA5B9078ELL,0L,0L,0x47DC22DBA5B9078ELL,0L,0L,0x47DC22DBA5B9078ELL};

void  func_1(void);
struct S0  func_2();


void func_1() {
  struct S0 a;
  struct S0 *b = &g_91;
  *b = func_2(0, a, a.f1, g_205[0]);
}
struct S0 func_2() { return g_91;}
```

the disassembly:
```
0000000000401186 <func_1>:
func_1():
/root/loadtest0/test/output2.c:44
  401186:       push   %rbp
  401187:       mov    %rsp,%rbp
  40118a:       sub    $0x20,%rsp
/root/loadtest0/test/output2.c:46
  40118e:       movq   $0x404080,-0x8(%rbp)
/root/loadtest0/test/output2.c:47
  401196:       mov    0x2f03(%rip),%rsi        # 4040a0 <g_205>
  40119d:       movzbl -0x10(%rbp),%eax
  4011a1:       movzbl %al,%ecx
  4011a4:       mov    -0x14(%rbp),%rdx
  4011a8:       mov    -0xc(%rbp),%eax
  4011ab:       mov    %rsi,%r8
  4011ae:       mov    %rdx,%rsi
  4011b1:       mov    %eax,%edx
  4011b3:       mov    $0x0,%edi
  4011b8:       mov    $0x0,%eax
  4011bd:       callq  4011d7 <func_2>
  4011c2:       mov    -0x8(%rbp),%rcx
  4011c6:       mov    %rax,(%rcx)
  4011c9:       mov    0x8(%rcx),%eax // redundant
  4011cc:       and    $0x0,%eax
  4011cf:       or     %edx,%eax
  4011d1:       mov    %eax,0x8(%rcx)
/root/loadtest0/test/output2.c:48
  4011d4:       nop
  4011d5:       leaveq 
  4011d6:       retq   
```

we can see that it's unnecessary to load `0x8(%rcx)` into %eax, because it will
be cleared in the next instruction

Reply via email to