I have a query regarding post-increment addressing for multiple array access in a loop. GCC version used: ver 4.4.0 Target: m32r Please consider the following cases. Case I. Single Array Access Within Loop ======================================== Please consider the below test case: int siLoopIndex; int siData[40]; int siVar1; void vAutoIncrementAddressingMode() { for (siLoopIndex=0; siLoopIndex<40; siLoopIndex++) { siVar1 = siData[siLoopIndex]; } } For the above case, the assembly generated is as follows: Assembly (post-increment generated) ------------------------------------- (GCC ver 4.4.0, target=m32r, option -O3) vAutoIncrementAddressingMode: ; PROLOGUE, vars= 0, regs= 0, args= 0, extra= 0 ld24 r4,#siData ld24 r6,#siData+160 .balign 4 .L2: ld r5,@r4+ <== Post-increment mode generated bne r4,r6,.L2 ld24 r4,#siVar1 st r5,@(r4) ld24 r4,#siLoopIndex ldi r5,#40 ; 0x28 st r5,@(r4) jmp lr For the above test case the optimized gimple obtained is as below: Optimized gimple (-fdump-tree-optimized) ----------------------------------------- vAutoIncrementAddressingMode () { long unsigned int D.1238; long unsigned int ivtmp.34; int siVar1.1; <bb 2>: ivtmp.34 = (long unsigned int) &siData[0]; <== (A) D.1238 = (long unsigned int) &siData + 160; <bb 3>: siVar1.1 = MEM[index: ivtmp.34]; <== (B) ivtmp.34 = ivtmp.34 + 4; <== (C) if (ivtmp.34 != D.1238) goto <bb 3>; else goto <bb 4>; <bb 4>: siVar1 = siVar1.1; siLoopIndex = 40; return; } Please note the marked statements (A), (B) and (C). In the statement (A), the pointer to first location of array "siData" is set as "ivtmp.22". Please note that this statement is not inside the loop, but is hoisted above it. Now, post-increment generation is identified with statements (B) and (C) as follows. siVar1.1 = MEM[index: ivtmp.22]; <== (B) \_____________/ | V X ivtmp.22 = ivtmp.22 + 4; <== (C) \_____________________/ | V X++ In statement (B), the array "siData" is accessed using index "ivtmp.22" (call it X). The next statement increments "X" to point to the next location. Hence, post-increment operation is identified and assembly with post-increment addressing gets generated: Case II. Multiple Array Access Within Loop (with same Array Index) =================================================================== Now, please consider the below test case: int siLoopIndex; int siSum ; int siData[40],siCoeff[40]; int siVar1; int siVar2; void vAutoIncrementAddressingMode() { int lsiSum; for (siLoopIndex=0; siLoopIndex<40; siLoopIndex++) { siVar1 = siData[siLoopIndex]; siVar2 = siCoeff[siLoopIndex]; } } The assembly generated for the above test case is as follows: Assembly (no post-increment generated) ---------------------------------------- (GCC ver 4.4.0, target=m32r, option -O3) vAutoIncrementAddressingMode: ; PROLOGUE, vars= 0, regs= 0, args= 0, extra= 0 ldi r4,#0 ; 0x0 .balign 4 .L2: ld24 r7,#siData ld24 r6,#siCoeff add r7,r4 // r7 points to base address of siData // r4 contains value of siLoopIndex // siData[siLoopIndex] accessed by adding // r7 and $4 add r6,r4 // r6 points to base address of siCoeff // r4 contains value of siLoopIndex // siCoeff[siLoopIndex] accessed by adding // r6 and $4 addi r4,#4 // siLoopIndex is incremented here add3 r5,r4,#-160 ld r7,@(r7) ld r6,@(r6) bnez r5,.L2 ld24 r4,#siVar1 st r7,@(r4) ld24 r4,#siVar2 st r6,@(r4) ld24 r4,#siLoopIndex ldi r5,#40 ; 0x28 st r5,@(r4) jmp lr In this case, post-increment addressing mode is not generated. Please note that here, (base address + siLoopIndex) is used to access the array locations, for each iteration of the loop. As against Case I above, where code for pointing to the base address of the array was hoisted above the loop. And then, only array index was incremented with each iteration of the loop. The optimized gimple generated by GCC for this case is as below: Optimized gimple (-fdump-tree-optimized) ----------------------------------------- vAutoIncrementAddressingMode () { long unsigned int ivtmp.37; int siVar2.2; int siVar1.1; <bb 2>: ivtmp.37 = 0; <bb 3>: siVar1.1 = MEM[base: &siData + ivtmp.37]; <== Base address + Loop Index siVar2.2 = MEM[base: &siCoeff + ivtmp.37];<== Base address + Loop Index ivtmp.37 = ivtmp.37 + 4; if (ivtmp.37 != 160) goto <bb 3>; else goto <bb 4>; <bb 4>: siVar1 = siVar1.1; siVar2 = siVar2.2; siLoopIndex = 40; return; } I have the understanding that some loop transformation might be required to convert the above code into the form: <bb 2>: ivtmp.22 = (long unsigned int) &siData[0]; ivtmp.23 = (long unsigned int) &siCoeff[0]; <bb 3>: siVar1.1 = MEM[index: ivtmp.22]; siVar2.2 = MEM[index: ivtmp.23]; ivtmp.22 = ivtmp.22 + 4; ivtmp.23 = ivtmp.23 + 4; Please verify my understanding. Case III. Multiple Array Access Within Loop (with different Array Index) ========================================================================= As an additional observation, when I changed the array index variable, to access the second array, the post-increment mode got generated. int siLoopIndex1; int siLoopIndex2; int siData[40],siCoeff[40]; int siVar1; int siVar2; void vAutoIncrementAddressingMode() { for (siLoopIndex1=0; siLoopIndex1<40; siLoopIndex1++) { siVar1 = siData[siLoopIndex1]; siVar2 = siCoeff[siLoopIndex2]; siLoopIndex2++; } } Assembly (post-increment generated) ------------------------------------- (GCC ver 4.4.0, target=m32r, option -O3) vAutoIncrementAddressingMode: ; PROLOGUE, vars= 0, regs= 1, args= 0, extra= 0 ld24 r3,#siLoopIndex2 ld24 r6,#siCoeff ld24 r4,#siData ld24 r2,#siData+160 push lr ld lr,@(r3) sll3 r5,lr,#2 add r5,r6 .balign 4 .L2: ld r7,@r4+ <== Post-Increment generated ld r6,@r5+ <== Post-Increment generated bne r4,r2,.L2 ld24 r4,#siVar1 st r7,@(r4) ld24 r4,#siVar2 st r6,@(r4) ld24 r4,#siLoopIndex1 addi lr,#40 ldi r5,#40 ; 0x28 st lr,@(r3) st r5,@(r4) pop lr jmp lr The optimized gimple for the above case is as follows: Optimized gimple (-fdump-tree-optimized) ----------------------------------------- vAutoIncrementAddressingMode () { long unsigned int D.1251; long unsigned int ivtmp.45; long unsigned int ivtmp.42; int pretmp.18; int siVar2.3; int siVar1.1; <bb 2>: pretmp.18 = siLoopIndex2; <== Code Hoisted ==> ivtmp.42 = (long unsigned int) &siData[0]; <== Code Hoisted ==> ivtmp.45 = (long unsigned int) &siCoeff[pretmp.18]; D.1251 = (long unsigned int) &siData + 160; <bb 3>: siVar1.1 = MEM[index: ivtmp.42]; siVar2.3 = MEM[index: ivtmp.45]; ivtmp.42 = ivtmp.42 + 4; ivtmp.45 = ivtmp.45 + 4; if (ivtmp.42 != D.1251) goto <bb 3>; else goto <bb 4>; <bb 4>: siVar1 = siVar1.1; siVar2 = siVar2.3; siLoopIndex2 = [plus_expr] pretmp.18 + 40; siLoopIndex1 = 40; return; } As we see above, code for pointing to base addresses of arrays gets hoisted. Could you please explain why the post-increment mode does not get generated in Case II? What would need to be done to generate post increment mode for Case II?