From: Manman Ren Date: Sat, 2 Aug 2014 23:41:54 +0000 (+0000) Subject: [SimplifyCFG] fix accessing deleted PHINodes in switch-to-table conversion. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=3d5463d81f1278bc75b273d17ec84ec8438be1a1;p=oota-llvm.git [SimplifyCFG] fix accessing deleted PHINodes in switch-to-table conversion. When we have a covered lookup table, make sure we don't delete PHINodes that are cached in PHIs. rdar://17887153 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214642 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index 1c62559739f..63cb1c9abbf 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -3830,7 +3830,10 @@ static bool SwitchToLookupTable(SwitchInst *SI, const bool GeneratingCoveredLookupTable = MaxTableSize == TableSize; if (GeneratingCoveredLookupTable) { Builder.CreateBr(LookupBB); - SI->getDefaultDest()->removePredecessor(SI->getParent()); + // We cached PHINodes in PHIs, to avoid accessing deleted PHINodes later, + // do not delete PHINodes here. + SI->getDefaultDest()->removePredecessor(SI->getParent(), + true/*DontDeleteUselessPHIs*/); } else { Value *Cmp = Builder.CreateICmpULT(TableIndex, ConstantInt::get( MinCaseVal->getType(), TableSize)); diff --git a/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll b/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll new file mode 100644 index 00000000000..22599b397ed --- /dev/null +++ b/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll @@ -0,0 +1,50 @@ +; RUN: opt -S -simplifycfg < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s +; rdar://17887153 +target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-apple-darwin12.0.0" + +; When we have a covered lookup table, make sure we don't delete PHINodes that +; are cached in PHIs. +; CHECK-LABEL: @test +; CHECK: entry: +; CHECK-NEXT: sub i3 %arg, -4 +; CHECK-NEXT: zext i3 %switch.tableidx to i4 +; CHECK-NEXT: getelementptr inbounds [8 x i64]* @switch.table, i32 0, i4 %switch.tableidx.zext +; CHECK-NEXT: load i64* %switch.gep +; CHECK-NEXT: add i64 +; CHECK-NEXT: ret i64 +define i64 @test(i3 %arg) { +entry: + switch i3 %arg, label %Default [ + i3 -2, label %Label6 + i3 1, label %Label1 + i3 2, label %Label2 + i3 3, label %Label3 + i3 -4, label %Label4 + i3 -3, label %Label5 + ] + +Default: + %v1 = phi i64 [ 7, %Label6 ], [ 11, %Label5 ], [ 6, %Label4 ], [ 13, %Label3 ], [ 9, %Label2 ], [ 15, %Label1 ], [ 8, %entry ] + %v2 = phi i64 [ 0, %Label6 ], [ 0, %Label5 ], [ 0, %Label4 ], [ 0, %Label3 ], [ 0, %Label2 ], [ 0, %Label1 ], [ 0, %entry ] + %v3 = add i64 %v1, %v2 + ret i64 %v3 + +Label1: + br label %Default + +Label2: + br label %Default + +Label3: + br label %Default + +Label4: + br label %Default + +Label5: + br label %Default + +Label6: + br label %Default +}