<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style>
</head>
<body lang="EN-US" link="#0563C1" vlink="#954F72" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal">Hi folks,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Our project is using ValueTracking's computeConstantRange() to refine loop bounds, and we're seeing some surprising behavior when llvm.assume is put in the mix.<o:p></o:p></p>
<p class="MsoNormal">Here's an example (which can be copied into ValueTrackingTest.cpp and executed):<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">  {<o:p></o:p></p>
<p class="MsoNormal">    // Assumptions:<o:p></o:p></p>
<p class="MsoNormal">    //  * x.2 < x.1<o:p></o:p></p>
<p class="MsoNormal">    // (x.1 is unknown [full-set])<o:p></o:p></p>
<p class="MsoNormal">    auto M = parseModule(R"(<o:p></o:p></p>
<p class="MsoNormal">  declare void @llvm.assume(i1)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">  define i32 @test(i32 %x.1, i32 %x.2) {<o:p></o:p></p>
<p class="MsoNormal">    %lt = icmp ule i32 %x.2, %x.1<o:p></o:p></p>
<p class="MsoNormal">    call void @llvm.assume(i1 %lt)<o:p></o:p></p>
<p class="MsoNormal">    %stride.plus.one = add nsw nuw i32 %x.1, 1<o:p></o:p></p>
<p class="MsoNormal">    ret i32 %stride.plus.one<o:p></o:p></p>
<p class="MsoNormal">  })");<o:p></o:p></p>
<p class="MsoNormal">    Function *F = M->getFunction("test");<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">    AssumptionCache AC(*F);<o:p></o:p></p>
<p class="MsoNormal">    Value *X2 = &*std::next(F->arg_begin());<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">    Instruction *I = &findInstructionByName(F, "stride.plus.one");<o:p></o:p></p>
<p class="MsoNormal">    ConstantRange CR1 = computeConstantRange(X2, true, &AC, I);<o:p></o:p></p>
<p class="MsoNormal">    EXPECT_EQ(0, CR1.getLower());<o:p></o:p></p>
<p class="MsoNormal">    EXPECT_EQ(1, CR1.getUpper()); // ????<o:p></o:p></p>
<p class="MsoNormal">  }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The value of %x.1 is completely unknown, so its range is [full-set].<o:p></o:p></p>
<p class="MsoNormal">The llvm.assume of %lt is intended to communicate that %x.2 is <=(u) %x.1, whatever the value of %x.1 may be.<o:p></o:p></p>
<p class="MsoNormal">If we ask computeConstantRange about %x.2, it returns [0,1) which seems too restrictive (and potentially leading to miscompilation).<o:p></o:p></p>
<p class="MsoNormal">The assume is interpreted as "only values that can never violate the assumption are allowed". Which in this case, is only 0.<o:p></o:p></p>
<p class="MsoNormal">Is this the correct interpretation of llvm.assume?<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">--- CJ<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</body>
</html>