https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98981
Bug ID: 98981 Summary: gcc-10.2 for RISC-V has extraneous register moves Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: brian.grayson at sifive dot com Target Milestone: --- gcc is inserting an unnecessary register-register move for a simple max-style operation: int a[256], b[256]; int32_t find_max_i32() { int32_t xme = 0, sc=0; for (int32_t i = 0; i < 100; i++) { if ((sc=a[i]+b[i]) > xme) xme=sc; } return xme; } This is from the SPECint2006 benchmark HMMER, in P7Viterbi(), hence the variable names sc and xme from the original source. Under these flags: -march=rv64imafdc -mcmodel=medany -mabi=lp64d -O3 I get this disassembly for the loop: .L5: lw a5,0(a4) lw a2,0(a3) addi a4,a4,4 addi a3,a3,4 addw a2,a5,a2 mv a5,a2 <--- unnecessary move bge a2,a0,.L4 mv a5,a0 .L4: sext.w a0,a5 bne a4,a1,.L5 If the addw targets a5, and the bge compares a5 to a0, the mv could be removed. In fact, if the variable types are changed to int64_t, that's exactly what happens: .L13: ld a5,0(a4) ld a2,0(a3) addi a4,a4,8 addi a3,a3,8 add a5,a5,a2 bgeu a0,a5,.L12 mv a0,a5 .L12: bne a4,a1,.L13