<html dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style id="owaParaStyle" type="text/css">
<!--
p
{margin-top:0;
margin-bottom:0}
-->
P {margin-top:0;margin-bottom:0;}</style>
</head>
<body ocsi="0" fpstyle="1" style="word-wrap:break-word">
<div style="direction: ltr;font-family: Tahoma;color: #000000;font-size: 10pt;">Hi<br>
<br>
I've looked a bit more at the SelectionDAGBuilder.cpp and the use of AssertZext.<br>
<br>
The isZExtFree() is called by RegsForValue::getCopyToRegs().<br>
This correctly marks vreg as ZEXT when an unsigned 8 load.<br>
<br>
The function that adds the ISD::AssertZext is RegsForValue::getCopyFromRegs().<br>
It does this by checking the LOI->KnownZero.countLeadingOnes() for integer Vregs.<br>
Hence, the EXT type needs to be known (and it to be in GetLiveOutRegInfo?)<br>
<br>
If the vreg is a PHI node instruction, getCopyFromRegs() does not look at the possible originators.<br>
Is that because some originator vreg are in later BasicBlocks, so getCopyToRegs() has not yet been called and ZEXTed!<br>
Is there a mechanism for sharing this information across blocks?<br>
Is this the GetLiveOutRegInfo?...<br>
<br>
Attached is a patch to output the following debug:<br>
$ llc -march=xcore test.ll -o -<br>
getCopyToRegs ZERO_EXTEND: %.pre = load i8* %c, align 1<br>
getCopyFromRegs: %0 = phi i8 [ %.pre, %entry ], [ %1, %if.end ]<br>
%1 = load i8* %lsr.iv, align 1<br>
%.pre = load i8* %c, align 1<br>
did/will getCopyToRegs ZERO_EXTEND? Can we assume?<br>
getCopyToRegs ZERO_EXTEND: %1 = load i8* %lsr.iv, align 1<br>
<br>
I think I need to understand the intent of the code/data better before I can continue.<br>
Any explanations most welcome.<br>
<br>
Robert<br>
<br>
p.s. can someone explain the following:<br>
<pre class="fragment"><span class="comment">/// GetLiveOutRegInfo - Gets LiveOutInfo for a register, returning NULL if the</span>
<a name="l00165"></a><span class="comment">/// register is a PHI destination and the PHI's LiveOutInfo is not valid. If</span>
<a name="l00166"></a><span class="comment">/// the register's LiveOutInfo is for a smaller bit width, it is extended to</span>
<a name="l00167"></a><span class="comment">/// the larger bit width by zero extension. The bit width must be no smaller</span>
<a name="l00168"></a><span class="comment">/// than the LiveOutInfo's existing bit width.</span>
<br></pre>
<div style="font-family: Times New Roman; color: #000000; font-size: 16px">
<hr tabindex="-1">
<div style="direction: ltr;" id="divRpF652169"><font color="#000000" face="Tahoma" size="2"><b>From:</b> llvmdev-bounces@cs.uiuc.edu [llvmdev-bounces@cs.uiuc.edu] on behalf of Robert Lytton [robert@xmos.com]<br>
<b>Sent:</b> 11 September 2013 15:22<br>
<b>To:</b> Andrew Trick<br>
<b>Cc:</b> llvmdev@cs.uiuc.edu<br>
<b>Subject:</b> Re: [LLVMdev] removing unnecessary ZEXT<br>
</font><br>
</div>
<div></div>
<div>
<div style="direction:ltr; font-family:Tahoma; color:#000000; font-size:10pt">Hi Andrew,<br>
<br>
Thank you for the suggestion.<br>
I've looked at CodeGenPrepare.cpp and MoveExtToFormExtLoad() is never run.<br>
<br>
I also notice that the ARM target produces the same additional register usage (copy) and zero extending (of the copy).<br>
(See the usage of r3 &r5 and also r12 & r4 in attached file arm-strcspn.s, my understanding is that 'ldrb' is zero extending.)<br>
<br>
<br>
Here is a simplified example:<br>
void test(const char *c) {<br>
do {<br>
if (!*c) break;<br>
++c;<br>
} while (*c);<br>
}<br>
<br>
And in IR form:<br>
define void @test(i8* nocapture %c) {<br>
entry:<br>
%.pre = load i8* %c, align 1<br>
br label %do.body<br>
do.body:<br>
%0 = phi i8 [ %.pre, %entry ], [ %1, %if.end ]<br>
%c.addr.0 = phi i8* [ %c, %entry ], [ %incdec.ptr, %if.end ]<br>
%tobool = icmp eq i8 %0, 0<br>
br i1 %tobool, label %do.end, label %if.end<br>
if.end:<br>
%incdec.ptr = getelementptr inbounds i8* %c.addr.0, i64 1<br>
%1 = load i8* %incdec.ptr, align 1<br>
%tobool1 = icmp eq i8 %1, 0<br>
br i1 %tobool1, label %do.end, label %do.body<br>
do.end:<br>
ret void<br>
}<br>
<br>
<br>
The problem seems to be that an icmp becomes isolated in a different basic block to the originators of the vreg it uses viz:<br>
entry:<br>
%.pre = load i8* %c, align 1<br>
do.body:<br>
%0 = phi i8 [ %.pre, %entry ], [ %1, %if.end ]<br>
%tobool = icmp eq i8 %0, 0<br>
if.end:<br>
%1 = load i8* %incdec.ptr, align 1<br>
<br>
When a vreg is promoted during legalization, I assume there is knowledge that the top bits are zero.<br>
(assuming a ZEXTLOAD will be used - the only option for the xcore target)<br>
But when a vreg is subsequently truncated, can the top bits be known? viz:<br>
BB#1 'test:do.body'<br>
0x2c8d190: i32 = Register %vreg3<br>
0x2c8d590: i32,ch = CopyFromReg 0x2c5fcc0, 0x2c8d190 [ORD=4]<br>
0x2c8ce90: i8 = truncate 0x2c8d590 [ORD=4]<br>
0x2c8d990: i8 = Constant<0><br>
0x2c8d890: ch = seteq<br>
0x2c8d390: i1 = setcc 0x2c8ce90, 0x2c8d990, 0x2c8d890 [ORD=4]<br>
<br>
Is this what is happening?<br>
Can the Type-legalizer discover this information when lowering the truncate?<br>
Is the problem that this knowledge is not know in the DAG, only in the IR?<br>
<br>
Robert<br>
<br>
</div>
</div>
</div>
</div>
</body>
</html>