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 @@ -425,10 +425,17 @@ ToErase->eraseFromParent(); ToErase = nullptr; } - // If a conditional trap instruction got optimized to an - // unconditional trap, eliminate all the instructions after - // the trap. + // If a conditional trap instruction got optimized to an unconditional + // trap, set all vreg definitions after the conditional trap to + // IMPLICIT_DEF and eliminate all the other instructions after the trap. if (EnableTrapOptimization && TrapOpt) { + bool IsVReg = + (MI.getNumOperands() && MI.getOperand(0).isReg()) + ? Register::isVirtualRegister(MI.getOperand(0).getReg()) + : false; + if (IsVReg) + BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(PPC::IMPLICIT_DEF), + MI.getOperand(0).getReg()); ToErase = &MI; continue; } @@ -1044,8 +1051,8 @@ auto ImmOperand2 = IsOperand2Immediate ? MI.getOperand(2).getImm() : LiMI2->getOperand(1).getImm(); - // We will replace the MI with an unconditional trap if it will always - // trap. + // We will remove the MI and change the terminator to an unconditional + // trap if it will always trap. if ((ImmOperand0 == 31) || ((ImmOperand0 & 0x10) && ((int64_t)ImmOperand1 < (int64_t)ImmOperand2)) || @@ -1056,7 +1063,6 @@ ((ImmOperand0 & 0x1) && ((uint64_t)ImmOperand1 > (uint64_t)ImmOperand2)) || ((ImmOperand0 & 0x4) && (ImmOperand1 == ImmOperand2))) { - BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(PPC::TRAP)); TrapOpt = true; } // We will delete the MI if it will never trap. @@ -1066,6 +1072,13 @@ } } } + // Change the terminator to an unconditional trap and reset TrapOpt to false + // at the end of the basic block. + if (EnableTrapOptimization && TrapOpt) { + if (ToErase) + BuildMI(MBB, ToErase, ToErase->getDebugLoc(), TII->get(PPC::TRAP)); + TrapOpt = false; + } // If the last instruction was marked for elimination, // remove it now. @@ -1073,9 +1086,6 @@ ToErase->eraseFromParent(); ToErase = nullptr; } - // Reset TrapOpt to false at the end of the basic block. - if (EnableTrapOptimization) - TrapOpt = false; } // Eliminate all the TOC save instructions which are redundant. diff --git a/llvm/test/CodeGen/PowerPC/mi-peephole-trap-opt-dominated-block.mir b/llvm/test/CodeGen/PowerPC/mi-peephole-trap-opt-dominated-block.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/mi-peephole-trap-opt-dominated-block.mir @@ -0,0 +1,152 @@ +# RUN: llc -mtriple powerpc64le-unknown-linux-gnu -mcpu=pwr8 -x mir < %s \ +# RUN: -verify-machineinstrs -start-before=ppc-mi-peepholes \ +# RUN: -stop-after=ppc-mi-peepholes -ppc-opt-conditional-trap \ +# RUN: | FileCheck --check-prefix=CHECK-MIR %s + +# RUN: llc -mtriple powerpc64-ibm-aix-xcoff -mcpu=pwr8 -x mir < %s \ +# RUN: -verify-machineinstrs -start-before=ppc-mi-peepholes \ +# RUN: -stop-after=ppc-mi-peepholes -ppc-opt-conditional-trap \ +# RUN: | FileCheck --check-prefix=CHECK-MIR %s + +# RUN: llc -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr8 -x mir < %s \ +# RUN: -verify-machineinstrs -start-before=ppc-mi-peepholes \ +# RUN: -stop-after=ppc-mi-peepholes -ppc-opt-conditional-trap \ +# RUN: | FileCheck --check-prefix=CHECK-MIR %s + +# RUN: llc -mtriple powerpc64le-unknown-linux-gnu -mcpu=pwr8 -x mir < %s \ +# RUN: -verify-machineinstrs -start-before=ppc-mi-peepholes \ +# RUN: -ppc-opt-conditional-trap | FileCheck %s + + +--- | + define dso_local signext i32 @callee(i32 signext %ic, i32 signext %id) { + entry: + %add = add nsw i32 %id, %ic + ret i32 %add + } + define dso_local signext i32 @test_MBB_dominated(i32 signext %ia, i32 signext %ib) { + entry: + tail call void @llvm.ppc.MBB_dominated(i32 3, i32 3, i32 4) + %cmp.not = icmp slt i32 %ia, %ib + br i1 %cmp.not, label %cleanup, label %if.then + if.then: ; preds = %entry + %add = add nsw i32 %ia, 1 + %call = tail call signext i32 @callee(i32 signext %add, i32 signext %ib) + %add1 = add nsw i32 %call, 1 + br label %cleanup + cleanup: ; preds = %if.then, %entry + %retval.0 = phi i32 [ %add1, %if.then ], [ 0, %entry ] + ret i32 %retval.0 + } + declare void @llvm.ppc.MBB_dominated(i32, i32, i32 immarg) #2 +... + +--- +name: callee +alignment: 16 +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x3, $x4 + %1:g8rc = COPY $x4 + %0:g8rc = COPY $x3 + %2:gprc = COPY %0.sub_32 + %3:gprc = COPY %1.sub_32 + %4:gprc = nsw ADD4 killed %3, killed %2 + %5:g8rc = EXTSW_32_64 killed %4 + $x3 = COPY %5 + BLR8 implicit $lr8, implicit $rm, implicit $x3 + +... + +--- +name: test_MBB_dominated +alignment: 16 +tracksRegLiveness: true +body: | + bb.0.entry: + successors: %bb.2(0x40000000), %bb.1(0x40000000) + liveins: $x3, $x4 + %3:g8rc = COPY $x4 + %2:g8rc = COPY $x3 + %5:gprc = COPY %3.sub_32 + %4:gprc_and_gprc_nor0 = COPY %2.sub_32 + %7:gprc = LI 3 + TW 4, %7, %7 + %6:gprc = LI 0 + %8:crrc = CMPW %4, %5 + BCC 12, killed %8, %bb.2 + B %bb.1 + bb.1.if.then: + successors: %bb.2(0x80000000) + %9:gprc = nsw ADDI %4, 1 + ADJCALLSTACKDOWN 112, 0, implicit-def dead $r1, implicit $r1 + %10:g8rc = EXTSW_32_64 %5 + %11:g8rc = EXTSW_32_64 killed %9 + $x3 = COPY %11 + $x4 = COPY %10 + BL8 @callee, csr_ppc64_altivec, implicit-def dead $lr8, implicit $rm, implicit $x3, implicit $x4, implicit-def $r1, implicit-def $x3 + ADJCALLSTACKUP 112, 0, implicit-def dead $r1, implicit $r1 + %12:g8rc = COPY $x3 + %13:gprc_and_gprc_nor0 = COPY %12.sub_32 + %0:gprc = nsw ADDI killed %13, 1 + bb.2.cleanup: + %1:gprc = PHI %6, %bb.0, %0, %bb.1 + %14:g8rc = EXTSW_32_64 %1 + $x3 = COPY %14 + BLR8 implicit $lr8, implicit $rm, implicit $x3 +... + # CHECK-MIR-LABEL: test_MBB_dominated + # CHECK-MIR: bb.0.entry: + # CHECK-MIR: successors: %bb.2(0x40000000), %bb.1(0x40000000) + # CHECK-MIR: liveins: $x3, $x4 + # CHECK-MIR: %0:g8rc = COPY $x4 + # CHECK-MIR-NEXT: %1:g8rc = COPY $x3 + # CHECK-MIR-NEXT: %2:gprc = COPY %0.sub_32 + # CHECK-MIR-NEXT: %3:gprc_and_gprc_nor0 = COPY %1.sub_32 + # CHECK-MIR-NEXT: %4:gprc = LI 3 + # CHECK-MIR-NEXT: %5:gprc = IMPLICIT_DEF + # CHECK-MIR-NEXT: %6:crrc = IMPLICIT_DEF + # CHECK-MIR-NEXT: TRAP + + # CHECK-MIR: bb.1.if.then: + # CHECK-MIR-NEXT: successors: %bb.2(0x80000000) + # CHECK-MIR: %7:gprc = nsw ADDI %3, 1 + # CHECK-MIR-NEXT: ADJCALLSTACKDOWN 112, 0, implicit-def dead $r1, implicit $r1 + # CHECK-MIR-NEXT: %8:g8rc = EXTSW_32_64 %2 + # CHECK-MIR-NEXT: %9:g8rc = EXTSW_32_64 killed %7 + # CHECK-MIR-NEXT: $x3 = COPY %9 + # CHECK-MIR-NEXT: $x4 = COPY %8 + # CHECK-MIR-NEXT: BL8 @callee, + # CHECK-MIR-NEXT: ADJCALLSTACKUP 112, 0, implicit-def dead $r1, implicit $r1 + # CHECK-MIR-NEXT: %10:g8rc = COPY $x3 + # CHECK-MIR-NEXT: %11:gprc_and_gprc_nor0 = COPY %10.sub_32 + # CHECK-MIR-NEXT: %12:gprc = nsw ADDI killed %11, 1 + + # CHECK-MIR: bb.2.cleanup: + # CHECK-MIR-NEXT: %13:gprc = PHI %5, %bb.0, %12, %bb.1 + # CHECK-MIR-NEXT: %14:g8rc = EXTSW_32_64 %13 + # CHECK-MIR-NEXT: $x3 = COPY %14 + # CHECK-MIR-NEXT: BLR8 implicit $lr8, implicit $rm, implicit $x3 + + + # CHECK-LABEL: test_MBB_dominated + # CHECK: # %bb.0: # %entry + # CHECK: trap + # CHECK-NEXT: .LBB1_1: # %if.then + # CHECK-NEXT: mflr 0 + # CHECK-NEXT: std 0, 16(1) + # CHECK-NEXT: stdu 1, -128(1) + # CHECK: addi 3, 3, 1 + # CHECK-NEXT: extsw 4, 4 + # CHECK-NEXT: std 2, 120(1) + # CHECK-NEXT: extsw 3, 3 + # CHECK-NEXT: bl callee + # CHECK-NEXT: ld 2, 120(1) + # CHECK-NEXT: addi 5, 3, 1 + # CHECK-NEXT: addi 1, 1, 128 + # CHECK-NEXT: ld 0, 16(1) + # CHECK-NEXT: mtlr 0 + # CHECK-NEXT: .LBB1_2: # %cleanup + # CHECK-NEXT: extsw 3, 5 + # CHECK-NEXT: blr