diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -5185,8 +5185,9 @@ } } -/// Turn a switch with two reachable destinations into an integer range -/// comparison and branch. +/// Turn a switch into an integer range comparison and branch. +/// Switches with more than 2 destinations are ignored. +/// Switches with 1 destation are also ignored. bool SimplifyCFGOpt::TurnSwitchRangeIntoICmp(SwitchInst *SI, IRBuilder<> &Builder) { assert(SI->getNumCases() > 1 && "Degenerate switch?"); @@ -5218,6 +5219,10 @@ } return false; // More than two destinations. } + // All destinations are the same and the default is undef + if (!DestB) { + return false; + } assert(DestA && DestB && "Single-destination switch should have been folded."); diff --git a/llvm/test/Transforms/SimplifyCFG/switch-default-undef.ll b/llvm/test/Transforms/SimplifyCFG/switch-default-undef.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/SimplifyCFG/switch-default-undef.ll @@ -0,0 +1,45 @@ +; RUN: opt -passes=simplifycfg"" -S %s | FileCheck %s + +; CHECK: define void @0(i8 %sw, i32* %p0) { +; CHECK: group2: +; CHECK: call void @bar(i32* %p0) +; CHECK: ret void +; CHECK: } +define void @0(i8 %sw, i32* %p0) { + switch i8 %sw, label %group3 [ + i8 0, label %group1 + i8 1, label %group1 + i8 2, label %group1 + i8 3, label %group1 + i8 11, label %group1 + i8 12, label %group1 + i8 13, label %group1 + i8 7, label %group1 + i8 17, label %group1 + i8 14, label %group1 + i8 15, label %group1 + i8 4, label %group2 + i8 5, label %group2 + i8 6, label %group2 + i8 8, label %group2 + i8 9, label %group2 + i8 10, label %group2 + ] + +group1: + br label %exit + +group2: + br label %exit + +group3: + br label %exit + +exit: + %phi = phi i32* [ null, %group3 ], [ %p0, %group2 ], [ null, %group1 ] + call void @bar(i32* %phi) + ret void +} + +; CHECK: declare void @bar(i32* nonnull dereferenceable(4)) +declare void @bar(i32* nonnull dereferenceable(4)) \ No newline at end of file