From 3096e9dcfef1fc09934eaf5aedc821bb2b976e6e Mon Sep 17 00:00:00 2001 From: Karl-Johan Karlsson Date: Thu, 24 May 2018 06:09:02 +0000 Subject: [PATCH] [NaryReassociate] Detect deleted instr with WeakVH Summary: If NaryReassociate succeed it will, when replacing the old instruction with the new instruction, also recursively delete trivially dead instructions from the old instruction. However, if the input to the NaryReassociate pass contain dead code it is not save to recursively delete trivially deadinstructions as it might lead to deleting the newly created instruction. This patch will fix the problem by using WeakVH to detect this rare case, when the newly created instruction is dead, and it will then restart the basic block iteration from the beginning. This fixes pr37539 Reviewers: tra, meheff, grosser, sanjoy Reviewed By: sanjoy Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D47139 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@333155 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/NaryReassociate.cpp | 13 +++++++--- test/Transforms/NaryReassociate/pr37539.ll | 29 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 test/Transforms/NaryReassociate/pr37539.ll diff --git a/lib/Transforms/Scalar/NaryReassociate.cpp b/lib/Transforms/Scalar/NaryReassociate.cpp index 64e5e1c7cb1..e0370a5fe42 100644 --- a/lib/Transforms/Scalar/NaryReassociate.cpp +++ b/lib/Transforms/Scalar/NaryReassociate.cpp @@ -240,10 +240,17 @@ bool NaryReassociatePass::doOneIteration(Function &F) { Changed = true; SE->forgetValue(&*I); I->replaceAllUsesWith(NewI); - // If SeenExprs constains I's WeakTrackingVH, that entry will be - // replaced with - // nullptr. + WeakVH NewIExist = NewI; + // If SeenExprs/NewIExist contains I's WeakTrackingVH/WeakVH, that + // entry will be replaced with nullptr if deleted. RecursivelyDeleteTriviallyDeadInstructions(&*I, TLI); + if (!NewIExist) { + // Rare occation where the new instruction (NewI) have been removed, + // probably due to parts of the input code was dead from the + // beginning, reset the iterator and start over from the beginning + I = BB->begin(); + continue; + } I = NewI->getIterator(); } // Add the rewritten instruction to SeenExprs; the original instruction diff --git a/test/Transforms/NaryReassociate/pr37539.ll b/test/Transforms/NaryReassociate/pr37539.ll new file mode 100644 index 00000000000..f7fbfd21599 --- /dev/null +++ b/test/Transforms/NaryReassociate/pr37539.ll @@ -0,0 +1,29 @@ +; RUN: opt < %s -nary-reassociate -S -o - | FileCheck %s + +; The test check that compilation does not segv (see pr37539). + +define void @f1() { +; CHECK-LABEL: @f1( +; CHECK-NEXT: br label %[[BB1:.*]] +; CHECK: [[BB1]] +; CHECK-NEXT: [[P1:%.*]] = phi i16 [ 0, [[TMP0:%.*]] ], [ [[A1:%.*]], %[[BB1]] ] +; CHECK-NEXT: [[SCEVGEP_OFFS:%.*]] = add i16 2, 0 +; CHECK-NEXT: [[A1]] = add i16 [[P1]], [[SCEVGEP_OFFS]] +; CHECK-NEXT: br i1 false, label %[[BB1]], label %[[BB7:.*]] +; CHECK: [[BB7]] +; CHECK-NEXT: ret void +; + br label %bb1 + +bb1: + %p1 = phi i16 [ 0, %0 ], [ %a1, %bb1 ] + %p2 = phi i16 [ 0, %0 ], [ %a2, %bb1 ] + %scevgep.offs = add i16 2, 0 + %a1 = add i16 %p1, %scevgep.offs + %scevgep.offs5 = add i16 2, 0 + %a2 = add i16 %p2, %scevgep.offs5 + br i1 false, label %bb1, label %bb7 + +bb7: + ret void +}