<div dir="ltr"><div><div><div><div><div><div>I've got an example where I think that there should be some loop-invariant optimization happening, but it's not.  Here's the C code:<br><br><span style="font-family:monospace,monospace">#define DIM 8<br>#define UNROLL_DIM DIM<br>typedef double InArray[DIM][DIM];<br><br>__declspec(noalias) void f1( InArray c, const InArray a, const InArray b )<br>{<br><br>#pragma clang loop unroll_count(UNROLL_DIM)<br>    for( int i=0;i<DIM;i++)<br>#pragma clang loop unroll_count(UNROLL_DIM)<br>        for( int j=0;j<DIM;j++)<br>#pragma clang loop  unroll_count(UNROLL_DIM)<br>            for( int k=0;k<DIM;k++) {<br>                c[i][k] = c[i][k] + a[i][j]*b[j][k];<br>            }<br>}</span><br><br></div>The "a[i][j]" there is invariant in that inner loop. I've unrolled the loops with the unroll pragma to make the assembly easier to read, here's what I see (LVM 3.9, compiling with: clang -fms-compatibility -funroll-loops -O3   -c fma.c -o fma.o )<br><br><br><span style="font-family:monospace,monospace">0000000000000000 <f1>:<br>       0: 29580c0000000000  load  r3,r0,0x0,64<br>       8: 2958100200000000  load  r4,r1,0x0,64 #r4 <- a[0][0]<br>      10: 2958140400000000  load  r5,r2,0x0,64<br>      18: c0580c0805018000  fmaf  r3,r4,r5,r3,64<br>      20: 79b80c0000000000  store r3,r0,0x0,64<br>      28: 2958100000000008  load  r4,r0,0x8,64<br>      30: 2958140200000000  load  r5,r1,0x0,64 #r5 <- a[0][0]<br>      38: 2958180400000008  load  r6,r2,0x8,64<br>      40: c058100a06020000  fmaf  r4,r5,r6,r4,64<br>      48: 79b8100000000008  store r4,r0,0x8,64<br>      50: 2958140000000010  load  r5,r0,0x10,64<br>      58: 2958180200000000  load  r6,r1,0x0,64 #r6 <- a[0][0]<br>      60: 29581c0400000010  load  r7,r2,0x10,64<br>      68: c058140c07028000  fmaf  r5,r6,r7,r5,64<br>      70: 79b8140000000010  store r5,r0,0x10,64<br>      78: 2958180000000018  load  r6,r0,0x18,64<br>      80: 29581c0200000000  load  r7,r1,0x0,64 #r7 <- a[0][0]<br>      88: 2958200400000018  load  r8,r2,0x18,64<br>      90: c058180e08030000  fmaf  r6,r7,r8,r6,64<br>... </span><br><br></div>(fmaf semantics are: fmaf r1,r2,r3,r4, SIZE    r1 <- r2*r3+r4 )<br></div><div>(load semantics are: load r1,r2,imm, SIZE     r1<- mem[r2+imm] )<br></div><br></div>All three of the addresses are loaded in every loop. Only two need to be reloaded in the inner loop. I added the 'noalias' declspec in the C code above thinking that it would indicate that the pointers going into the function are not aliased and that that would allow the optimization, but it didn't make any difference.<br><br></div>Of course it's easy to rewrite the example code to avoid this extra load/inner loop, but I would have thought this would be a fairly straighforward optimization for the optimizer. Am I missing something?<br><br></div>Phil<br><div><div><div><div><div><div><br></div></div></div></div></div></div></div>