<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <br>
    <br>
    <div class="moz-cite-prefix">On 09/10/2015 01:17 PM, David Majnemer
      wrote:<br>
    </div>
    <blockquote
cite="mid:CAL7bZ_d8t_WV4_DHSbsL2Vbmc5jPuDmMf9Na6doDBpuprCBwDw@mail.gmail.com"
      type="cite">
      <div dir="ltr"><br>
        <div class="gmail_extra"><br>
          <div class="gmail_quote">On Thu, Sep 10, 2015 at 10:44 AM,
            Philip Reames via llvm-commits <span dir="ltr"><<a
                moz-do-not-send="true"
                href="mailto:llvm-commits@lists.llvm.org"
                target="_blank">llvm-commits@lists.llvm.org</a>></span>
            wrote:<br>
            <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author:
              reames<br>
              Date: Thu Sep 10 12:44:47 2015<br>
              New Revision: 247309<br>
              <br>
              URL: <a moz-do-not-send="true"
                href="http://llvm.org/viewvc/llvm-project?rev=247309&view=rev"
                rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=247309&view=rev</a><br>
              Log:<br>
              [SimplifyCFG] Use known bits to eliminate dead switch
              defaults<br>
              <br>
              This is a follow up to <a moz-do-not-send="true"
                href="http://reviews.llvm.org/D11995" rel="noreferrer"
                target="_blank">http://reviews.llvm.org/D11995</a>
              implementing the suggestion by Hans.<br>
              <br>
              If we know some of the bits of the value being switched
              on, we know that the maximum number of unique cases covers
              the unknown bits. This allows to eliminate switch defaults
              for large integers (i32) when most bits in the value are
              known.<br>
              <br>
              Note that I had to make the transform contingent on not
              having any dead cases. This is conservatively correct with
              the old code, but required for the new code since we might
              have a dead case which varies one of the known bits.
              Counting that towards our number of covering cases would
              be bad.  If we do have dead cases, we'll eliminate them
              first, then revisit the possibly dead default.<br>
              <br>
              Differential Revision: <a moz-do-not-send="true"
                href="http://reviews.llvm.org/D12497" rel="noreferrer"
                target="_blank">http://reviews.llvm.org/D12497</a><br>
              <br>
              <br>
              Modified:<br>
                  llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp<br>
                 
              llvm/trunk/test/Transforms/SimplifyCFG/switch-dead-default.ll<br>
              <br>
              Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp<br>
              URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=247309&r1=247308&r2=247309&view=diff"
                rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=247309&r1=247308&r2=247309&view=diff</a><br>
