I traced the compilation, and found that CheckedAddINode::match() was never called before hitting the assert.<div>The available rules for Proj #1 (the conditions projection) doesn&#39;t look right in the output log, does it?<br>
<div><br></div><div>- Kris<br><br><div class="gmail_quote">On Thu, Jun 21, 2012 at 8:28 AM, Krystal Mok <span dir="ltr">&lt;<a href="mailto:rednaxelafx@gmail.com" target="_blank">rednaxelafx@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_quote"><div class="im">On Thu, Jun 21, 2012 at 8:03 AM, Vladimir Kozlov <span dir="ltr">&lt;<a href="mailto:vladimir.kozlov@oracle.com" target="_blank">vladimir.kozlov@oracle.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>Krystal Mok wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Thanks for the reply! Comments inline below:<br>
<br>
On 2012-6-21, at 6:13, Vladimir Kozlov &lt;<a href="mailto:vladimir.kozlov@oracle.com" target="_blank">vladimir.kozlov@oracle.com</a>&gt; wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Look on output before assert message. It should have problematic ideal subgraph dump which it can&#39;t match.<br>
<br>
</blockquote>
The output is:<br>
</blockquote>
<br></div>
You did not send output.<div><br></div></blockquote></div><div>Oops, I hit the send button too early ...</div><div><br></div><div>Here&#39;s the output:</div><div><br></div><div><div><font face="&#39;courier new&#39;, monospace">o30<span style="white-space:pre-wrap">        </span>If<span style="white-space:pre-wrap">        </span>=== o5 o46 o45  [[o31 o32  6 ]] P=0.000001, C=-1.000000</font></div>

<div><font face="&#39;courier new&#39;, monospace"><br></font></div><div><font face="&#39;courier new&#39;, monospace">--N: o30<span style="white-space:pre-wrap">        </span>If<span style="white-space:pre-wrap">        </span>=== o5 o46 o45  [[o31 o32  6 ]] P=0.000001, C=-1.000000</font></div>

<div><font face="&#39;courier new&#39;, monospace"><br></font></div><div><font face="&#39;courier new&#39;, monospace">   --N: o46<span style="white-space:pre-wrap">        </span>Bool<span style="white-space:pre-wrap">        </span>=== _ o45  [[o30 ]] [??]</font></div>

<div><font face="&#39;courier new&#39;, monospace">   CMPOP  0  CMPOP</font></div><div><font face="&#39;courier new&#39;, monospace">   CMPOPU  0  CMPOPU</font></div><div><font face="&#39;courier new&#39;, monospace"><br>

</font></div><div><font face="&#39;courier new&#39;, monospace">   --N: o45<span style="white-space:pre-wrap">        </span>Proj<span style="white-space:pre-wrap">        </span>=== o43  [[o46 o30 ]] #1</font></div>
<div><font face="&#39;courier new&#39;, monospace">   RREGI  0  RREGI</font></div><div><font face="&#39;courier new&#39;, monospace">   RAX_REGI  0  RAX_REGI</font></div><div><font face="&#39;courier new&#39;, monospace">   RBX_REGI  0  RBX_REGI</font></div>

<div><font face="&#39;courier new&#39;, monospace">   RCX_REGI  0  RCX_REGI</font></div><div><font face="&#39;courier new&#39;, monospace">   RDX_REGI  0  RDX_REGI</font></div><div><font face="&#39;courier new&#39;, monospace">   RDI_REGI  0  RDI_REGI</font></div>

<div><font face="&#39;courier new&#39;, monospace">   NO_RCX_REGI  0  NO_RCX_REGI</font></div><div><font face="&#39;courier new&#39;, monospace">   NO_RAX_RDX_REGI  0  NO_RAX_RDX_REGI</font></div><div><font face="&#39;courier new&#39;, monospace">   STACKSLOTI  100  storeSSI</font></div>

