simplifycfg: Fix integer overflow converting switch into icmp.
authorHans Wennborg <hans@hanshq.net>
Tue, 16 Apr 2013 08:35:36 +0000 (08:35 +0000)
committerHans Wennborg <hans@hanshq.net>
Tue, 16 Apr 2013 08:35:36 +0000 (08:35 +0000)
If a switch instruction has a case for every possible value of its type,
with the same successor, SimplifyCFG would replace it with an icmp ult,
but the computation of the bound overflows in that case, which inverts
the test.

Patch by Jed Davis!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179587 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Utils/SimplifyCFG.cpp
test/Transforms/SimplifyCFG/switch-to-icmp.ll

index 681bf9c2b7a422231a51daaf826ca0fb3bcaae91..6de602e4c3e428044884110781275db6d41910d5 100644 (file)
@@ -3073,7 +3073,12 @@ static bool TurnSwitchRangeIntoICmp(SwitchInst *SI, IRBuilder<> &Builder) {
   Value *Sub = SI->getCondition();
   if (!Offset->isNullValue())
     Sub = Builder.CreateAdd(Sub, Offset, Sub->getName()+".off");
-  Value *Cmp = Builder.CreateICmpULT(Sub, NumCases, "switch");
+  Value *Cmp;
+  // If NumCases overflowed, then all possible values jump to the successor.
+  if (NumCases->isNullValue() && SI->getNumCases() != 0)
+    Cmp = ConstantInt::getTrue(SI->getContext());
+  else
+    Cmp = Builder.CreateICmpULT(Sub, NumCases, "switch");
   BranchInst *NewBI = Builder.CreateCondBr(
       Cmp, SI->case_begin().getCaseSuccessor(), SI->getDefaultDest());
 
index 414f8475bc2302353ff3cd7332250050e4837845..e9a6db45cb0077fbe13c50baab422e9f6366df08 100644 (file)
@@ -37,3 +37,21 @@ lor.end:
 ; CHECK: @test2
 ; CHECK: %switch = icmp ult i32 %x, 2
 }
+
+define i32 @test3(i1 %flag) {
+entry:
+ switch i1 %flag, label %bad [
+   i1 true, label %good
+   i1 false, label %good
+ ]
+
+good:
+ ret i32 0
+
+bad:
+ ret i32 1
+
+; CHECK: @test3
+; CHECK: entry:
+; CHECK-NEXT: ret i32 0
+}