Index: llvm/lib/Target/PowerPC/PPCMIPeephole.cpp =================================================================== --- llvm/lib/Target/PowerPC/PPCMIPeephole.cpp +++ llvm/lib/Target/PowerPC/PPCMIPeephole.cpp @@ -1589,6 +1589,12 @@ LLVM_DEBUG(dbgs() << "To: "); LLVM_DEBUG(MI.dump()); NumRotatesCollapsed++; + // If SrcReg has no non-debug use it's safe to delete its def SrcMI. + if (MRI->use_nodbg_empty(SrcReg)) { + assert(!SrcMI->hasImplicitDef() && + "Not expecting an implicit def with this instr."); + SrcMI->eraseFromParent(); + } return true; } Index: llvm/test/CodeGen/PowerPC/jump-tables-collapse-rotate-remove-SrcMI.mir =================================================================== --- /dev/null +++ llvm/test/CodeGen/PowerPC/jump-tables-collapse-rotate-remove-SrcMI.mir @@ -0,0 +1,207 @@ +# RUN: llc -mtriple=powerpc64le--linux-gnu -start-before ppc-mi-peepholes %s -o - -verify-machineinstrs | FileCheck %s + +--- | + ; ModuleID = 'jump-tables-collapse-rotate-remove-SrcMI.ll' + source_filename = "jump-tables-collapse-rotate-remove-SrcMI.ll" + target datalayout = "e-m:e-i64:64-n32:64" + + @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 + + define dso_local void @fn1() { + 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 + } + +... +--- +name: fn1 +alignment: 16 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +failedISel: false +tracksRegLiveness: true +hasWinCFI: false +registers: + - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 2, class: gprc, preferred-register: '' } + - { id: 3, class: crrc, preferred-register: '' } + - { id: 4, class: g8rc, preferred-register: '' } + - { id: 5, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 6, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 7, class: gprc, preferred-register: '' } + - { id: 8, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 9, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 10, class: gprc, preferred-register: '' } + - { id: 11, class: gprc, preferred-register: '' } + - { id: 12, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 13, class: crrc, preferred-register: '' } + - { id: 14, class: gprc_and_gprc_nor0, preferred-register: '' } + - { id: 15, class: gprc, preferred-register: '' } + - { id: 16, class: g8rc, preferred-register: '' } + - { id: 17, class: g8rc, preferred-register: '' } + - { id: 18, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 19, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 20, class: g8rc, preferred-register: '' } + - { id: 21, class: g8rc, preferred-register: '' } + - { id: 22, class: g8rc, preferred-register: '' } + - { id: 23, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 24, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 25, class: g8rc, preferred-register: '' } + - { id: 26, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 27, class: g8rc_and_g8rc_nox0, preferred-register: '' } + - { id: 28, class: g8rc, preferred-register: '' } + - { id: 29, class: g8rc, preferred-register: '' } + - { id: 30, class: g8rc, preferred-register: '' } +liveins: + - { reg: '$x2', virtual-reg: '' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 1 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + cvBytesOfCalleeSavedRegisters: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + localFrameSize: 0 + savePoint: '' + restorePoint: '' +fixedStack: [] +stack: [] +callSites: [] +constants: [] +machineFunctionInfo: {} +jumpTable: + kind: label-difference32 + entries: + - id: 0 + blocks: [ '%bb.2', '%bb.4', '%bb.3', '%bb.3', '%bb.4', '%bb.2' ] +body: | + bb.0.entry: + successors: %bb.4(0x30000000), %bb.1(0x50000000) + liveins: $x2 + + %0:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, @c + %1:g8rc_and_g8rc_nox0 = LDtocL @c, killed %0 :: (load 8 from got) + %2:gprc = LWZ 0, killed %1 :: (dereferenceable load 4 from @c) + %3:crrc = CMPLWI killed %2, 0 + BCC 76, killed %3, %bb.4 + B %bb.1 + + bb.1.if.then: + successors: %bb.2(0x40000000), %bb.4(0x40000000), %bb.3(0x00000000) + liveins: $x2 + + %5:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, @b + %6:g8rc_and_g8rc_nox0 = LDtocL @b, killed %5 :: (load 8 from got) + %7:gprc = LWZ 0, killed %6 :: (dereferenceable load 4 from @b) + %8:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, @d + %9:g8rc_and_g8rc_nox0 = LDtocL @d, killed %8 :: (load 8 from got) + %10:gprc = LWZ 0, killed %9 :: (dereferenceable load 4 from @d) + %11:gprc = CNTLZW killed %10 + %12:gprc_and_gprc_nor0 = RLWINM killed %11, 27, 5, 31 + %13:crrc = CMPLWI killed %7, 0 + %14:gprc_and_gprc_nor0 = LI 5 + %15:gprc = ISEL %12, %14, %13.sub_eq + %17:g8rc = IMPLICIT_DEF + %16:g8rc = INSERT_SUBREG %17, killed %15, %subreg.sub_32 + %4:g8rc = RLDICL killed %16, 0, 32 + %26:g8rc_and_g8rc_nox0 = RLDICR %4, 2, 61 + %27:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, %jump-table.0 + %28:g8rc = LDtocL %jump-table.0, %27 :: (load 8 from got) + %29:g8rc = LWAX %26, %28 :: (load 4 from jump-table) + %30:g8rc = ADD8 %29, %28 + MTCTR8 %30, implicit-def $ctr8 + BCTR8 implicit $ctr8 + + bb.2.sw.bb: + successors: %bb.4(0x80000000) + liveins: $x2 + + %23:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, @a + %24:g8rc_and_g8rc_nox0 = LDtocL @a, killed %23 :: (load 8 from got) + %25:g8rc = LI8 4 + STW8 killed %25, 0, killed %24 :: (store 4 into @a) + B %bb.4 + + bb.3.if.end6: + successors: + liveins: $x2 + + + bb.4.if.end: + BLR8 implicit $lr8, implicit $rm + +... +# CHECK-LABEL: fn1 +# CHECK: # %bb.0: # %entry +# CHECK-NEXT: addis 3, 2, .LC0@toc@ha +# CHECK-NEXT: ld 3, .LC0@toc@l(3) +# CHECK-NEXT: lwz 3, 0(3) +# CHECK-NEXT: cmplwi 3, 0 +# CHECK-NEXT: beqlr 0 +# CHECK-NEXT: # %bb.1: # %if.then +# CHECK-NEXT: addis 3, 2, .LC1@toc@ha +# CHECK-NEXT: addis 4, 2, .LC2@toc@ha +# CHECK-NEXT: addis 5, 2, .LC3@toc@ha +# CHECK-NEXT: ld 3, .LC1@toc@l(3) +# CHECK-NEXT: ld 4, .LC2@toc@l(4) +# CHECK-NEXT: lwz 3, 0(3) +# CHECK-NEXT: lwz 4, 0(4) +# CHECK-NEXT: cntlzw 3, 3 +# CHECK-NEXT: cmplwi 4, 0 +# CHECK-NEXT: ld 4, .LC3@toc@l(5) +# CHECK-NEXT: li 5, 5 +# CHECK-NEXT: srwi 3, 3, 5 +# CHECK-NEXT: isel 3, 3, 5, 2 +# CHECK-NEXT: rldic 3, 3, 2, 30 +# CHECK-NEXT: lwax 3, 3, 4 +# CHECK-NEXT: add 3, 3, 4 +# CHECK-NEXT: mtctr 3 +# CHECK-NEXT: bctr +# CHECK-NEXT: .LBB0_2: # %sw.bb +# CHECK-NEXT: addis 3, 2, .LC4@toc@ha +# CHECK-NEXT: li 4, 4 +# CHECK-NEXT: ld 3, .LC4@toc@l(3) +# CHECK-NEXT: stw 4, 0(3) +# CHECK-NEXT: .LBB0_3: # %if.end +# CHECK-NEXT: blr