==============================================================================<br>
              --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
              (original)<br>
              +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Thu
              Sep 10 12:44:47 2015<br>
              @@ -3423,11 +3423,17 @@ static bool
              EliminateDeadSwitchCases(Swi<br>
                 }<br>
              <br>
                 // If we can prove that the cases must cover all
              possible values, the<br>
              -  // default destination becomes dead and we can remove
              it.<br>
              +  // default destination becomes dead and we can remove
              it.  If we know some<br>
              +  // of the bits in the value, we can use that to more
              precisely compute the<br>
              +  // number of possible unique case values.<br>
                 bool HasDefault =<br>
                 
 !isa<UnreachableInst>(SI->getDefaultDest()->getFirstNonPHIOrDbg());<br>
              -  if (HasDefault && Bits < 64 /* avoid
              overflow */ &&<br>
              -      SI->getNumCases() == (1ULL << Bits)) {<br>
              +  const unsigned NumUnknownBits = Bits -<br>
              +    (KnownZero.Or(KnownOne)).countPopulation();<br>
              +  assert(0 <= NumUnknownBits && NumUnknownBits
              <= Bits);<br>
            </blockquote>
            <div><br>
            </div>
            <div>Isn't the first half of this assert vacuously true?
              NumUnknownBits is unsigned and thus always greater than or
              equal to zero.</div>
          </div>
        </div>
      </div>
    </blockquote>
    Yep.  Will fix.  <br>
    <blockquote
cite="mid:CAL7bZ_d8t_WV4_DHSbsL2Vbmc5jPuDmMf9Na6doDBpuprCBwDw@mail.gmail.com"
      type="cite">
      <div dir="ltr">
        <div class="gmail_extra">
          <div class="gmail_quote">
            <div> </div>
            <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+ 
              if (HasDefault && DeadCases.empty() &&<br>
              +      NumUnknownBits < 64 /* avoid overflow */
              &&<br>
              +      SI->getNumCases() == (1ULL <<
              NumUnknownBits)) {<br>
                   DEBUG(dbgs() << "SimplifyCFG: switch default is
              dead.\n");<br>
                   BasicBlock *NewDefault =
              SplitBlockPredecessors(SI->getDefaultDest(),<br>
                                                                 
               SI->getParent(), "");<br>
              <br>
              Modified:
              llvm/trunk/test/Transforms/SimplifyCFG/switch-dead-default.ll<br>
              URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/switch-dead-default.ll?rev=247309&r1=247308&r2=247309&view=diff"
                rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/switch-dead-default.ll?rev=247309&r1=247308&r2=247309&view=diff</a><br>
==============================================================================<br>
              ---
              llvm/trunk/test/Transforms/SimplifyCFG/switch-dead-default.ll
              (original)<br>
              +++
              llvm/trunk/test/Transforms/SimplifyCFG/switch-dead-default.ll
              Thu Sep 10 12:44:47 2015<br>
              @@ -2,7 +2,7 @@<br>
               declare void @foo(i32)<br>
              <br>
               define void @test(i1 %a) {<br>
              -; CHECK-LABEL @test<br>
              +; CHECK-LABEL: @test<br>
               ; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false<br>
                 switch i1 %a, label %default [i1 1, label %true<br>
                                               i1 0, label %false]<br>
              @@ -18,7 +18,7 @@ default:<br>
               }<br>
              <br>
               define void @test2(i2 %a) {<br>
              -; CHECK-LABEL @test2<br>
              +; CHECK-LABEL: @test2<br>
                 switch i2 %a, label %default [i2 0, label %case0<br>
                                               i2 1, label %case1<br>
                                               i2 2, label %case2<br>
              @@ -45,7 +45,7 @@ default:<br>
               ; This one is a negative test - we know the value of the
              default,<br>
               ; but that's about it<br>
               define void @test3(i2 %a) {<br>
              -; CHECK-LABEL @test3<br>
              +; CHECK-LABEL: @test3<br>
                 switch i2 %a, label %default [i2 0, label %case0<br>
                                               i2 1, label %case1<br>
                                               i2 2, label %case2]<br>
              @@ -69,7 +69,7 @@ default:<br>
               ; Negative test - check for possible overflow when
              computing<br>
               ; number of possible cases.<br>
               define void @test4(i128 %a) {<br>
              -; CHECK-LABEL @test4<br>
              +; CHECK-LABEL: @test4<br>
                 switch i128 %a, label %default [i128 0, label %case0<br>
                                                 i128 1, label %case1]<br>
              <br>
              @@ -85,3 +85,95 @@ default:<br>
                 call void @foo(i32 0)<br>
                 ret void<br>
               }<br>
              +<br>
              +; All but one bit known zero<br>
              +define void @test5(i8 %a) {<br>
              +; CHECK-LABEL: @test5<br>
              +; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false<br>
              +  %cmp = icmp ult i8 %a, 2<br>
              +  call void @llvm.assume(i1 %cmp)<br>
              +  switch i8 %a, label %default [i8 1, label %true<br>
              +                                i8 0, label %false]<br>
              +true:<br>
              +  call void @foo(i32 1)<br>
              +  ret void<br>
              +false:<br>
              +  call void @foo(i32 3)<br>
              +  ret void<br>
              +default:<br>
              +  call void @foo(i32 2)<br>
              +  ret void<br>
              +}<br>
              +<br>
              +;; All but one bit known one<br>
              +define void @test6(i8 %a) {<br>
              +; CHECK-LABEL: @test6<br>
              +; CHECK: @llvm.assume<br>
              +; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false<br>
              +  %and = and i8 %a, 254<br>
              +  %cmp = icmp eq i8 %and, 254<br>
              +  call void @llvm.assume(i1 %cmp)<br>
              +  switch i8 %a, label %default [i8 255, label %true<br>
              +                                i8 254, label %false]<br>
              +true:<br>
              +  call void @foo(i32 1)<br>
              +  ret void<br>
              +false:<br>
              +  call void @foo(i32 3)<br>
              +  ret void<br>
              +default:<br>
              +  call void @foo(i32 2)<br>
              +  ret void<br>
              +}<br>
              +<br>
              +; Check that we can eliminate both dead cases and dead
              defaults<br>
              +; within a single run of simplify-cfg<br>
              +define void @test7(i8 %a) {<br>
              +; CHECK-LABEL: @test7<br>
              +; CHECK: @llvm.assume<br>
              +; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false<br>
              +  %and = and i8 %a, 254<br>
              +  %cmp = icmp eq i8 %and, 254<br>
              +  call void @llvm.assume(i1 %cmp)<br>
              +  switch i8 %a, label %default [i8 255, label %true<br>
              +                                i8 254, label %false<br>
              +                                i8 0, label %also_dead]<br>
              +true:<br>
              +  call void @foo(i32 1)<br>
              +  ret void<br>
              +false:<br>
              +  call void @foo(i32 3)<br>
              +  ret void<br>
              +also_dead:<br>
              +  call void @foo(i32 5)<br>
              +  ret void<br>
              +default:<br>
              +  call void @foo(i32 2)<br>
              +  ret void<br>
              +}<br>
              +<br>
              +;; All but one bit known undef<br>
              +;; Note: This is currently testing an optimization which
              doesn't trigger. The<br>
              +;; case this is protecting against is that a bit could be
              assumed both zero<br>
              +;; *or* one given we know it's undef.  ValueTracking
              doesn't do this today,<br>
              +;; but it doesn't hurt to confirm.<br>
              +define void @test8(i8 %a) {<br>
              +; CHECK-LABEL: @test8(<br>
              +; CHECK: switch i8<br>
              +  %and = and i8 %a, 254<br>
              +  %cmp = icmp eq i8 %and, undef<br>
              +  call void @llvm.assume(i1 %cmp)<br>
              +  switch i8 %a, label %default [i8 255, label %true<br>
              +                                i8 254, label %false]<br>
              +true:<br>
              +  call void @foo(i32 1)<br>
              +  ret void<br>
              +false:<br>
              +  call void @foo(i32 3)<br>
              +  ret void<br>
              +default:<br>
              +  call void @foo(i32 2)<br>
              +  ret void<br>
              +}<br>
              +<br>
              +declare void @llvm.assume(i1)<br>
              <br>
              <br>
              _______________________________________________<br>
              llvm-commits mailing list<br>
              <a moz-do-not-send="true"
                href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
              <a moz-do-not-send="true"
                href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits"
                rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
            </blockquote>
          </div>
          <br>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>