From 8484f92f7f32575c9b48819b0d1e06316cd5ab4f Mon Sep 17 00:00:00 2001 From: Mehdi Amini Date: Thu, 14 Jul 2016 01:31:25 +0000 Subject: [PATCH] [Scalarizer] PR28108: Skip over nullptr rather than crashing on it. Summary: In Scalarizer::gather we see if we already have a scattered form of Op, and in that case use the new form. In the particular case of PR28108, the found ValueVector SV has size 2, where the first Value is nullptr, and the second is indeed a proper Value. The nullptr then caused an assert to blow when we tried to do cast(SV[I]). With this patch we check SV[I] before doing the cast, and if it's nullptr we just skip over it. I don't know the Scalarizer well enough to know if this is the best fix or if something should be done else where to prevent the nullptr from being in the ValueVector at all, but at least this avoids the crash and looking at the test case output it looks reasonable. Reviewers: hfinkel, frasercrmck, wala, mehdi_amini Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D21518 llvm-svn: 275359 --- llvm/lib/Transforms/Scalar/Scalarizer.cpp | 6 +++++- llvm/test/Transforms/Scalarizer/crash-bug.ll | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 llvm/test/Transforms/Scalarizer/crash-bug.ll diff --git a/llvm/lib/Transforms/Scalar/Scalarizer.cpp b/llvm/lib/Transforms/Scalar/Scalarizer.cpp index 15aa541..aed4a4a 100644 --- a/llvm/lib/Transforms/Scalar/Scalarizer.cpp +++ b/llvm/lib/Transforms/Scalar/Scalarizer.cpp @@ -306,7 +306,11 @@ void Scalarizer::gather(Instruction *Op, const ValueVector &CV) { ValueVector &SV = Scattered[Op]; if (!SV.empty()) { for (unsigned I = 0, E = SV.size(); I != E; ++I) { - Instruction *Old = cast(SV[I]); + Value *V = SV[I]; + if (V == nullptr) + continue; + + Instruction *Old = cast(V); CV[I]->takeName(Old); Old->replaceAllUsesWith(CV[I]); Old->eraseFromParent(); diff --git a/llvm/test/Transforms/Scalarizer/crash-bug.ll b/llvm/test/Transforms/Scalarizer/crash-bug.ll new file mode 100644 index 0000000..36430a9 --- /dev/null +++ b/llvm/test/Transforms/Scalarizer/crash-bug.ll @@ -0,0 +1,24 @@ +; RUN: opt %s -scalarizer -S -o - | FileCheck %s + +; Don't crash + +define void @foo() { + br label %bb1 + +bb2: ; preds = %bb1 + %bb2_vec = shufflevector <2 x i16> , + <2 x i16> %bb1_vec, + <2 x i32> + br label %bb1 + +bb1: ; preds = %bb2, %0 + %bb1_vec = phi <2 x i16> [ , %0 ], [ %bb2_vec, %bb2 ] +;CHECK: bb1: +;CHECK: %bb1_vec.i0 = phi i16 [ 100, %0 ], [ 0, %bb2 ] +;CHECK: %bb1_vec.i1 = phi i16 [ 200, %0 ], [ %bb1_vec.i1, %bb2 ] + br i1 undef, label %bb3, label %bb2 + +bb3: + ret void +} + -- 2.7.4