diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -738,32 +738,52 @@ } static MachineBasicBlock *insertDivByZeroTrap(MachineInstr &MI, - MachineBasicBlock &MBB, - const TargetInstrInfo &TII) { + MachineBasicBlock *MBB) { if (!ZeroDivCheck) - return &MBB; + return MBB; // Build instructions: + // MBB: // div(or mod) $dst, $dividend, $divisor - // bnez $divisor, 8 - // break 7 + // bnez $divisor, SinkMBB + // BreakMBB: + // break 7 // BRK_DIVZERO + // SinkMBB: // fallthrough + const BasicBlock *LLVM_BB = MBB->getBasicBlock(); + MachineFunction::iterator It = ++MBB->getIterator(); + MachineFunction *MF = MBB->getParent(); + auto BreakMBB = MF->CreateMachineBasicBlock(LLVM_BB); + auto SinkMBB = MF->CreateMachineBasicBlock(LLVM_BB); + MF->insert(It, BreakMBB); + MF->insert(It, SinkMBB); + + // Transfer the remainder of MBB and its successor edges to SinkMBB. + SinkMBB->splice(SinkMBB->end(), MBB, std::next(MI.getIterator()), MBB->end()); + SinkMBB->transferSuccessorsAndUpdatePHIs(MBB); + + const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo(); + DebugLoc DL = MI.getDebugLoc(); MachineOperand &Divisor = MI.getOperand(2); - auto FallThrough = std::next(MI.getIterator()); + Register DivisorReg = Divisor.getReg(); - BuildMI(MBB, FallThrough, MI.getDebugLoc(), TII.get(LoongArch::BNEZ)) - .addReg(Divisor.getReg(), getKillRegState(Divisor.isKill())) - .addImm(8); + // MBB: + BuildMI(MBB, DL, TII.get(LoongArch::BNEZ)) + .addReg(DivisorReg, getKillRegState(Divisor.isKill())) + .addMBB(SinkMBB); + MBB->addSuccessor(BreakMBB); + MBB->addSuccessor(SinkMBB); + // BreakMBB: // See linux header file arch/loongarch/include/uapi/asm/break.h for the // definition of BRK_DIVZERO. - BuildMI(MBB, FallThrough, MI.getDebugLoc(), TII.get(LoongArch::BREAK)) - .addImm(7/*BRK_DIVZERO*/); + BuildMI(BreakMBB, DL, TII.get(LoongArch::BREAK)).addImm(7 /*BRK_DIVZERO*/); + BreakMBB->addSuccessor(SinkMBB); // Clear Divisor's kill flag. Divisor.setIsKill(false); - return &MBB; + return SinkMBB; } MachineBasicBlock *LoongArchTargetLowering::EmitInstrWithCustomInserter( @@ -780,7 +800,7 @@ case LoongArch::DIV_DU: case LoongArch::MOD_D: case LoongArch::MOD_DU: - return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo()); + return insertDivByZeroTrap(MI, BB); break; } } diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem.ll --- a/llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem.ll @@ -49,8 +49,10 @@ ; LA32-TRAP-NEXT: ext.w.b $a1, $a1 ; LA32-TRAP-NEXT: ext.w.b $a0, $a0 ; LA32-TRAP-NEXT: div.w $a0, $a0, $a1 -; LA32-TRAP-NEXT: bnez $a1, 8 +; LA32-TRAP-NEXT: bnez $a1, .LBB1_2 +; LA32-TRAP-NEXT: # %bb.1: # %entry ; LA32-TRAP-NEXT: break 7 +; LA32-TRAP-NEXT: .LBB1_2: # %entry ; LA32-TRAP-NEXT: jirl $zero, $ra, 0 ; ; LA64-TRAP-LABEL: sdiv_i8: @@ -58,8 +60,10 @@ ; LA64-TRAP-NEXT: ext.w.b $a1, $a1 ; LA64-TRAP-NEXT: ext.w.b $a0, $a0 ; LA64-TRAP-NEXT: div.d $a0, $a0, $a1 -; LA64-TRAP-NEXT: bnez $a1, 8 +; LA64-TRAP-NEXT: bnez $a1, .LBB1_2 +; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 +; LA64-TRAP-NEXT: .LBB1_2: # %entry ; LA64-TRAP-NEXT: jirl $zero, $ra, 0 entry: %r = sdiv i8 %a, %b @@ -86,8 +90,10 @@ ; LA32-TRAP-NEXT: ext.w.h $a1, $a1 ; LA32-TRAP-NEXT: ext.w.h $a0, $a0 ; LA32-TRAP-NEXT: div.w $a0, $a0, $a1 -; LA32-TRAP-NEXT: bnez $a1, 8 +; LA32-TRAP-NEXT: bnez $a1, .LBB2_2 +; LA32-TRAP-NEXT: # %bb.1: # %entry ; LA32-TRAP-NEXT: break 7 +; LA32-TRAP-NEXT: .LBB2_2: # %entry ; LA32-TRAP-NEXT: jirl $zero, $ra, 0 ; ; LA64-TRAP-LABEL: sdiv_i16: @@ -95,8 +101,10 @@ ; LA64-TRAP-NEXT: ext.w.h $a1, $a1 ; LA64-TRAP-NEXT: ext.w.h $a0, $a0 ; LA64-TRAP-NEXT: div.d $a0, $a0, $a1 -; LA64-TRAP-NEXT: bnez $a1, 8 +; LA64-TRAP-NEXT: bnez $a1, .LBB2_2 +; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 +; LA64-TRAP-NEXT: .LBB2_2: # %entry ; LA64-TRAP-NEXT: jirl $zero, $ra, 0 entry: %r = sdiv i16 %a, %b @@ -119,8 +127,10 @@ ; LA32-TRAP-LABEL: sdiv_i32: ; LA32-TRAP: # %bb.0: # %entry ; LA32-TRAP-NEXT: div.w $a0, $a0, $a1 -; LA32-TRAP-NEXT: bnez $a1, 8 +; LA32-TRAP-NEXT: bnez $a1, .LBB3_2 +; LA32-TRAP-NEXT: # %bb.1: # %entry ; LA32-TRAP-NEXT: break 7 +; LA32-TRAP-NEXT: .LBB3_2: # %entry ; LA32-TRAP-NEXT: jirl $zero, $ra, 0 ; ; LA64-TRAP-LABEL: sdiv_i32: @@ -128,8 +138,10 @@ ; LA64-TRAP-NEXT: addi.w $a1, $a1, 0 ; LA64-TRAP-NEXT: addi.w $a0, $a0, 0 ; LA64-TRAP-NEXT: div.d $a0, $a0, $a1 -; LA64-TRAP-NEXT: bnez $a1, 8 +; LA64-TRAP-NEXT: bnez $a1, .LBB3_2 +; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 +; LA64-TRAP-NEXT: .LBB3_2: # %entry ; LA64-TRAP-NEXT: jirl $zero, $ra, 0 entry: %r = sdiv i32 %a, %b @@ -167,8 +179,10 @@ ; LA64-TRAP-LABEL: sdiv_i64: ; LA64-TRAP: # %bb.0: # %entry ; LA64-TRAP-NEXT: div.d $a0, $a0, $a1 -; LA64-TRAP-NEXT: bnez $a1, 8 +; LA64-TRAP-NEXT: bnez $a1, .LBB4_2 +; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 +; LA64-TRAP-NEXT: .LBB4_2: # %entry ; LA64-TRAP-NEXT: jirl $zero, $ra, 0 entry: %r = sdiv i64 %a, %b @@ -216,8 +230,10 @@ ; LA32-TRAP-NEXT: andi $a1, $a1, 255 ; LA32-TRAP-NEXT: andi $a0, $a0, 255 ; LA32-TRAP-NEXT: div.wu $a0, $a0, $a1 -; LA32-TRAP-NEXT: bnez $a1, 8 +; LA32-TRAP-NEXT: bnez $a1, .LBB6_2 +; LA32-TRAP-NEXT: # %bb.1: # %entry ; LA32-TRAP-NEXT: break 7 +; LA32-TRAP-NEXT: .LBB6_2: # %entry ; LA32-TRAP-NEXT: jirl $zero, $ra, 0 ; ; LA64-TRAP-LABEL: udiv_i8: @@ -225,8 +241,10 @@ ; LA64-TRAP-NEXT: andi $a1, $a1, 255 ; LA64-TRAP-NEXT: andi $a0, $a0, 255 ; LA64-TRAP-NEXT: div.du $a0, $a0, $a1 -; LA64-TRAP-NEXT: bnez $a1, 8 +; LA64-TRAP-NEXT: bnez $a1, .LBB6_2 +; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 +; LA64-TRAP-NEXT: .LBB6_2: # %entry ; LA64-TRAP-NEXT: jirl $zero, $ra, 0 entry: %r = udiv i8 %a, %b @@ -253,8 +271,10 @@ ; LA32-TRAP-NEXT: bstrpick.w $a1, $a1, 15, 0 ; LA32-TRAP-NEXT: bstrpick.w $a0, $a0, 15, 0 ; LA32-TRAP-NEXT: div.wu $a0, $a0, $a1 -; LA32-TRAP-NEXT: bnez $a1, 8 +; LA32-TRAP-NEXT: bnez $a1, .LBB7_2 +; LA32-TRAP-NEXT: # %bb.1: # %entry ; LA32-TRAP-NEXT: break 7 +; LA32-TRAP-NEXT: .LBB7_2: # %entry ; LA32-TRAP-NEXT: jirl $zero, $ra, 0 ; ; LA64-TRAP-LABEL: udiv_i16: @@ -262,8 +282,10 @@ ; LA64-TRAP-NEXT: bstrpick.d $a1, $a1, 15, 0 ; LA64-TRAP-NEXT: bstrpick.d $a0, $a0, 15, 0 ; LA64-TRAP-NEXT: div.du $a0, $a0, $a1 -; LA64-TRAP-NEXT: bnez $a1, 8 +; LA64-TRAP-NEXT: bnez $a1, .LBB7_2 +; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 +; LA64-TRAP-NEXT: .LBB7_2: # %entry ; LA64-TRAP-NEXT: jirl $zero, $ra, 0 entry: %r = udiv i16 %a, %b @@ -286,8 +308,10 @@ ; LA32-TRAP-LABEL: udiv_i32: ; LA32-TRAP: # %bb.0: # %entry ; LA32-TRAP-NEXT: div.wu $a0, $a0, $a1 -; LA32-TRAP-NEXT: bnez $a1, 8 +; LA32-TRAP-NEXT: bnez $a1, .LBB8_2 +; LA32-TRAP-NEXT: # %bb.1: # %entry ; LA32-TRAP-NEXT: break 7 +; LA32-TRAP-NEXT: .LBB8_2: # %entry ; LA32-TRAP-NEXT: jirl $zero, $ra, 0 ; ; LA64-TRAP-LABEL: udiv_i32: @@ -295,8 +319,10 @@ ; LA64-TRAP-NEXT: bstrpick.d $a1, $a1, 31, 0 ; LA64-TRAP-NEXT: bstrpick.d $a0, $a0, 31, 0 ; LA64-TRAP-NEXT: div.du $a0, $a0, $a1 -; LA64-TRAP-NEXT: bnez $a1, 8 +; LA64-TRAP-NEXT: bnez $a1, .LBB8_2 +; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 +; LA64-TRAP-NEXT: .LBB8_2: # %entry ; LA64-TRAP-NEXT: jirl $zero, $ra, 0 entry: %r = udiv i32 %a, %b @@ -334,8 +360,10 @@ ; LA64-TRAP-LABEL: udiv_i64: ; LA64-TRAP: # %bb.0: # %entry ; LA64-TRAP-NEXT: div.du $a0, $a0, $a1 -; LA64-TRAP-NEXT: bnez $a1, 8 +; LA64-TRAP-NEXT: bnez $a1, .LBB9_2 +; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 +; LA64-TRAP-NEXT: .LBB9_2: # %entry ; LA64-TRAP-NEXT: jirl $zero, $ra, 0 entry: %r = udiv i64 %a, %b @@ -387,8 +415,10 @@ ; LA32-TRAP-NEXT: ext.w.b $a1, $a1 ; LA32-TRAP-NEXT: ext.w.b $a0, $a0 ; LA32-TRAP-NEXT: mod.w $a0, $a0, $a1 -; LA32-TRAP-NEXT: bnez $a1, 8 +; LA32-TRAP-NEXT: bnez $a1, .LBB11_2 +; LA32-TRAP-NEXT: # %bb.1: # %entry ; LA32-TRAP-NEXT: break 7 +; LA32-TRAP-NEXT: .LBB11_2: # %entry ; LA32-TRAP-NEXT: jirl $zero, $ra, 0 ; ; LA64-TRAP-LABEL: srem_i8: @@ -396,8 +426,10 @@ ; LA64-TRAP-NEXT: ext.w.b $a1, $a1 ; LA64-TRAP-NEXT: ext.w.b $a0, $a0 ; LA64-TRAP-NEXT: mod.d $a0, $a0, $a1 -; LA64-TRAP-NEXT: bnez $a1, 8 +; LA64-TRAP-NEXT: bnez $a1, .LBB11_2 +; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 +; LA64-TRAP-NEXT: .LBB11_2: # %entry ; LA64-TRAP-NEXT: jirl $zero, $ra, 0 entry: %r = srem i8 %a, %b @@ -424,8 +456,10 @@ ; LA32-TRAP-NEXT: ext.w.h $a1, $a1 ; LA32-TRAP-NEXT: ext.w.h $a0, $a0 ; LA32-TRAP-NEXT: mod.w $a0, $a0, $a1 -; LA32-TRAP-NEXT: bnez $a1, 8 +; LA32-TRAP-NEXT: bnez $a1, .LBB12_2 +; LA32-TRAP-NEXT: # %bb.1: # %entry ; LA32-TRAP-NEXT: break 7 +; LA32-TRAP-NEXT: .LBB12_2: # %entry ; LA32-TRAP-NEXT: jirl $zero, $ra, 0 ; ; LA64-TRAP-LABEL: srem_i16: @@ -433,8 +467,10 @@ ; LA64-TRAP-NEXT: ext.w.h $a1, $a1 ; LA64-TRAP-NEXT: ext.w.h $a0, $a0 ; LA64-TRAP-NEXT: mod.d $a0, $a0, $a1 -; LA64-TRAP-NEXT: bnez $a1, 8 +; LA64-TRAP-NEXT: bnez $a1, .LBB12_2 +; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 +; LA64-TRAP-NEXT: .LBB12_2: # %entry ; LA64-TRAP-NEXT: jirl $zero, $ra, 0 entry: %r = srem i16 %a, %b @@ -457,8 +493,10 @@ ; LA32-TRAP-LABEL: srem_i32: ; LA32-TRAP: # %bb.0: # %entry ; LA32-TRAP-NEXT: mod.w $a0, $a0, $a1 -; LA32-TRAP-NEXT: bnez $a1, 8 +; LA32-TRAP-NEXT: bnez $a1, .LBB13_2 +; LA32-TRAP-NEXT: # %bb.1: # %entry ; LA32-TRAP-NEXT: break 7 +; LA32-TRAP-NEXT: .LBB13_2: # %entry ; LA32-TRAP-NEXT: jirl $zero, $ra, 0 ; ; LA64-TRAP-LABEL: srem_i32: @@ -466,8 +504,10 @@ ; LA64-TRAP-NEXT: addi.w $a1, $a1, 0 ; LA64-TRAP-NEXT: addi.w $a0, $a0, 0 ; LA64-TRAP-NEXT: mod.d $a0, $a0, $a1 -; LA64-TRAP-NEXT: bnez $a1, 8 +; LA64-TRAP-NEXT: bnez $a1, .LBB13_2 +; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 +; LA64-TRAP-NEXT: .LBB13_2: # %entry ; LA64-TRAP-NEXT: jirl $zero, $ra, 0 entry: %r = srem i32 %a, %b @@ -505,8 +545,10 @@ ; LA64-TRAP-LABEL: srem_i64: ; LA64-TRAP: # %bb.0: # %entry ; LA64-TRAP-NEXT: mod.d $a0, $a0, $a1 -; LA64-TRAP-NEXT: bnez $a1, 8 +; LA64-TRAP-NEXT: bnez $a1, .LBB14_2 +; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 +; LA64-TRAP-NEXT: .LBB14_2: # %entry ; LA64-TRAP-NEXT: jirl $zero, $ra, 0 entry: %r = srem i64 %a, %b @@ -558,8 +600,10 @@ ; LA32-TRAP-NEXT: andi $a1, $a1, 255 ; LA32-TRAP-NEXT: andi $a0, $a0, 255 ; LA32-TRAP-NEXT: mod.wu $a0, $a0, $a1 -; LA32-TRAP-NEXT: bnez $a1, 8 +; LA32-TRAP-NEXT: bnez $a1, .LBB16_2 +; LA32-TRAP-NEXT: # %bb.1: # %entry ; LA32-TRAP-NEXT: break 7 +; LA32-TRAP-NEXT: .LBB16_2: # %entry ; LA32-TRAP-NEXT: jirl $zero, $ra, 0 ; ; LA64-TRAP-LABEL: urem_i8: @@ -567,8 +611,10 @@ ; LA64-TRAP-NEXT: andi $a1, $a1, 255 ; LA64-TRAP-NEXT: andi $a0, $a0, 255 ; LA64-TRAP-NEXT: mod.du $a0, $a0, $a1 -; LA64-TRAP-NEXT: bnez $a1, 8 +; LA64-TRAP-NEXT: bnez $a1, .LBB16_2 +; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 +; LA64-TRAP-NEXT: .LBB16_2: # %entry ; LA64-TRAP-NEXT: jirl $zero, $ra, 0 entry: %r = urem i8 %a, %b @@ -595,8 +641,10 @@ ; LA32-TRAP-NEXT: bstrpick.w $a1, $a1, 15, 0 ; LA32-TRAP-NEXT: bstrpick.w $a0, $a0, 15, 0 ; LA32-TRAP-NEXT: mod.wu $a0, $a0, $a1 -; LA32-TRAP-NEXT: bnez $a1, 8 +; LA32-TRAP-NEXT: bnez $a1, .LBB17_2 +; LA32-TRAP-NEXT: # %bb.1: # %entry ; LA32-TRAP-NEXT: break 7 +; LA32-TRAP-NEXT: .LBB17_2: # %entry ; LA32-TRAP-NEXT: jirl $zero, $ra, 0 ; ; LA64-TRAP-LABEL: urem_i16: @@ -604,8 +652,10 @@ ; LA64-TRAP-NEXT: bstrpick.d $a1, $a1, 15, 0 ; LA64-TRAP-NEXT: bstrpick.d $a0, $a0, 15, 0 ; LA64-TRAP-NEXT: mod.du $a0, $a0, $a1 -; LA64-TRAP-NEXT: bnez $a1, 8 +; LA64-TRAP-NEXT: bnez $a1, .LBB17_2 +; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 +; LA64-TRAP-NEXT: .LBB17_2: # %entry ; LA64-TRAP-NEXT: jirl $zero, $ra, 0 entry: %r = urem i16 %a, %b @@ -628,8 +678,10 @@ ; LA32-TRAP-LABEL: urem_i32: ; LA32-TRAP: # %bb.0: # %entry ; LA32-TRAP-NEXT: mod.wu $a0, $a0, $a1 -; LA32-TRAP-NEXT: bnez $a1, 8 +; LA32-TRAP-NEXT: bnez $a1, .LBB18_2 +; LA32-TRAP-NEXT: # %bb.1: # %entry ; LA32-TRAP-NEXT: break 7 +; LA32-TRAP-NEXT: .LBB18_2: # %entry ; LA32-TRAP-NEXT: jirl $zero, $ra, 0 ; ; LA64-TRAP-LABEL: urem_i32: @@ -637,8 +689,10 @@ ; LA64-TRAP-NEXT: bstrpick.d $a1, $a1, 31, 0 ; LA64-TRAP-NEXT: bstrpick.d $a0, $a0, 31, 0 ; LA64-TRAP-NEXT: mod.du $a0, $a0, $a1 -; LA64-TRAP-NEXT: bnez $a1, 8 +; LA64-TRAP-NEXT: bnez $a1, .LBB18_2 +; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 +; LA64-TRAP-NEXT: .LBB18_2: # %entry ; LA64-TRAP-NEXT: jirl $zero, $ra, 0 entry: %r = urem i32 %a, %b @@ -676,8 +730,10 @@ ; LA64-TRAP-LABEL: urem_i64: ; LA64-TRAP: # %bb.0: # %entry ; LA64-TRAP-NEXT: mod.du $a0, $a0, $a1 -; LA64-TRAP-NEXT: bnez $a1, 8 +; LA64-TRAP-NEXT: bnez $a1, .LBB19_2 +; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 +; LA64-TRAP-NEXT: .LBB19_2: # %entry ; LA64-TRAP-NEXT: jirl $zero, $ra, 0 entry: %r = urem i64 %a, %b