Index: lib/Transforms/Scalar/LoopUnswitch.cpp =================================================================== --- lib/Transforms/Scalar/LoopUnswitch.cpp +++ lib/Transforms/Scalar/LoopUnswitch.cpp @@ -644,8 +644,27 @@ } else if (SwitchInst *SI = dyn_cast(TI)) { Value *LoopCond = FindLIVLoopCondition(SI->getCondition(), currentLoop, Changed); + // %and = and i32 %loop_invariant, %loop_variant + // switch i32 %and, + // label %sw.default [ + // i32 11, label %sw.bb + // i32 12, label %sw.bb1 + // ] + // + // Only unswitch on the switchinst input value. It is not meaningful + // to compare the %loop_invariant with one of the switch case value. + // This will most likely lead to no simplication opportunities in + // the original loop and the newly generated loop. + // + // i.e. the only thing we know is the loop-invariant input to the + // and is/isnt the value we choose to unswitch on. This most + // likely will not enable us to simplify the switch instruction. + // + // To make matter worse, we do not record this loop has been unswitched + // on this particular value and we keep unswitching it on the same + // value until we run out of quota. unsigned NumCases = SI->getNumCases(); - if (LoopCond && NumCases) { + if (LoopCond && LoopCond == SI->getCondition() && NumCases) { // Find a value to unswitch on: // FIXME: this should chose the most expensive case! // FIXME: scan for a case with a non-critical edge? Index: test/Transforms/LoopUnswitch/basictest.ll =================================================================== --- test/Transforms/LoopUnswitch/basictest.ll +++ test/Transforms/LoopUnswitch/basictest.ll @@ -101,7 +101,49 @@ ; CHECK: } } +; Make sure we do not unswitch this loop, as we do not really know the +; right value for %a to unswitch on. +; +; CHECK: define i32 @and_as_switch_input(i32 +; CHECK: entry: +; This is an indication that the loop has been unswitched. +; CHECK-NOT: icmp +; CHECK: br +define i32 @and_as_switch_input(i32 %a) #0 { +entry: + br label %for.body + +for.body: + %i = phi i32 [ 0, %entry ], [ %inc, %for.inc ] + %and = and i32 %a, %i + switch i32 %and, label %sw.default [ + i32 11, label %sw.bb + i32 12, label %sw.bb1 + ] + +sw.bb: + %call = call i32 (...) @boo() + br label %sw.epilog + +sw.bb1: + br label %sw.epilog + +sw.default: + br label %sw.epilog + +sw.epilog: + br label %for.inc + +for.inc: + %inc = add nsw i32 %i, 1 + %cmp = icmp slt i32 %inc, 1024 + br i1 %cmp, label %for.body, label %for.end + +for.end: + ret i32 %a +} +declare i32 @boo(...) declare void @incf() noreturn declare void @decf() noreturn declare void @conv() convergent