[llvm] r247309 - [SimplifyCFG] Use known bits to eliminate dead switch defaults
David Majnemer via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 10 13:17:52 PDT 2015
On Thu, Sep 10, 2015 at 10:44 AM, Philip Reames via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: reames
> Date: Thu Sep 10 12:44:47 2015
> New Revision: 247309
>
> URL: http://llvm.org/viewvc/llvm-project?rev=247309&view=rev
> Log:
> [SimplifyCFG] Use known bits to eliminate dead switch defaults
>
> This is a follow up to http://reviews.llvm.org/D11995 implementing the
> suggestion by Hans.
>
> 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.
>
> 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.
>
> Differential Revision: http://reviews.llvm.org/D12497
>
>
> Modified:
> llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
> llvm/trunk/test/Transforms/SimplifyCFG/switch-dead-default.ll
>
> Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=247309&r1=247308&r2=247309&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Thu Sep 10 12:44:47
> 2015
> @@ -3423,11 +3423,17 @@ static bool EliminateDeadSwitchCases(Swi
> }
>
> // If we can prove that the cases must cover all possible values, the
> - // default destination becomes dead and we can remove it.
> + // default destination becomes dead and we can remove it. If we know
> some
> + // of the bits in the value, we can use that to more precisely compute
> the
> + // number of possible unique case values.
> bool HasDefault =
> !isa<UnreachableInst>(SI->getDefaultDest()->getFirstNonPHIOrDbg());
> - if (HasDefault && Bits < 64 /* avoid overflow */ &&
> - SI->getNumCases() == (1ULL << Bits)) {
> + const unsigned NumUnknownBits = Bits -
> + (KnownZero.Or(KnownOne)).countPopulation();
> + assert(0 <= NumUnknownBits && NumUnknownBits <= Bits);
>
Isn't the first half of this assert vacuously true? NumUnknownBits is
unsigned and thus always greater than or equal to zero.
> + if (HasDefault && DeadCases.empty() &&
> + NumUnknownBits < 64 /* avoid overflow */ &&
> + SI->getNumCases() == (1ULL << NumUnknownBits)) {
> DEBUG(dbgs() << "SimplifyCFG: switch default is dead.\n");
> BasicBlock *NewDefault = SplitBlockPredecessors(SI->getDefaultDest(),
> SI->getParent(), "");
>
> Modified: llvm/trunk/test/Transforms/SimplifyCFG/switch-dead-default.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/switch-dead-default.ll?rev=247309&r1=247308&r2=247309&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/Transforms/SimplifyCFG/switch-dead-default.ll
> (original)
> +++ llvm/trunk/test/Transforms/SimplifyCFG/switch-dead-default.ll Thu Sep
> 10 12:44:47 2015
> @@ -2,7 +2,7 @@
> declare void @foo(i32)
>
> define void @test(i1 %a) {
> -; CHECK-LABEL @test
> +; CHECK-LABEL: @test
> ; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false
> switch i1 %a, label %default [i1 1, label %true
> i1 0, label %false]
> @@ -18,7 +18,7 @@ default:
> }
>
> define void @test2(i2 %a) {
> -; CHECK-LABEL @test2
> +; CHECK-LABEL: @test2
> switch i2 %a, label %default [i2 0, label %case0
> i2 1, label %case1
> i2 2, label %case2
> @@ -45,7 +45,7 @@ default:
> ; This one is a negative test - we know the value of the default,
> ; but that's about it
> define void @test3(i2 %a) {
> -; CHECK-LABEL @test3
> +; CHECK-LABEL: @test3
> switch i2 %a, label %default [i2 0, label %case0
> i2 1, label %case1
> i2 2, label %case2]
> @@ -69,7 +69,7 @@ default:
> ; Negative test - check for possible overflow when computing
> ; number of possible cases.
> define void @test4(i128 %a) {
> -; CHECK-LABEL @test4
> +; CHECK-LABEL: @test4
> switch i128 %a, label %default [i128 0, label %case0
> i128 1, label %case1]
>
> @@ -85,3 +85,95 @@ default:
> call void @foo(i32 0)
> ret void
> }
> +
> +; All but one bit known zero
> +define void @test5(i8 %a) {
> +; CHECK-LABEL: @test5
> +; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false
> + %cmp = icmp ult i8 %a, 2
> + call void @llvm.assume(i1 %cmp)
> + switch i8 %a, label %default [i8 1, label %true
> + i8 0, label %false]
> +true:
> + call void @foo(i32 1)
> + ret void
> +false:
> + call void @foo(i32 3)
> + ret void
> +default:
> + call void @foo(i32 2)
> + ret void
> +}
> +
> +;; All but one bit known one
> +define void @test6(i8 %a) {
> +; CHECK-LABEL: @test6
> +; CHECK: @llvm.assume
> +; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false
> + %and = and i8 %a, 254
> + %cmp = icmp eq i8 %and, 254
> + call void @llvm.assume(i1 %cmp)
> + switch i8 %a, label %default [i8 255, label %true
> + i8 254, label %false]
> +true:
> + call void @foo(i32 1)
> + ret void
> +false:
> + call void @foo(i32 3)
> + ret void
> +default:
> + call void @foo(i32 2)
> + ret void
> +}
> +
> +; Check that we can eliminate both dead cases and dead defaults
> +; within a single run of simplify-cfg
> +define void @test7(i8 %a) {
> +; CHECK-LABEL: @test7
> +; CHECK: @llvm.assume
> +; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false
> + %and = and i8 %a, 254
> + %cmp = icmp eq i8 %and, 254
> + call void @llvm.assume(i1 %cmp)
> + switch i8 %a, label %default [i8 255, label %true
> + i8 254, label %false
> + i8 0, label %also_dead]
> +true:
> + call void @foo(i32 1)
> + ret void
> +false:
> + call void @foo(i32 3)
> + ret void
> +also_dead:
> + call void @foo(i32 5)
> + ret void
> +default:
> + call void @foo(i32 2)
> + ret void
> +}
> +
> +;; All but one bit known undef
> +;; Note: This is currently testing an optimization which doesn't trigger.
> The
> +;; case this is protecting against is that a bit could be assumed both
> zero
> +;; *or* one given we know it's undef. ValueTracking doesn't do this
> today,
> +;; but it doesn't hurt to confirm.
> +define void @test8(i8 %a) {
> +; CHECK-LABEL: @test8(
> +; CHECK: switch i8
> + %and = and i8 %a, 254
> + %cmp = icmp eq i8 %and, undef
> + call void @llvm.assume(i1 %cmp)
> + switch i8 %a, label %default [i8 255, label %true
> + i8 254, label %false]
> +true:
> + call void @foo(i32 1)
> + ret void
> +false:
> + call void @foo(i32 3)
> + ret void
> +default:
> + call void @foo(i32 2)
> + ret void
> +}
> +
> +declare void @llvm.assume(i1)
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150910/474df06e/attachment.html>
More information about the llvm-commits
mailing list