From bf7190a15470adb31f8df08aa9d61bb2861e7d54 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Mon, 23 Apr 2018 06:58:36 +0000 Subject: [PATCH] [PM/LoopUnswitch] Remove a buggy assert in the new loop unswitch. The condition this was asserting doesn't actually hold. I've added comments to explain why, removed the assert, and added a fun test case reduced out of 403.gcc. llvm-svn: 330564 --- llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp | 11 ++--- .../SimpleLoopUnswitch/nontrivial-unswitch.ll | 55 ++++++++++++++++++++++ 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp index b6194d9..c7b071b 100644 --- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp +++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp @@ -1364,9 +1364,10 @@ static SmallPtrSet recomputeLoopBlockSet(Loop &L, continue; // Insert all of the blocks (other than those already present) into - // the loop set. The only block we expect to already be in the set is - // the one we used to find this loop as we immediately handle the - // others the first time we encounter the loop. + // the loop set. We expect at least the block that led us to find the + // inner loop to be in the block set, but we may also have other loop + // blocks if they were already enqueued as predecessors of some other + // outer loop block. for (auto *InnerBB : InnerL->blocks()) { if (InnerBB == BB) { assert(LoopBlockSet.count(InnerBB) && @@ -1374,9 +1375,7 @@ static SmallPtrSet recomputeLoopBlockSet(Loop &L, continue; } - bool Inserted = LoopBlockSet.insert(InnerBB).second; - (void)Inserted; - assert(Inserted && "Should only insert an inner loop once!"); + LoopBlockSet.insert(InnerBB); } // Add the preheader to the worklist so we will continue past the diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll b/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll index 651ba19..e181bc5 100644 --- a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll @@ -2380,3 +2380,58 @@ loop_latch: loop_exit: ret void } + +; A test reduced out of 403.gcc with interesting nested loops that trigger +; multiple unswitches. A key component of this test is that there are multiple +; paths to reach an inner loop after unswitching, and one of them is via the +; predecessors of the unswitched loop header. That can allow us to find the loop +; through multiple different paths. +define void @test21(i1 %a, i1 %b) { +; CHECK-LABEL: @test21( +bb: + br label %bb3 +; CHECK-NOT: br i1 %a +; +; CHECK: br i1 %a, label %[[BB_SPLIT_US:.*]], label %[[BB_SPLIT:.*]] +; +; CHECK-NOT: br i1 %a +; CHECK-NOT: br i1 %b +; +; CHECK: [[BB_SPLIT]]: +; CHECK: br i1 %b +; +; CHECK-NOT: br i1 %a +; CHECK-NOT: br i1 %b + +bb3: + %tmp1.0 = phi i32 [ 0, %bb ], [ %tmp1.3, %bb23 ] + br label %bb7 + +bb7: + %tmp.0 = phi i1 [ true, %bb3 ], [ false, %bb19 ] + %tmp1.1 = phi i32 [ %tmp1.0, %bb3 ], [ %tmp1.2.lcssa, %bb19 ] + br i1 %tmp.0, label %bb11.preheader, label %bb23 + +bb11.preheader: + br i1 %a, label %bb19, label %bb14.lr.ph + +bb14.lr.ph: + br label %bb14 + +bb14: + %tmp2.02 = phi i32 [ 0, %bb14.lr.ph ], [ 1, %bb14 ] + br i1 %b, label %bb11.bb19_crit_edge, label %bb14 + +bb11.bb19_crit_edge: + %split = phi i32 [ %tmp2.02, %bb14 ] + br label %bb19 + +bb19: + %tmp1.2.lcssa = phi i32 [ %split, %bb11.bb19_crit_edge ], [ %tmp1.1, %bb11.preheader ] + %tmp21 = icmp eq i32 %tmp1.2.lcssa, 0 + br i1 %tmp21, label %bb23, label %bb7 + +bb23: + %tmp1.3 = phi i32 [ %tmp1.2.lcssa, %bb19 ], [ %tmp1.1, %bb7 ] + br label %bb3 +} -- 2.7.4