<div dir="auto"><div><div class="gmail_extra"><div class="gmail_quote">On 25 Aug 2017 10:27, "bluechristlove via cfe-dev" <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br type="attribution"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><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></div></blockquote></div></div></div><div dir="auto"><br></div><div dir="auto">1 || x is a constant expression.</div><div dir="auto">x || 1 is not.</div><div dir="auto">This is a property of the underlying programming language -- || short circuits. The user needs to understand that.</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div style="font-family:'PingFang SC';font-size:10.5pt"><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(<wbr>LHSResult.Val, lhsResult);</div><div>    bool RHSIsOK = HandleConversionToBool(<wbr>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">ConstantFoldsToSimple<wbr>Integer</span><span style="font-size:10.5pt">:</span></div><div><br></div><div><div>bool CodeGenFunction::<wbr>ConstantFoldsToSimpleInteger(<wbr>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<wbr>::</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(<wbr>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" style="font-family:Arial;font-size:10.5pt" target="_blank">https://bugs.llvm.org/show_<wbr>bug.cgi?id=34229</a></div><div><br></div><div>So, I think we should fix it. <br>
<div class="m_6466878450700435283yomail-sig" style="margin:0;padding:0"><div class="m_6466878450700435283yomail-sig" style="padding:0px 0px 0px 20px"><span> </span><div style="font-family:'PingFang SC';font-size:10.5pt"><br></div></div></div>
<br>
<div class="m_6466878450700435283-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><div class="elided-text">

        <blockquote style="margin:0">
                <div dir="ltr">
                        
<div>
<div> </div>
<blockquote type="cite">
<div>On Aug 21, 2017, at 12:28 AM, Frozen via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:</div>
<div>
<div style="line-height:1.7;font-size:14px;font-family:Arial">
<div>Simple Example:<br>
<br>
int main()</div>
<div>{</div>
<div>  int x;</div>
<div>  if (x || 1) {}</div>
<div>}</div>
<div><br></div>
<div>Clang can not evaluate this condition and will emit IR like this:</div>
<div><br></div>
<div>define signext i32 @main() #0 {</div>
<div>entry:</div>
<div>  %retval = alloca i32, align 4</div>
<div>  %x = alloca i32, align 4</div>
<div>  store i32 0, i32* %retval, align 4</div>
<div>  %0 = load i32, i32* %x, align 4</div>
<div>  %tobool = icmp ne i32 %0, 0</div>
<div>  br i1 %tobool, label %if.then, label %lor.lhs.false</div>
<div><br></div>
<div>lor.lhs.false:                                    ; preds = %entry</div>
<div>  br i1 true, label %if.then, label %if.end</div>
<div><br></div>
<div>if.then:                                          ; preds = %lor.lhs.false, %entry</div>
<div>  br label %if.end</div>
<div><br></div>
<div>if.end:                                           ; preds = %if.then, %lor.lhs.false</div>
<div>  %1 = load i32, i32* %retval, align 4</div>
<div>  ret i32 %1</div>
<div>}</div>
<div><br></div>
<div>However, when we swap the position of LHS and RHS(i.e. if (1 || x), Clang can recognize it:</div>
<div><br></div>
<div>define signext i32 @main() #0 {</div>
<div>entry:</div>
<div>  %x = alloca i32, align 4</div>
<div>  ret i32 0</div>
<div>}<br>
<br>
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" target="_blank">https://bugs.llvm.org/<wbr>show_bug.cgi?id=34229</a><br>
<br>
Any idea?<br>
</div>
</div>
</div>
</blockquote>
<div><br></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></div>
<div>John.</div>

                </div>
        </blockquote>
</div></div>
                        </div></div></div></div><br>______________________________<wbr>_________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-dev</a><br>
<br></blockquote></div><br></div></div></div>