<body><div style="font-family: 'PingFang SC'; font-size: 10.5pt;">
This is not specific example. If we don’t fix it, user will feel strange why LHS of if stmt condition could do constant folding but RHS couldn’t.<div><br></div><div>From the source code view’s point, this is our compiler bug. </div><div><br></div><div>In the ExprConstant.cpp:</div><div><br></div><div><div> case Job::BinOpKind: {</div><div> ...</div><div> if (!VisitBinOpLHSOnly(Result, Bop, SuppressRHSDiags)) {</div><div> Queue.pop_back();</div><div> return;</div><div> }</div><div> ...</div><div> job.Kind = Job::BinOpVisitedLHSKind;</div><div> enqueue(Bop->getRHS());</div><div> return;</div><div> }</div><div> </div><div> case Job::BinOpVisitedLHSKind: {</div><div> ...</div><div> Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);</div><div> Queue.pop_back();</div><div> return;</div><div> }</div><div><br></div><div>If we can not evaluate LHS successfully, we will evaluate RHS (function VisitBinOp). In the function VisitBinOp:</div><div><br></div><div><div> if (E->isLogicalOp()) {</div><div> bool lhsResult, rhsResult;</div><div> bool LHSIsOK = HandleConversionToBool(LHSResult.Val, lhsResult);</div><div> bool RHSIsOK = HandleConversionToBool(RHSResult.Val, rhsResult);</div><div> if (LHSIsOK) {</div><div> if (RHSIsOK) {</div><div> if (E->getOpcode() == BO_LOr)</div><div> return Success(lhsResult || rhsResult, E, Result);</div><div> else</div><div> return Success(lhsResult && rhsResult, E, Result);</div><div> }</div><div> } else {</div><div> if (RHSIsOK) {</div><div><b> // We can't evaluate the LHS; however, sometimes the result</b></div><div><b> // is determined by the RHS: X && 0 -> 0, X || 1 -> 1.</b></div><div> if (rhsResult == (E->getOpcode() == BO_LOr)) {</div><div> return Success(rhsResult, E, Result);</div><div> }</div><div> }</div><div> }</div></div><div><br></div><div>We can see that our previous implementation has consider this condition of RHS constant folding. But because of ignore the parameter Expr::SE_AllowSideEffects in the function <span style="font-size: 10.5pt;">ConstantFoldsToSimpleInteger</span><span style="font-size: 10.5pt;">:</span></div><div><br></div><div><div>bool CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond,</div><div> llvm::APSInt &ResultInt,</div><div> bool AllowLabels) {</div><div> // FIXME: Rename and handle conversion of other evaluatable things</div><div> // to bool.</div><div> llvm::APSInt Int;</div><div> if (!Cond->EvaluateAsInt(Int, getContext(), <b>Expr::SE_AllowSideEffects)</b>) -------> allow side effect</div><div> return false; // Not foldable, not integer or not fully evaluatable.</div></div><div><br></div><div>We will not make the RHS constant folding happened.</div><div><br></div><div><div>bool DataRecursiveIntBinOpEvaluator::</div><div> VisitBinOpLHSOnly(EvalResult &LHSResult, const BinaryOperator *E,</div><div> bool &SuppressRHSDiags) {</div><div>….</div><div><br></div><div> if (E->isLogicalOp()) {</div><div> bool LHSAsBool;</div><div><span style="font-size: 10.5pt;"> E->getLHS()->dumpColor();</span></div><div> if (!LHSResult.Failed && HandleConversionToBool(LHSResult.Val, LHSAsBool)) {</div><div> // We were able to evaluate the LHS, see if we can get away with not</div><div> // evaluating the RHS: 0 && X -> 0, 1 || X -> 1</div><div> if (LHSAsBool == (E->getOpcode() == BO_LOr)) {</div><div> Success(LHSAsBool, E, LHSResult.Val);</div><div> return false; // Ignore RHS</div><div> }</div><div> } else {</div><div> LHSResult.Failed = true;</div><div><br></div><div> // Since we weren't able to evaluate the left hand side, it</div><div> // might have had side effects.</div><div><b> if (!Info.noteSideEffect()) { --------> HERE!!!</b></div><div> return false;</div><div> }</div></div><div>The detail source code analysis could be find in the comment 2 of <a href="https://bugs.llvm.org/show_bug.cgi?id=34229" class="" style="font-family: Arial; font-size: 10.5pt;">https://bugs.llvm.org/show_bug.cgi?id=34229</a></div><div><br></div><div>So, I think we should fix it. <br>
<div class="yomail-sig" style="margin:0;padding:0;"><div class="yomail-sig" style="padding: 0px 0px 0px 20px; margin: 0px 0px 0px -20px;"><span> </span><div style="font-family: 'PingFang SC'; font-size: 10.5pt;"><br></div></div></div>
<br>
<div class="-eMc-quote" style="margin: 0px 0px 0px 0.8ex; display: block;">
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<div style="PADDING-RIGHT: 8px; PADDING-LEFT: 8px; FONT-SIZE: 12px;COLOR:#000000; BACKGROUND: #efefef; PADDING-BOTTOM: 8px; PADDING-TOP: 8px">
<div>
<b>发件人:</b> <a href="mailto:rjmccall@apple.com" target="_blank">John McCall</a>
</div>
<div>
<b>发送时间:</b> 2017-08-23 01:30:45
</div>
<div>
<b>收件人:</b>
<a href="mailto:bluechristlove@163.com" target="_blank">Frozen</a>
</div>
<div>
<b>抄送:</b>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>
</div>
<div>
<b>主题:</b> Re: [cfe-dev] Evaluate constant condition of if statement has no effect
</div>
</div>
</div>
<blockquote style="margin:0;">
<div dir="ltr">
<div>
<div onclick="emc_toggle_blockquote_visibility(this);"> </div>
<blockquote type="cite" class="">
<div class="">On Aug 21, 2017, at 12:28 AM, Frozen via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a>> wrote:</div>
<div class="">
<div style="line-height: 1.7; font-size: 14px; font-family: Arial;" class="">
<div class="">Simple Example:<br class="">
<br class="">
int main()</div>
<div class="">{</div>
<div class=""> int x;</div>
<div class=""> if (x || 1) {}</div>
<div class="">}</div>
<div class=""><br class=""></div>
<div class="">Clang can not evaluate this condition and will emit IR like this:</div>
<div class=""><br class=""></div>
<div class="">define signext i32 @main() #0 {</div>
<div class="">entry:</div>
<div class=""> %retval = alloca i32, align 4</div>
<div class=""> %x = alloca i32, align 4</div>
<div class=""> store i32 0, i32* %retval, align 4</div>
<div class=""> %0 = load i32, i32* %x, align 4</div>
<div class=""> %tobool = icmp ne i32 %0, 0</div>
<div class=""> br i1 %tobool, label %if.then, label %lor.lhs.false</div>
<div class=""><br class=""></div>
<div class="">lor.lhs.false: ; preds = %entry</div>
<div class=""> br i1 true, label %if.then, label %if.end</div>
<div class=""><br class=""></div>
<div class="">if.then: ; preds = %lor.lhs.false, %entry</div>
<div class=""> br label %if.end</div>
<div class=""><br class=""></div>
<div class="">if.end: ; preds = %if.then, %lor.lhs.false</div>
<div class=""> %1 = load i32, i32* %retval, align 4</div>
<div class=""> ret i32 %1</div>
<div class="">}</div>
<div class=""><br class=""></div>
<div class="">However, when we swap the position of LHS and RHS(i.e. if (1 || x), Clang can recognize it:</div>
<div class=""><br class=""></div>
<div class="">define signext i32 @main() #0 {</div>
<div class="">entry:</div>
<div class=""> %x = alloca i32, align 4</div>
<div class=""> ret i32 0</div>
<div class="">}<br class="">
<br class="">
I also find the root issue and propose one potential solution in comment 2 of this link: <a href="https://bugs.llvm.org/show_bug.cgi?id=34229" class="">https://bugs.llvm.org/show_bug.cgi?id=34229</a><br class="">
<br class="">
Any idea?<br class="">
</div>
</div>
</div>
</blockquote>
<div><br class=""></div>
There will always be some example of something that we generate less efficiently at -O0 than we could. Why is this example specifically worth optimizing?</div>
<div><br class=""></div>
<div>John.</div>
</div>
</blockquote>
</div>
</div></div></div></body>