On Fri, 1 Oct 2021, Nelson Ribeiro via Gcc wrote: > Hello. > > Firstly I want to apologize for this long post, but in a way this post also > is meant for documenting the work that I have done hunting down this issue. > Secondly I must say that I do not have much insights on the GCC internals, > only the basic stuff. I know what a function prologue and epilogue is, but > I am not able to read GIMPLE or RTL for instance... > > So I have a C function that basically starts this way (after CPP > pre-processing): > > void e_printf( const charptr ctrl1, ...){ > int long_flag; > int dot_flag; > int skip_switch; > params_t par; > char ch; > va_list argp; > charptr ctrl = ctrl1; > __builtin_va_start(argp,ctrl1); > for ( ; *ctrl; ctrl++) { > (....) > > This C code function when compiled with the GCC version currently in git > trunk, compiled for target lm32-elf, generates the following assembly code: > (...) > .global e_printf > .type e_printf, @function > e_printf: > addi sp, sp, -116 > sw (sp+56), r11 > sw (sp+52), r12 > sw (sp+48), r13 > sw (sp+44), r14 > sw (sp+40), r15 > sw (sp+36), r16 > sw (sp+32), r17 > sw (sp+28), r18 > sw (sp+24), r19 > sw (sp+20), r20 > sw (sp+16), r21 > sw (sp+12), r22 > sw (sp+8), r23 > sw (sp+4), ra > lw r9, (sp+88) > sw (sp+92), r2 > sw (sp+88), r1 > lbu r1, (r9+0) > sw (sp+96), r3 > sw (sp+100), r4 > sw (sp+104), r5 > sw (sp+108), r6 > sw (sp+112), r7 > sw (sp+116), r8 > sw (sp+60), r9 > be r1,r0,.L1 > (...) > > Now this code in part is suboptimal because all 'pushed registers' from r2 > to r8 to the stack are never "poped" back but that is not the issue I am > referring. > Assuming that the "const charptr ctrl1" is passed to the function in > register r1, the following sequence is obviously wrong (the "sw > (sp+88), r1" instruction should appear first in this small sequence of > instructions for this snip of code to be correct): > lw r9, (sp+88) > sw (sp+92), r2 > sw (sp+88), r1 > lbu r1, (r9+0) > > Something went horrible wrong in this reordering instructions in the stack.
If I were you, I'd look into setting proper alias sets for the MEMs through which frame and varargs values are stored for lm32. Grep for set_mem_alias_set in the prologue/epilogue/varargs-handling expansions of other ports and perform archeology on the related commits and email-list traffic. Then again, that's more or less just a wild hunch. brgds, H-P