<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">I come across a situation that I am having a hard time to understand. </div><div class=""><br class=""></div><div class="">When I compile the following code :</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">char</span> *tst( <span style="color: #ba2da2" class="">char</span> *dest, <span style="color: #ba2da2" class="">const</span> <span style="color: #ba2da2" class="">char</span> *src, <span style="color: #ba2da2" class="">unsigned</span> <span style="color: #ba2da2" class="">int</span> len )</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class="">{</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""> <span style="color: #ba2da2" class="">for</span> (<span style="color: #ba2da2" class="">int</span> i=<span style="color: #272ad8" class="">0</span> ; i<len ; i++) {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""> dest[i] = src[i];</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""> } </div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);" class="">return<span style="color: #000000" class=""> dest;</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class="">}</div></div><div class=""><br class=""></div><div class="">Clang generates this for the ‘for’ body:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class="">for.body: ; preds = %for.cond</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""> %arrayidx = getelementptr inbounds i8, i8* %src, i16 %i.0</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""> %0 = load i8, i8* %arrayidx, align 1, !tbaa !2</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""> %arrayidx1 = getelementptr inbounds i8, i8* %dest, i16 %i.0</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""> store i8 %0, i8* %arrayidx1, align 1, !tbaa !2</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""> %inc = add nuw nsw i16 %i.0, 1</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""> br label %for.cond</div></div><div class=""><br class=""></div><div class="">This gets converted into this by llc:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t2: i16,ch = CopyFromReg t0, Register:i16 %3</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t4: i16,ch = CopyFromReg t0, Register:i16 %0</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t5: i16 = add t2, t4</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating constant: t6: i16 = Constant<0></b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t7: i16 = undef</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t8: i8,ch = load<(load 1 from %ir.scevgep1, !tbaa !2)> t0, t5, undef:i16</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t10: i16,ch = CopyFromReg t0, Register:i16 %2</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t11: i16 = add t10, t4</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t12: ch = store<(store 1 into %ir.scevgep, !tbaa !2)> t8:1, t8, t11, undef:i16</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating constant: t13: i16 = Constant<1></b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t14: i16 = add nuw nsw t4, Constant:i16<1></b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t16: ch = CopyToReg t0, Register:i16 %1, t14</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t17: ch = TokenFactor t16, t12</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t19: ch = br t17, BasicBlock:ch<for.cond 0x10983ff38></b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Initial selection DAG: %bb.3 'tst:for.body'</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">SelectionDAG has 20 nodes:</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t0: ch = EntryToken</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t4: i16,ch = CopyFromReg t0, Register:i16 %0</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t6: i16 = Constant<0></b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t2: i16,ch = CopyFromReg t0, Register:i16 %3</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t5: i16 = add t2, t4</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t8: i8,ch = load<(load 1 from %ir.scevgep1, !tbaa !2)> t0, t5, undef:i16</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t14: i16 = add nuw nsw t4, Constant:i16<1></b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t16: ch = CopyToReg t0, Register:i16 %1, t14</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t10: i16,ch = CopyFromReg t0, Register:i16 %2</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t11: i16 = add t10, t4</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t12: ch = store<(store 1 into %ir.scevgep, !tbaa !2)> t8:1, t8, t11, undef:i16</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t17: ch = TokenFactor t16, t12</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t19: ch = br t17, BasicBlock:ch<for.cond 0x10983ff38></b></span></div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">This is ok: </div><div class="">The array indexes get replaced by ‘add’ instructions (see t5 and t11) that later on can be folded into appropriate load/store addressing modes.</div><div class="">So far so good.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">However, if I replace the original code by this:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">char</span> *tst( <span style="color: #ba2da2" class="">char</span> *dest, <span style="color: #ba2da2" class="">const</span> <span style="color: #ba2da2" class="">char</span> *src, <span style="color: #ba2da2" class="">unsigned</span> <span style="color: #ba2da2" class="">int</span> len )</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class="">{</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""> <span style="color: #ba2da2" class="">if</span> ( dest ) {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""> <span style="color: #ba2da2" class="">for</span> (<span style="color: #ba2da2" class="">int</span> i=<span style="color: #272ad8" class="">0</span> ; i<len ; i++) {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""> dest[i] = src[i];</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""> }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""> }</div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255); min-height: 15px;" class=""> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);" class="">return<span style="color: #000000" class=""> dest;</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class="">}</div></div><div class=""><br class=""></div><div class="">I get IDENTICAL output from Clang for the ‘for’ body</div><div class=""><br class=""></div><div class="">But totally different code from llc:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Total amount of phi nodes to update: 0</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t2: i16,ch = CopyFromReg t0, Register:i16 %1</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating constant: t3: i16 = Constant<0></b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t4: i16 = undef</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t5: i8,ch = load<(load 1 from %ir.lsr.iv1, !tbaa !2)> t0, t2, undef:i16</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t7: i16,ch = CopyFromReg t0, Register:i16 %2</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t8: ch = store<(store 1 into %ir.lsr.iv, !tbaa !2)> t5:1, t5, t7, undef:i16</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating constant: t9: i16 = Constant<1></b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t10: i16 = add t7, Constant:i16<1></b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t12: ch = CopyToReg t0, Register:i16 %3, t10</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t13: i16 = add t2, Constant:i16<1></b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t15: ch = CopyToReg t0, Register:i16 %4, t13</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t17: i16,ch = CopyFromReg t0, Register:i16 %0</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating constant: t18: i16 = Constant<-1></b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t19: i16 = add t17, Constant:i16<-1></b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t21: ch = CopyToReg t0, Register:i16 %5, t19</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t22: ch = TokenFactor t12, t15, t21, t8</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Creating new node: t24: ch = br t22, BasicBlock:ch<for.cond 0x10985e000></b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">Initial selection DAG: %bb.3 'tst:for.body'</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">SelectionDAG has 25 nodes:</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t0: ch = EntryToken</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t2: i16,ch = CopyFromReg t0, Register:i16 %1</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t3: i16 = Constant<0></b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t5: i8,ch = load<(load 1 from %ir.lsr.iv1, !tbaa !2)> t0, t2, undef:i16</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t7: i16,ch = CopyFromReg t0, Register:i16 %2</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t10: i16 = add t7, Constant:i16<1></b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t12: ch = CopyToReg t0, Register:i16 %3, t10</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t13: i16 = add t2, Constant:i16<1></b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t15: ch = CopyToReg t0, Register:i16 %4, t13</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t17: i16,ch = CopyFromReg t0, Register:i16 %0</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t19: i16 = add t17, Constant:i16<-1></b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t21: ch = CopyToReg t0, Register:i16 %5, t19</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t8: ch = store<(store 1 into %ir.lsr.iv, !tbaa !2)> t5:1, t5, t7, undef:i16</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t22: ch = TokenFactor t12, t15, t21, t8</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> t24: ch = br t22, BasicBlock:ch<for.cond 0x10985e000></b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""></b></span><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div></div><div class="">Now, instead of using array indexes with ‘add’ instructions (which can be folded later on into load/store addressing modes), LLVM choses to directly increment the pointers!. This is suboptimal -at least on my architecture- because at this point it’s impossible to select optimal addressing modes. Instead, the pointers must be explicitly incremented with additional instructions as llvm dictates.</div><div class=""><br class=""></div><div class="">Any ideas about why this happens?. Particularly, what could cause this change of behaviour just by adding an ‘if’ before the ‘for’? Note that the IR code for the for ‘for’ body is IDENTICAL in both cases, so this is definitely a LLVM thing. </div><div class=""><br class=""></div><div class="">Joan Lluch</div><div class=""><br class=""></div><div class=""><br class=""></div></body></html>