<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body style='font-size: 10pt; font-family: Verdana,Geneva,sans-serif'>
<p>I wrote a pass in LLVM 3.5 and I'm trying to port it into LLVM 3.6.</p>
<p>Unfortunately, my pass replace the operand of some constants expressions using the function <strong>replaceUsesOfWithOnConstant(...)</strong> that have been modified in the 3.6 release...</p>
<p> </p>
<p>In both LLVM 3.5 and 3.6, the function <strong>ConstantExpr::replaceUsesOfWithOnConstant(...)</strong> receives 3 arguments : two <strong>Value</strong> and one <strong>Use</strong>.</p>
<p>In LLVM 3.5, the <strong>Use</strong> object was not really used. So, I could easily replace an operand in a constant expression by giving the old and the new <strong>Value</strong> as arguments with nullptr for <strong>Use</strong>.</p>
<blockquote type="cite" style="padding: 0 0.4em; border-left: #1010ff 2px solid; margin: 0">
<p>myConstExpr->replaceUsesOfWithOnConstant(oldOp, newOp, nullptr);</p>
</blockquote>
<p>Since LLVM 3.6, the <strong>Use</strong> object is used in a strange manner and the function <strong>getWithOperands</strong> (used inside <strong>replaceUsesOfWithOnConstant(..)</strong>) take a new boolean argument <strong>OnlyIfReduced</strong>. The documentation says:</p>
<blockquote type="cite" style="padding: 0 0.4em; border-left: #1010ff 2px solid; margin: 0">
<p>  /// If \c OnlyIfReduced is \c true, nullptr will be returned unless something<br />  /// gets constant-folded, the type changes, or the expression is otherwise<br />  /// canonicalized.  This parameter should almost always be \c false.</p>
</blockquote>
<p>Strangely, the <strong>OnlyIfReduced</strong> is set to <strong>true</strong> as you can see in the source code below. Most of time, in my case, the <strong>getWithOperands(...)</strong> will return nullptr because of this new argument (in LLVM 3.5, the old <strong>getWithOperands(...)</strong> did the job).</p>
<blockquote type="cite" style="padding: 0 0.4em; border-left: #1010ff 2px solid; margin: 0">
<p>  if (Constant *C = getWithOperands(NewOps, getType(), true)) {<br />    replaceUsesOfWithOnConstantImpl(C);<br />    return;<br />  }<br /><br />  // Update to the new value.<br />  if (Constant *C = getContext().pImpl->ExprConstants.replaceOperandsInPlace(<br />          NewOps, this, From, To, NumUpdated, U - OperandList))<br />    replaceUsesOfWithOnConstantImpl(C);</p>
</blockquote>
<p>Because it return nullptr, the new function <strong><span style="font-family: courier new,courier;">replaceOperandsInPlace(...)</span></strong> should do the job instead. Unfortunately, there's an "optimization" inside <strong>replaceOperandsInPlace(...)</strong> :</p>
<blockquote type="cite" style="padding: 0 0.4em; border-left: #1010ff 2px solid; margin: 0">
<p>  // Update to the new value.  Optimize for the case when we have a single<br />  // operand that we're changing, but handle bulk updates efficiently.</p>
<p>    remove(CP);<br />    if (NumUpdated == 1) {<br />      assert(OperandNo < CP->getNumOperands() && "Invalid index");<br />      assert(CP->getOperand(OperandNo) != To && "I didn't contain From!");<br />      CP->setOperand(OperandNo, To);<br />    } else {<br />      for (unsigned I = 0, E = CP->getNumOperands(); I != E; ++I)<br />        if (CP->getOperand(I) == From)<br />          CP->setOperand(I, To);<br />    }</p>
</blockquote>
<p>Normally, the loop inside the else branch should work (iterate over the operands and change the old ones by the new ones) but when you have <strong>NumUpdated</strong> equal to 1 (means there's only one operand to change), it actually use the <strong>Use</strong> object to identify the operand number to change (????)...</p>
<p> </p>
<p>From my point of view, this behavior is not very logical...</p>
<p> </p>
<p>I see two differents situations:</p>
<ol>
<li>One want to replace an operand by another one in a constant expression. We don't know how many operands are used by the constant expression nor the opcode of this constant expression. So, we call <strong>replaceUsesOfWithOnConstant(...)</strong> without <strong>Use</strong> (should be a default argument <strong>Use</strong>=nullptr) and the function should do the job (iterate over the operands, identify those that need to be replaced and replace them). If the replacement does not include a constant-folding/type change/canonicalized, the function <strong>replaceOperandsInPlace(...)</strong> is called and the modifications are done in place.</li>
<li>One want to replace only one operand by another one in a constant expression. We identified the correct operand so we know in advance the <strong>Use</strong> object linked to the operand and the constant expression. In that case, we call <strong>replaceUsesOfWithOnConstant</strong> with the <strong>Use</strong> object and the function should use the "optimization" inside <strong>replaceOperandsInPlace(...)</strong> to avoid doing an unnecessary loop.</li>
</ol>
<p>Furthemore, the function <strong>replaceOperandsInPlace(...)</strong> have defaults arguments for <strong>NumUpdated</strong>=0 and <strong>OperandNo</strong>=0 that means it can be <span id="result_box" class="short_text"><span class="hps">explicitly</span></span> called to avoid the "optimization" trick.</p>
<p> </p>
<p>Maybe I'm wrong, but for me this implementation seems more correct:</p>
<p> </p>
<p>Source Code</p>
<blockquote type="cite" style="padding: 0 0.4em; border-left: #1010ff 2px solid; margin: 0">
<p><span style="font-family: courier new,courier;">   void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,</span><br /><span style="font-family: courier new,courier;">-                                                 Use *U) {</span><br /><span style="font-family: courier new,courier;">+                                                 Use *U = nullptr) {</span><br /><span style="font-family: courier new,courier;">     assert(isa<Constant>(ToV) && "Cannot make Constant refer to non-constant!");</span><br /><span style="font-family: courier new,courier;">     Constant *To = cast<Constant>(ToV);</span><br /><span style="font-family: courier new,courier;">   </span><br /><span style="font-family: courier new,courier;">     SmallVector<Constant*, 8> NewOps;</span><br /><span style="font-family: courier new,courier;">     unsigned NumUpdated = 0;</span><br /><span style="font-family: courier new,courier;">     for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {</span><br /><span style="font-family: courier new,courier;">       Constant *Op = getOperand(i);</span><br /><span style="font-family: courier new,courier;">       if (Op == From) {</span><br /><span style="font-family: courier new,courier;">         ++NumUpdated;</span><br /><span style="font-family: courier new,courier;">         Op = To;</span><br /><span style="font-family: courier new,courier;">       }</span><br /><span style="font-family: courier new,courier;">       NewOps.push_back(Op);</span><br /><span style="font-family: courier new,courier;">     }</span><br /><span style="font-family: courier new,courier;">     assert(NumUpdated && "I didn't contain From!");</span></p>
<p><span style="font-family: courier new,courier;">   </span><br /><span style="font-family: courier new,courier;">     if (Constant *C = getWithOperands(NewOps, getType(), true)) {</span><br /><span style="font-family: courier new,courier;">       replaceUsesOfWithOnConstantImpl(C);</span><br /><span style="font-family: courier new,courier;">       return;</span><br /><span style="font-family: courier new,courier;">     }</span><br /><span style="font-family: courier new,courier;">   </span><br /><span style="font-family: courier new,courier;">+    if (U == nullptr) </span><span style="font-family: courier new,courier;">{</span><br /><span style="font-family: courier new,courier;">+      NumUpdated = 0;</span><br /><span style="font-family: courier new,courier;">+      U = OperandList;</span><br /><span style="font-family: courier new,courier;">+    }</span><br /><br /><span style="font-family: courier new,courier;">     // Update to the new value.</span><br /><span style="font-family: courier new,courier;">     if (Constant *C = getContext().pImpl->ExprConstants.replaceOperandsInPlace(</span><br /><span style="font-family: courier new,courier;">             NewOps, this, From, To, NumUpdated, U - OperandList))</span><br /><span style="font-family: courier new,courier;">       replaceUsesOfWithOnConstantImpl(C);</span><br /><span style="font-family: courier new,courier;">   }</span></p>
</blockquote>
<div> </div>
</body></html>