<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="">Hi Markus,<div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Aug 28, 2014, at 9:57 AM, Markus Timpl <<a href="mailto:tima0900@googlemail.com" class="">tima0900@googlemail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="">Hi all,</div><div class="">I'm trying to figure out why llvm(llvm 3.1, can't easilly try it with other version) inserts an unnecessary load for one register.</div><div class=""> </div><div class="">The following is the code before instruction selection:</div>
<div class="">----------------------------------------------------------------------------</div><div class=""> %call = tail call i32 @_Z7zahlIntv()<br class=""> %0 = inttoptr i32 %call to i32*<br class=""> %1 = load i32* %0, align 4, !tbaa !0<br class=""> %arrayidx1 = getelementptr inbounds i32* %0, i32 1<br class="">
%2 = load i32* %arrayidx1, align 4, !tbaa !0<br class=""> %mul = mul nsw i32 %2, %1<br class=""> ret i32 %mul</div><div class="">----------------------------------------------------------------------------</div><div class=""> </div><div class="">After instruction selection I get the following:</div>
<div class=""> </div><div class="">----------------------------------------------------------------------------<br class=""> BB#0: derived from LLVM BB %entry<br class=""> ADJCALLSTACKDOWN 8, %SP<imp-def,dead>, %SP<imp-use><br class=""> JSUB <ga:@_Z7zahlIntv>, 1, <fi#-2>, 0, <fi#0>, 0, ...<br class="">
ADJCALLSTACKUP 8, 0, %SP<imp-def,dead>, %SP<imp-use><br class=""> %vreg0<def> = LDrid <fi#-2>, 4; mem:LD4[FixedStack-2] AkkuDRegs:%vreg0<br class=""> %vreg2<def> = COPY %vreg0; PointerAdrRegs:%vreg2 AkkuDRegs:%vreg0<br class="">
%vreg1<def> = LDridAddr %vreg2, 4; mem:LD4[%arrayidx1](tbaa=!"int") AkkuDRegs:%vreg1 PointerAdrRegs:%vreg2<br class=""> %vreg4<def> = COPY %vreg0; PointerAdrRegs:%vreg4 AkkuDRegs:%vreg0<br class=""> %vreg3<def> = MULINTDLDridAddr %vreg1<kill>, %vreg4, 0; mem:LD4[%0](tbaa=!"int") AkkuDRegs:%vreg3,%vreg1 PointerAdrRegs:%vreg4</div>
<div class=""> STrid <fi#-, 0, %vreg3<kill>; mem:ST4[FixedStack-1] AkkuDRegs:%vreg3<br class="">----------------------------------------------------------------------------</div><div class=""> </div><div class="">So far everything seems to look fine. But I don't understand why there is a %vreg4 as it has the same value as %vreg2.</div></div></div></blockquote><div><br class=""></div><div>I’d suggest that you check how the lowering is actually done for your target to end up with those two copies of the same value.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class="">
<div class=""> </div><div class="">At the end I get the following:</div><div class=""> </div><div class="">----------------------------------------------------------------------------<br class=""> JSUB <ga:@_Z7zahlIntv>, 1, %SP, 24, %SP, 0, %AKKU1D<imp-def,dead>, %AR2<imp-def,dead><br class="">
%AKKU1D<def> = LDrid %SP, 28; mem:LD4[FixedStack-2]<br class=""> STrid %SP, 8, %AKKU1D<kill><br class=""> %AKKU1D<def> = LDrid %SP, 8<br class=""> %AR2<def> = LAR2d %AKKU1D<kill><br class=""> %AKKU1D<def> = LDridAddr %AR2<kill>, 4; mem:LD4[%arrayidx1](tbaa=!"int")<br class="">
STrid %SP, 12, %AKKU1D<kill><br class=""> %AKKU1D<def> = LDrid %SP, 8<br class=""> %AR2<def> = LAR2d %AKKU1D<kill><br class=""> %AKKU1D<def> = LDrid %SP, 12<br class=""> %AKKU1D<def> = MULINTDLDridAddr %AKKU1D<kill>, %AR2<kill>, 0; mem:LD4[%0](tbaa=!"int")<br class="">
STrid %SP, 0, %AKKU1D<kill>; mem:ST4[FixedStack-1]<br class="">----------------------------------------------------------------------------</div><div class=""> </div><div class="">It should be obvious that the second " %AR2<def> = LAR2d %AKKU1D<kill>" is unneccessary. I've no idea why llvm thinks it needs to fill the register with the prober value again.</div></div></div></blockquote><div><br class=""></div><div>The thing is that llvm does not keep track of the values. It sees three virtual registers: vreg0, vreg2, and vreg4 and the only thing special about them is that vreg0 and vreg2 are copy-related, same for vreg4 and vreg0. Other than with the register coalescer, these values are not attempted to be merged. Perhaps you could check the output of the register coalescer to see why it is not merging them (-debug-only regalloc), though I suspect that it is because PointerAdrRegs and AkkuDRegs are not coalescable.</div><div>If that is the case, we do have an optimization in the peephole optimizer that rewrites the COPYs to avoid cross register file copies. It wouldn’t catch this case[1], but it is possible to teach it.</div><div><br class=""></div><div>Another option would be to check why MachineCSE does not catch this.</div><div><br class=""></div><div>Anyway, the best way to avoid these redundant copies is not to emit them in the first place :).</div><div><br class=""></div><div>[1] The copy rewriting works bottom-up:</div><div>A = b</div><div>c = A</div><div>=></div><div>A = b</div><div>c = b</div><div>but what you want here is a bit different (you look for all the alternative sources):</div><div>A = b</div><div>C= b</div><div>=></div><div>A = b</div><div>C = A</div><div>Note: Uppercase and lowercase registers are in different register file.</div><div><br class=""></div><div>Thanks,</div><div>-Quentin</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">No instruction in the whole block is destroying the value in AR2. Might it be because %AR2 is marked kill in the LDridAddr instruction? If so, how can I mark the instruction that it isn't destroying the register value? The following is the definition of the instruction:</div>
<div class=""> </div><div class="">----------------------------------------------------------------------------</div><div class=""><font face="Consolas" class=""><font face="Consolas" class=""><p class="">def MEMirPtr : Operand<i32> {</p><p class=""> let PrintMethod = "printMemOperand";</p><p class=""> let MIOperandInfo = (ops PointerAdrRegs, i64imm);</p><p class="">}</p><font face="Consolas" class=""><font face="Consolas" class=""><p class="">class AwlInst<dag outs, dag ins, string asmstr, list<dag> pattern, int size = 0> : Instruction {</p><div class="">
<br class="webkit-block-placeholder"></div><p class=""> field bits<32> Inst;</p><div class="">
<br class="webkit-block-placeholder"></div><p class=""> let Namespace = "Awl0";</p><div class="">
<br class="webkit-block-placeholder"></div><p class=""> dag OutOperandList = outs;</p><div class="">
<br class="webkit-block-placeholder"></div><p class=""> dag InOperandList = ins;</p><div class="">
<br class="webkit-block-placeholder"></div><p class=""> let AsmString = asmstr;</p><div class="">
<br class="webkit-block-placeholder"></div><p class=""> let Pattern = pattern;</p><div class="">
<br class="webkit-block-placeholder"></div><p class=""> let Size = size;</p><div class="">
<br class="webkit-block-placeholder"></div><p class="">}</p></font></font><div class=""> <br class="webkit-block-placeholder"></div></font></font></div><div class=""><font face="Consolas" class=""><font face="Consolas" class=""><p class=""> def LDridAddr : AwlInst<(outs AkkuDRegs:$dst), (ins MEMirPtr:$addr),</p><p class=""> "L D$addr; \t// LDridAddr $addr -> $dst",</p><p class=""> [(set AkkuDRegs:$dst, (load addraddr:$addr))], 4>;</p><p class="">----------------------------------------------------------------------------</p><div class=""> <br class="webkit-block-placeholder"></div><div class=""> <br class="webkit-block-placeholder"></div><p class="">The complete output of print-after-all is attached to this mail.</p><p class="">Any hints are appreciated.</p><p class="">Thanks in advance,</p><p class="">Markus</p></font></font></div></div>
<span id="cid:AC986A0C-1DE6-4C00-974D-2590B0068F77"><printafterallOutput.txt></span>_______________________________________________<br class="">LLVM Developers mailing list<br class=""><a href="mailto:LLVMdev@cs.uiuc.edu" class="">LLVMdev@cs.uiuc.edu</a> <a href="http://llvm.cs.uiuc.edu" class="">http://llvm.cs.uiuc.edu</a><br class=""><a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" class="">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br class=""></div></blockquote></div><br class=""></div></body></html>