Index: include/llvm/Transforms/Scalar/SROA.h =================================================================== --- include/llvm/Transforms/Scalar/SROA.h +++ include/llvm/Transforms/Scalar/SROA.h @@ -130,7 +130,7 @@ bool splitAlloca(AllocaInst &AI, sroa::AllocaSlices &AS); bool runOnAlloca(AllocaInst &AI); void clobberUse(Use &U); - void deleteDeadInstructions(SmallPtrSetImpl &DeletedAllocas); + bool deleteDeadInstructions(SmallPtrSetImpl &DeletedAllocas); bool promoteAllocas(Function &F); }; Index: lib/Transforms/Scalar/SROA.cpp =================================================================== --- lib/Transforms/Scalar/SROA.cpp +++ lib/Transforms/Scalar/SROA.cpp @@ -4243,8 +4243,9 @@ /// /// We also record the alloca instructions deleted here so that they aren't /// subsequently handed to mem2reg to promote. -void SROA::deleteDeadInstructions( +bool SROA::deleteDeadInstructions( SmallPtrSetImpl &DeletedAllocas) { + bool Changed = false; while (!DeadInsts.empty()) { Instruction *I = DeadInsts.pop_back_val(); DEBUG(dbgs() << "Deleting dead instruction: " << *I << "\n"); @@ -4270,7 +4271,9 @@ ++NumDeleted; I->eraseFromParent(); + Changed = true; } + return Changed; } /// \brief Promote the allocas, using the best available technique. @@ -4312,7 +4315,7 @@ do { while (!Worklist.empty()) { Changed |= runOnAlloca(*Worklist.pop_back_val()); - deleteDeadInstructions(DeletedAllocas); + Changed |= deleteDeadInstructions(DeletedAllocas); // Remove the deleted allocas from various lists so that we don't try to // continue processing them. Index: test/Transforms/SROA/dead-inst.ll =================================================================== --- /dev/null +++ test/Transforms/SROA/dead-inst.ll @@ -0,0 +1,141 @@ +; SROA fails to rewrite allocs but does rewrite some phis and delete +; dead instructions. Ensure that this invalidates analyses required +; for other passes. +; RUN: opt < %s -passes=bdce,sroa,bdce -o %t -debug-pass-manager 2>&1 | FileCheck %s +; CHECK: Running pass: BDCEPass on H +; CHECK: Running analysis: DemandedBitsAnalysis on H +; CHECK: Running pass: SROA on H +; CHECK: Invalidating all non-preserved analyses for: H +; CHECK: Invalidating analysis: DemandedBitsAnalysis on H +; CHECK: Running pass: BDCEPass on H +; CHECK: Running analysis: DemandedBitsAnalysis on H +; CHECK: Finished llvm::Function pass manager run. + +; ModuleID = 'bugpoint-reduced-simplified.bc' +source_filename = "bugpoint-output-7a27a2b.bc" +target datalayout = "e-m:e-i64:64-n32:64" +target triple = "powerpc64le-grtev4-linux-gnu" + +%"struct.X" = type { %"class.B", %"class.B" } +%"class.B" = type { %"struct.J2" } +%"struct.J2" = type { %"struct.K1" } +%"struct.K1" = type { i64 } +%"struct.K0" = type { i8 } +%class.b = type { %"class.L" } +%"class.L" = type { %"class.M" } +%"class.M" = type { %"struct.N", i64, %union.anon } +%"struct.N" = type { i8* } +%union.anon = type { i64, [8 x i8] } +%"class.I" = type { i64 } +%"class.F" = type { %"struct.A" } +%"struct.A" = type <{ i8*, i8*, i8*, i8*, i8* (i32, i8*, i8*, i8*)*, void (i8*)*, i8, i8, i8, [5 x i8], i1 ()*, void ()*, i8*, i8*, i64, %"struct.J2", %"struct.X"*, %"struct.J1", [7 x i8] }> +%"struct.J1" = type { %"struct.J3" } +%"struct.J3" = type { %"struct.K0" } + +@C = external global { { i8*, i8*, i8*, i8*, i8* (i32, i8*, i8*, i8*)*, void (i8*)*, i8, i8, i8, i1 ()*, void ()*, i8*, i8*, i64, { i64 }, %"struct.X"*, { %"struct.K0" } } }, align 8 +@.str.14 = external hidden unnamed_addr constant [5 x i8], align 1 + +declare void @D(%class.b* sret, %class.b* dereferenceable(32)) local_unnamed_addr #0 + +; Function Attrs: nounwind +define hidden fastcc void @H(%"class.I"* noalias nocapture readnone, [2 x i64]) unnamed_addr #1 !prof !1 { + %3 = alloca %class.b, align 8 + %.sroa.0 = alloca i64, align 8 + store i64 0, i64* %.sroa.0, align 8 + %4 = extractvalue [2 x i64] %1, 1 + switch i64 %4, label %6 [ + i64 4, label %37 + i64 5, label %5 + ] + +;