</div><div class="im"><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I think the problem is that you have Proj node in between If and CheckedAddI nodes so that it can&#39;t match &#39;If&#39; node since it looks for inputs which produce flags (cr). May be CheckedAddINode::match() is not enough.<br>


<br>
</blockquote>
You&#39;re right, that&#39;s exactly what&#39;s happening.<br></blockquote></div></blockquote><div><br></div></div><div>One more question on this one: how does the matcher know that the data projection should be in the same location as the dst input? There&#39;s nowhere to specify it.</div>
<div class="im">
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Also you can&#39;t use EMPTY mask for data result projection. Bind it to an register as DivMod node.<br>
<br>
</blockquote></blockquote>
<br></div>
Mask should reflect in what registers could be result. You don&#39;t need to bind to specific register but you need to return non-empty mask, for example, INT_REG_mask(). And for flag projection you need INT_FLAGS_mask().</blockquote>

<div><br></div></div><div>Ahh, so the register class declaration for RFLAGS moved to <a href="http://x86.ad" target="_blank">x86.ad</a> ... no wonder I couldn&#39;t find it when I searched <a href="http://x86_64.ad" target="_blank">x86_64.ad</a>.</div>
<div><br>
</div><div>I&#39;m still getting the same crash after I changed CheckedAddINode::match() to this:</div><div><br></div><div><div><font face="&#39;courier new&#39;, monospace">Node* CheckedAddINode::match(const ProjNode* proj, const Matcher* match) {</font></div>

<div><font face="&#39;courier new&#39;, monospace">  uint ideal_reg = proj-&gt;ideal_reg();</font></div><div><font face="&#39;courier new&#39;, monospace">  RegMask rm = RegMask::Empty;</font></div><div><font face="&#39;courier new&#39;, monospace">  if (proj-&gt;_con == sum_proj_num) {</font></div>

<div><font face="&#39;courier new&#39;, monospace">    rm = match-&gt;checkedAddI_sum_proj_mask();</font></div><div><font face="&#39;courier new&#39;, monospace">  } else {</font></div><div><font face="&#39;courier new&#39;, monospace">    assert(proj-&gt;_con == overflow_proj_num, &quot;must be sum or overflow projection&quot;);</font></div>

<div><font face="&#39;courier new&#39;, monospace">    ideal_reg = Op_RegFlags;</font></div><div><font face="&#39;courier new&#39;, monospace">    rm = match-&gt;overflow_proj_mask();</font></div><div><font face="&#39;courier new&#39;, monospace">  }</font></div>

<div><font face="&#39;courier new&#39;, monospace">  return new (match-&gt;C, 1) MachProjNode(this, proj-&gt;_con, rm, ideal_reg);</font></div><div><font face="&#39;courier new&#39;, monospace">}</font></div></div><div><br>

</div><div>Where both RegMasks specified as suggested above. The output log is still the same.</div><div><br></div><div>Thanks,</div><div>Kris</div><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<span><font color="#888888"><br>
<br>
Vladimir</font></span><div><div><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
But in the DivMod case, both data projections had to be in fixed registers because that&#39;s required by idiv, where as here binding the sum projection to a fixed register (e.g. rax) would be less optimal, right?<br>
<br>
If only there&#39;s a way to express the (Set dest ...) semantic for CheckedAddI&#39;s data projection ...<br>
<br>
Anyway, binding it fixed should at least get the example running. I&#39;ll try this first and look for alternative solutions later.<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
And use masm instructions encoding<br>
<br>
 ins_encode %{<br>
   __ addl($dst$$Register, $src$$Register);<br>
 %}<br>
<br>
instead of<br>
<br>
  ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));<br>
