https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92308
Bug ID: 92308 Summary: Gimple passes could do a better job of forming address CSEs Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: rearnsha at gcc dot gnu.org Target Milestone: --- Consider this testcase which was mentioned in https://gcc.gnu.org/ml/gcc-help/2019-10/msg00122.html. #define BB_ADDRESS 0x43fe1800 void test1(void) { volatile uint32_t * const p = (uint32_t *) BB_ADDRESS; p[3] = 1; p[4] = 2; p[1] = 3; p[7] = 4; p[0] = 6; } The gimple generated for this is test1 () { ;; basic block 2, loop depth 0 ;; pred: ENTRY MEM[(volatile uint32_t *)1140725772B] ={v} 1; MEM[(volatile uint32_t *)1140725776B] ={v} 2; MEM[(volatile uint32_t *)1140725764B] ={v} 3; MEM[(volatile uint32_t *)1140725788B] ={v} 4; MEM[(volatile uint32_t *)1140725760B] ={v} 6; return; ;; succ: EXIT } However, it's very unlikely on any RISC type architecture that addresses of this form will be valid. The TARGET_LEGITIMIZE_ADDRESS hook can help here, but that has to guess how to split the address and it has no idea what, for each call, the best base that should be chosen. In this case the best base is likely to be the lowest addressed object in the sequence, so that all other objects can use a small positive offset from that. The GIMPLE passes have a much broader view on the code being optimized, so forming a common base for all these addresses should be straight forward and much more likely to lead to better code than having to use a heuristic in the back-end.