diff --git a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp --- a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp +++ b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp @@ -1589,6 +1589,10 @@ LLVM_DEBUG(dbgs() << "To: "); LLVM_DEBUG(MI.dump()); NumRotatesCollapsed++; + // If SrcReg has no non-debug use and it has no implicit def it's safe to + // delete its def SrcMI. Otherwise keep it. + if (MRI->use_nodbg_empty(SrcReg) && !SrcMI->hasImplicitDef()) + SrcMI->eraseFromParent(); return true; } diff --git a/llvm/test/CodeGen/PowerPC/jump-tables-collapse-rotate.ll b/llvm/test/CodeGen/PowerPC/jump-tables-collapse-rotate.ll --- a/llvm/test/CodeGen/PowerPC/jump-tables-collapse-rotate.ll +++ b/llvm/test/CodeGen/PowerPC/jump-tables-collapse-rotate.ll @@ -118,3 +118,74 @@ declare signext i32 @test2(i32 signext) declare signext i32 @test4(i32 signext) + +@b = external local_unnamed_addr global i32, align 4 +@d = external local_unnamed_addr global i32, align 4 +@c = external local_unnamed_addr global i32, align 4 +@a = external local_unnamed_addr global i32, align 4 + +; Function Attrs: nofree norecurse nounwind +define dso_local void @fn1() { +; CHECK-LABEL: fn1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: addis r3, r2, .LC1@toc@ha +; CHECK-NEXT: ld r3, .LC1@toc@l(r3) +; CHECK-NEXT: lwz r3, 0(r3) +; CHECK-NEXT: cmplwi r3, 0 +; CHECK-NEXT: beqlr cr0 +; CHECK-NEXT: # %bb.1: # %if.then +; CHECK-NEXT: addis r3, r2, .LC2@toc@ha +; CHECK-NEXT: addis r4, r2, .LC3@toc@ha +; CHECK-NEXT: addis r5, r2, .LC4@toc@ha +; CHECK-NEXT: ld r3, .LC2@toc@l(r3) +; CHECK-NEXT: ld r4, .LC3@toc@l(r4) +; CHECK-NEXT: ld r5, .LC4@toc@l(r5) +; CHECK-NEXT: lwz r3, 0(r3) +; CHECK-NEXT: lwz r4, 0(r4) +; CHECK-NEXT: cntlzw r3, r3 +; CHECK-NEXT: cmplwi r4, 0 +; CHECK-NEXT: li r4, 5 +; CHECK-NEXT: srwi r3, r3, 5 +; CHECK-NEXT: isel r3, r3, r4, eq +; CHECK-NEXT: rldic r3, r3, 2, 30 +; CHECK-NEXT: lwax r3, r3, r5 +; CHECK-NEXT: add r3, r3, r5 +; CHECK-NEXT: mtctr r3 +; CHECK-NEXT: bctr +; CHECK-NEXT: .LBB1_2: # %sw.bb +; CHECK-NEXT: addis r3, r2, .LC5@toc@ha +; CHECK-NEXT: li r4, 4 +; CHECK-NEXT: ld r3, .LC5@toc@l(r3) +; CHECK-NEXT: stw r4, 0(r3) +; CHECK-NEXT: .LBB1_3: # %if.end +; CHECK-NEXT: blr + +entry: + %0 = load i32, i32* @c, align 4 + %tobool3 = icmp eq i32 %0, 0 + br i1 %tobool3, label %if.end, label %if.then + +if.then: ; preds = %entry + %1 = load i32, i32* @b, align 4 + %tobool = icmp eq i32 %1, 0 + %2 = load i32, i32* @d, align 4 + %tobool1 = icmp eq i32 %2, 0 + %cond = zext i1 %tobool1 to i32 + %cond2 = select i1 %tobool, i32 %cond, i32 5 + switch i32 %cond2, label %if.end6 [ + i32 5, label %sw.bb + i32 0, label %sw.bb + i32 1, label %if.end + i32 4, label %if.end + ] + +sw.bb: ; preds = %if.then, %if.then + store i32 4, i32* @a, align 4 + br label %if.end + +if.end6: ; preds = %if.then + unreachable + +if.end: ; preds = %sw.bb, %if.then, %if.then, %entry + ret void +}