<br>
</blockquote>
Will fix this one. I just copied the code from the basic instruct for AddI, which is still using the old ins_encode form.<br>
<br>
Thanks,<br>
Kris<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Vladimir<br>
<br>
Krystal Mok wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Thank you for all your input, John and Vladimir!<br>
I&#39;m close to getting some prototype that could actually run...but not there just yet.<br>
I&#39;ve got Match.addExact(int, int) compiled down to this graph:<br>
<a href="http://dl.iteye.com/upload/picture/pic/114582/cc7535db-20d8-3e5d-9abd-b96456c7166c.png" target="_blank">http://dl.iteye.com/upload/<u></u>picture/pic/114582/cc7535db-<u></u>20d8-3e5d-9abd-b96456c7166c.<u></u>png</a><br>


with the CheckedAddI node resembling the way DivModI works.<br>
But apparently I&#39;m not getting the Matcher part right yet. I&#39;m getting this error message:<br>
#  Internal Error (/home/sajia/temp/hotspot-<u></u>comp/src/share/vm/opto/<u></u>matcher.cpp:1564), pid=16856, tid=1117243712<br>
#  assert(false) failed: bad AD file<br>
from this stack trace:<br>
V  [libjvm.so+0xb10bea]  VMError::report(outputStream*)<u></u>+0xfa4<br>
V  [libjvm.so+0xb11f77]  VMError::report_and_die()+<u></u>0x649<br>
V  [libjvm.so+0x59e706]  report_vm_error(char const*, int, char const*, char const*)+0x9c<br>
V  [libjvm.so+0x8d4af0]  Matcher::Label_Root(Node const*, State*, Node*, Node const*)+0x48c<br>
V  [libjvm.so+0x8d4d0f]  Matcher::match_tree(Node const*)+0x205<br>
V  [libjvm.so+0x8d6397]  Matcher::xform(Node*, int)+0x16d<br>
V  [libjvm.so+0x8d9ea2]  Matcher::match()+0xb0e<br>
V  [libjvm.so+0x52e20f]  Compile::Code_Gen()+0x91<br>
V  [libjvm.so+0x537678]  Compile::Compile(ciEnv*, C2Compiler*, ciMethod*, int, bool, bool)+0x101e<br>
V  [libjvm.so+0x47aa8c]  C2Compiler::compile_method(<u></u>ciEnv*, ciMethod*, int)+0xea<br>
V  [libjvm.so+0x53e552]  CompileBroker::invoke_<u></u>compiler_on_method(<u></u>CompileTask*)+0x332<br>
V  [libjvm.so+0x540f10]  CompileBroker::compiler_<u></u>thread_loop()+0x2fa<br>
V  [libjvm.so+0xabed88]  compiler_thread_entry(<u></u>JavaThread*, Thread*)+0x54<br>
V  [libjvm.so+0xac288c]  JavaThread::thread_main_inner(<u></u>)+0x102<br>
V  [libjvm.so+0xac4f0b]  JavaThread::run()+0xef<br>
V  [libjvm.so+0x979557]  java_start(Thread*)+0x16f<br>
The current status of the patch is avaiable here:<br>
<a href="https://gist.github.com/05f6f33cb01c7f5aedf3" target="_blank">https://gist.github.com/<u></u>05f6f33cb01c7f5aedf3</a><br>
I haven&#39;t done a full-fledged intrinsic for Math.addExact(int, int) yet; just as a prototype, I&#39;m faking the use of CmpAddI node right now. At the end of Optimize(), I pattern match for the overflow checking logic, replace it with a new fake CmpAddI node, then make the actual CheckedAddI node from the CmpAddI, finally replace the old AddI and Bool nodes.<br>


Most of the changes besides the new nodes are for adding the overflow/no-overflow conditions to BoolTest and cmpOp.<br>
If there were separate AddI and CmpAddI nodes, they would have had a (Set dst ...) and (Set cr ...) in their match rule. But I can&#39;t see how I can express it here.<br>
Regards,<br>
Kris<br>
</blockquote></blockquote></blockquote>
</div></div></blockquote></div></div></div><br>
</blockquote></div><br></div></div>