[llvm] [Mips] Handle division by zero trap on MIPS1 (PR #201133)

via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 13 09:37:38 PDT 2026


https://github.com/neoto updated https://github.com/llvm/llvm-project/pull/201133

>From bb943ba552732ea250c32bc2c6afd5b015af9ebf Mon Sep 17 00:00:00 2001
From: Leon Lombar <leon at makase.ro>
Date: Sun, 13 Sep 2026 18:27:56 +0200
Subject: [PATCH] [Mips] Handle division by zero trap on MIPS1

Special cases MIPS1 so that LLVM emits `bnez` and `break` instead of `teq`
---
 llvm/lib/Target/Mips/MipsISelLowering.cpp | 75 +++++++++++++++---
 llvm/lib/Target/Mips/MipsInstrInfo.td     |  4 +-
 llvm/test/CodeGen/Mips/llvm-ir/sdiv.ll    | 88 ++++++++++++++++++++++
 llvm/test/CodeGen/Mips/llvm-ir/srem.ll    | 86 +++++++++++++++++++++
 llvm/test/CodeGen/Mips/llvm-ir/udiv.ll    | 86 +++++++++++++++++++++
 llvm/test/CodeGen/Mips/llvm-ir/urem.ll    | 92 +++++++++++++++++++++++
 6 files changed, 419 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index bfbcad786c965..a75960fd2af76 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -94,6 +94,12 @@ static const MCPhysReg Mips64DPRegs[8] = {
   Mips::D16_64, Mips::D17_64, Mips::D18_64, Mips::D19_64
 };
 
+enum class DivByZeroTrapKind {
+  Break, // MIPS I
+  Teq,   // MIPS II+
+  TeqMM, // microMIPS
+};
+
 // The MIPS MSA ABI passes vector arguments in the integer register set.
 // The number of integer registers used is dependant on the ABI used.
 MVT MipsTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
@@ -1279,19 +1285,62 @@ addLiveIn(MachineFunction &MF, unsigned PReg, const TargetRegisterClass *RC)
   return VReg;
 }
 
-static MachineBasicBlock *insertDivByZeroTrap(MachineInstr &MI,
-                                              MachineBasicBlock &MBB,
-                                              const TargetInstrInfo &TII,
-                                              bool Is64Bit, bool IsMicroMips) {
+static MachineBasicBlock *
+insertDivByZeroTrap(MachineInstr &MI, MachineBasicBlock &MBB,
+                    const TargetInstrInfo &TII, bool Is64Bit,
+                    const DivByZeroTrapKind TrapKind) {
   if (NoZeroDivCheck)
     return &MBB;
 
+  MachineOperand &Divisor = MI.getOperand(2);
+
+  if (TrapKind == DivByZeroTrapKind::Break) {
+    // Build instructions:
+    // MBB:
+    //   bnez     $divisor, $zero, SinkMBB
+    //   MI       $dst, $dividend, $divisor (delay slot)
+    //
+    // BreakMBB:
+    //   break    7
+    //
+    // SinkMBB:
+    //   fallthrough
+    const DebugLoc &DL = MI.getDebugLoc();
+    const BasicBlock *BB = MBB.getBasicBlock();
+
+    // Place all instructions after MI into SinkMBB.
+    MachineBasicBlock *SinkMBB = MBB.splitAt(MI, true);
+
+    // BreakMBB setup.
+    MachineFunction *MF = MBB.getParent();
+    MachineBasicBlock *BreakMBB = MF->CreateMachineBasicBlock(BB);
+    MF->insert(++MBB.getIterator(), BreakMBB);
+
+    // Place the branch at the end of the block. Since MI is defined as having
+    // no side effects in TableGen, the filler will place it in the branch delay
+    // slot.
+    BuildMI(&MBB, DL, TII.get(Mips::BNE))
+        .addReg(Divisor.getReg(), getKillRegState(Divisor.isKill()))
+        .addReg(Mips::ZERO)
+        .addMBB(SinkMBB);
+
+    // BreakMBB: break 7
+    BuildMI(BreakMBB, DL, TII.get(Mips::BREAK)).addImm(7).addImm(0);
+
+    MBB.addSuccessor(BreakMBB);
+    BreakMBB->addSuccessor(SinkMBB);
+
+    Divisor.setIsKill(false);
+
+    return SinkMBB;
+  }
+
   // Insert instruction "teq $divisor_reg, $zero, 7".
   MachineBasicBlock::iterator I(MI);
   MachineInstrBuilder MIB;
-  MachineOperand &Divisor = MI.getOperand(2);
   MIB = BuildMI(MBB, std::next(I), MI.getDebugLoc(),
-                TII.get(IsMicroMips ? Mips::TEQ_MM : Mips::TEQ))
+                TII.get(TrapKind == DivByZeroTrapKind::TeqMM ? Mips::TEQ_MM
+                                                             : Mips::TEQ))
             .addReg(Divisor.getReg(), getKillRegState(Divisor.isKill()))
             .addReg(Mips::ZERO)
             .addImm(7);
@@ -1428,9 +1477,13 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
   case Mips::DIV:
   case Mips::DIVU:
   case Mips::MOD:
-  case Mips::MODU:
+  case Mips::MODU: {
+    const DivByZeroTrapKind TrapKind = !Subtarget.hasMips2()
+                                           ? DivByZeroTrapKind::Break
+                                           : DivByZeroTrapKind::Teq;
     return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), false,
-                               false);
+                               TrapKind);
+  }
   case Mips::SDIV_MM_Pseudo:
   case Mips::UDIV_MM_Pseudo:
   case Mips::SDIV_MM:
@@ -1439,14 +1492,16 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
   case Mips::DIVU_MMR6:
   case Mips::MOD_MMR6:
   case Mips::MODU_MMR6:
-    return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), false, true);
+    return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), false,
+                               DivByZeroTrapKind::TeqMM);
   case Mips::PseudoDSDIV:
   case Mips::PseudoDUDIV:
   case Mips::DDIV:
   case Mips::DDIVU:
   case Mips::DMOD:
   case Mips::DMODU:
-    return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), true, false);
+    return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), true,
+                               DivByZeroTrapKind::Teq);
 
   case Mips::PseudoSELECT_I:
   case Mips::PseudoSELECT_I64:
diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td
index ccbf2d5f2aa05..6ffd94c9a72ea 100644
--- a/llvm/lib/Target/Mips/MipsInstrInfo.td
+++ b/llvm/lib/Target/Mips/MipsInstrInfo.td
@@ -2453,9 +2453,9 @@ def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu>,
 
 let AdditionalPredicates = [NotInMicroMips] in {
   def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem,
-                                 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
+                                 0, 0, 1>, ISA_MIPS1_NOT_32R6_64R6;
   def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU,
-                                 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
+                                 0, 0, 1>, ISA_MIPS1_NOT_32R6_64R6;
   def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM, ISA_MIPS1;
   // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction
   def EXT : MMRel, StdMMR6Rel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1,
diff --git a/llvm/test/CodeGen/Mips/llvm-ir/sdiv.ll b/llvm/test/CodeGen/Mips/llvm-ir/sdiv.ll
index 72cead18f89fa..91a45a88df90a 100644
--- a/llvm/test/CodeGen/Mips/llvm-ir/sdiv.ll
+++ b/llvm/test/CodeGen/Mips/llvm-ir/sdiv.ll
@@ -1,4 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=mips -mcpu=mips1 -relocation-model=pic \
+; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefix=MIPS1
 ; RUN: llc < %s -mtriple=mips -mcpu=mips2 -relocation-model=pic \
 ; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefixes=MIPS2
 ; RUN: llc < %s -mtriple=mips -mcpu=mips32 -relocation-model=pic \
@@ -35,6 +37,11 @@
 ; RUN:   FileCheck %s -check-prefix=MMR6
 
 define signext i1 @sdiv_i1(i1 signext %a, i1 signext %b) {
+; MIPS1-LABEL: sdiv_i1:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    move $2, $4
+;
 ; MIPS2-LABEL: sdiv_i1:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    jr $ra
@@ -80,6 +87,18 @@ entry:
 }
 
 define signext i8 @sdiv_i8(i8 signext %a, i8 signext %b) {
+; MIPS1-LABEL: sdiv_i8:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    bnez $5, $BB1_2
+; MIPS1-NEXT:    div $zero, $4, $5
+; MIPS1-NEXT:  # %bb.1: # %entry
+; MIPS1-NEXT:    break 7
+; MIPS1-NEXT:  $BB1_2: # %entry
+; MIPS1-NEXT:    mflo $1
+; MIPS1-NEXT:    sll $1, $1, 24
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    sra $2, $1, 24
+;
 ; MIPS2-LABEL: sdiv_i8:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    div $zero, $4, $5
@@ -166,6 +185,18 @@ entry:
 }
 
 define signext i16 @sdiv_i16(i16 signext %a, i16 signext %b) {
+; MIPS1-LABEL: sdiv_i16:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    bnez $5, $BB2_2
+; MIPS1-NEXT:    div $zero, $4, $5
+; MIPS1-NEXT:  # %bb.1: # %entry
+; MIPS1-NEXT:    break 7
+; MIPS1-NEXT:  $BB2_2: # %entry
+; MIPS1-NEXT:    mflo $1
+; MIPS1-NEXT:    sll $1, $1, 16
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    sra $2, $1, 16
+;
 ; MIPS2-LABEL: sdiv_i16:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    div $zero, $4, $5
@@ -252,6 +283,17 @@ entry:
 }
 
 define signext i32 @sdiv_i32(i32 signext %a, i32 signext %b) {
+; MIPS1-LABEL: sdiv_i32:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    bnez $5, $BB3_2
+; MIPS1-NEXT:    div $zero, $4, $5
+; MIPS1-NEXT:  # %bb.1: # %entry
+; MIPS1-NEXT:    break 7
+; MIPS1-NEXT:  $BB3_2: # %entry
+; MIPS1-NEXT:    mflo $2
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    nop
+;
 ; MIPS2-LABEL: sdiv_i32:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    div $zero, $4, $5
@@ -312,6 +354,24 @@ entry:
 }
 
 define signext i64 @sdiv_i64(i64 signext %a, i64 signext %b) {
+; MIPS1-LABEL: sdiv_i64:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    lui $2, %hi(_gp_disp)
+; MIPS1-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; MIPS1-NEXT:    addiu $sp, $sp, -24
+; MIPS1-NEXT:    .cfi_def_cfa_offset 24
+; MIPS1-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
+; MIPS1-NEXT:    .cfi_offset 31, -4
+; MIPS1-NEXT:    addu $gp, $2, $25
+; MIPS1-NEXT:    lw $25, %call16(__divdi3)($gp)
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    jalr $25
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    addiu $sp, $sp, 24
+;
 ; MIPS2-LABEL: sdiv_i64:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    lui $2, %hi(_gp_disp)
@@ -416,6 +476,34 @@ entry:
 }
 
 define signext i128 @sdiv_i128(i128 signext %a, i128 signext %b) {
+; MIPS1-LABEL: sdiv_i128:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    lui $2, %hi(_gp_disp)
+; MIPS1-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; MIPS1-NEXT:    addiu $sp, $sp, -40
+; MIPS1-NEXT:    .cfi_def_cfa_offset 40
+; MIPS1-NEXT:    sw $ra, 36($sp) # 4-byte Folded Spill
+; MIPS1-NEXT:    .cfi_offset 31, -4
+; MIPS1-NEXT:    addu $gp, $2, $25
+; MIPS1-NEXT:    lw $1, 60($sp)
+; MIPS1-NEXT:    lw $2, 64($sp)
+; MIPS1-NEXT:    lw $3, 68($sp)
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    sw $3, 28($sp)
+; MIPS1-NEXT:    sw $2, 24($sp)
+; MIPS1-NEXT:    sw $1, 20($sp)
+; MIPS1-NEXT:    lw $1, 56($sp)
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    sw $1, 16($sp)
+; MIPS1-NEXT:    lw $25, %call16(__divti3)($gp)
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    jalr $25
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    lw $ra, 36($sp) # 4-byte Folded Reload
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    addiu $sp, $sp, 40
+;
 ; MIPS2-LABEL: sdiv_i128:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    lui $2, %hi(_gp_disp)
diff --git a/llvm/test/CodeGen/Mips/llvm-ir/srem.ll b/llvm/test/CodeGen/Mips/llvm-ir/srem.ll
index 72496fcc53a5a..de166d6f26abc 100644
--- a/llvm/test/CodeGen/Mips/llvm-ir/srem.ll
+++ b/llvm/test/CodeGen/Mips/llvm-ir/srem.ll
@@ -1,4 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=mips -mcpu=mips1 -relocation-model=pic \
+; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefix=MIPS1
 ; RUN: llc < %s -mtriple=mips -mcpu=mips2 -relocation-model=pic \
 ; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefixes=MIPS2
 ; RUN: llc < %s -mtriple=mips -mcpu=mips32 -relocation-model=pic \
@@ -35,6 +37,11 @@
 ; RUN:   FileCheck %s -check-prefix=MMR6
 
 define signext i1 @srem_i1(i1 signext %a, i1 signext %b) {
+; MIPS1-LABEL: srem_i1:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    addiu $2, $zero, 0
+;
 ; MIPS2-LABEL: srem_i1:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    jr $ra
@@ -80,6 +87,17 @@ entry:
 }
 
 define signext i8 @srem_i8(i8 signext %a, i8 signext %b) {
+; MIPS1-LABEL: srem_i8:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    bnez $5, $BB1_2
+; MIPS1-NEXT:    div $zero, $4, $5
+; MIPS1-NEXT:  # %bb.1: # %entry
+; MIPS1-NEXT:    break 7
+; MIPS1-NEXT:  $BB1_2: # %entry
+; MIPS1-NEXT:    mfhi $2
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    nop
+;
 ; MIPS2-LABEL: srem_i8:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    div $zero, $4, $5
@@ -140,6 +158,17 @@ entry:
 }
 
 define signext i16 @srem_i16(i16 signext %a, i16 signext %b) {
+; MIPS1-LABEL: srem_i16:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    bnez $5, $BB2_2
+; MIPS1-NEXT:    div $zero, $4, $5
+; MIPS1-NEXT:  # %bb.1: # %entry
+; MIPS1-NEXT:    break 7
+; MIPS1-NEXT:  $BB2_2: # %entry
+; MIPS1-NEXT:    mfhi $2
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    nop
+;
 ; MIPS2-LABEL: srem_i16:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    div $zero, $4, $5
@@ -200,6 +229,17 @@ entry:
 }
 
 define signext i32 @srem_i32(i32 signext %a, i32 signext %b) {
+; MIPS1-LABEL: srem_i32:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    bnez $5, $BB3_2
+; MIPS1-NEXT:    div $zero, $4, $5
+; MIPS1-NEXT:  # %bb.1: # %entry
+; MIPS1-NEXT:    break 7
+; MIPS1-NEXT:  $BB3_2: # %entry
+; MIPS1-NEXT:    mfhi $2
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    nop
+;
 ; MIPS2-LABEL: srem_i32:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    div $zero, $4, $5
@@ -260,6 +300,24 @@ entry:
 }
 
 define signext i64 @srem_i64(i64 signext %a, i64 signext %b) {
+; MIPS1-LABEL: srem_i64:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    lui $2, %hi(_gp_disp)
+; MIPS1-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; MIPS1-NEXT:    addiu $sp, $sp, -24
+; MIPS1-NEXT:    .cfi_def_cfa_offset 24
+; MIPS1-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
+; MIPS1-NEXT:    .cfi_offset 31, -4
+; MIPS1-NEXT:    addu $gp, $2, $25
+; MIPS1-NEXT:    lw $25, %call16(__moddi3)($gp)
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    jalr $25
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    addiu $sp, $sp, 24
+;
 ; MIPS2-LABEL: srem_i64:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    lui $2, %hi(_gp_disp)
@@ -364,6 +422,34 @@ entry:
 }
 
 define signext i128 @srem_i128(i128 signext %a, i128 signext %b) {
+; MIPS1-LABEL: srem_i128:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    lui $2, %hi(_gp_disp)
+; MIPS1-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; MIPS1-NEXT:    addiu $sp, $sp, -40
+; MIPS1-NEXT:    .cfi_def_cfa_offset 40
+; MIPS1-NEXT:    sw $ra, 36($sp) # 4-byte Folded Spill
+; MIPS1-NEXT:    .cfi_offset 31, -4
+; MIPS1-NEXT:    addu $gp, $2, $25
+; MIPS1-NEXT:    lw $1, 60($sp)
+; MIPS1-NEXT:    lw $2, 64($sp)
+; MIPS1-NEXT:    lw $3, 68($sp)
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    sw $3, 28($sp)
+; MIPS1-NEXT:    sw $2, 24($sp)
+; MIPS1-NEXT:    sw $1, 20($sp)
+; MIPS1-NEXT:    lw $1, 56($sp)
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    sw $1, 16($sp)
+; MIPS1-NEXT:    lw $25, %call16(__modti3)($gp)
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    jalr $25
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    lw $ra, 36($sp) # 4-byte Folded Reload
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    addiu $sp, $sp, 40
+;
 ; MIPS2-LABEL: srem_i128:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    lui $2, %hi(_gp_disp)
diff --git a/llvm/test/CodeGen/Mips/llvm-ir/udiv.ll b/llvm/test/CodeGen/Mips/llvm-ir/udiv.ll
index 9451f1e9be096..b15e5869f3584 100644
--- a/llvm/test/CodeGen/Mips/llvm-ir/udiv.ll
+++ b/llvm/test/CodeGen/Mips/llvm-ir/udiv.ll
@@ -1,4 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=mips -mcpu=mips1 -relocation-model=pic \
+; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefix=MIPS1
 ; RUN: llc < %s -mtriple=mips -mcpu=mips2 -relocation-model=pic \
 ; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefixes=MIPS2
 ; RUN: llc < %s -mtriple=mips -mcpu=mips32 -relocation-model=pic \
@@ -35,6 +37,11 @@
 ; RUN:   FileCheck %s -check-prefix=MMR6
 
 define zeroext i1 @udiv_i1(i1 zeroext %a, i1 zeroext %b) {
+; MIPS1-LABEL: udiv_i1:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    move $2, $4
+;
 ; MIPS2-LABEL: udiv_i1:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    jr $ra
@@ -80,6 +87,17 @@ entry:
 }
 
 define zeroext i8 @udiv_i8(i8 zeroext %a, i8 zeroext %b) {
+; MIPS1-LABEL: udiv_i8:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    bnez $5, $BB1_2
+; MIPS1-NEXT:    divu $zero, $4, $5
+; MIPS1-NEXT:  # %bb.1: # %entry
+; MIPS1-NEXT:    break 7
+; MIPS1-NEXT:  $BB1_2: # %entry
+; MIPS1-NEXT:    mflo $2
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    nop
+;
 ; MIPS2-LABEL: udiv_i8:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    divu $zero, $4, $5
@@ -140,6 +158,17 @@ entry:
 }
 
 define zeroext i16 @udiv_i16(i16 zeroext %a, i16 zeroext %b) {
+; MIPS1-LABEL: udiv_i16:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    bnez $5, $BB2_2
+; MIPS1-NEXT:    divu $zero, $4, $5
+; MIPS1-NEXT:  # %bb.1: # %entry
+; MIPS1-NEXT:    break 7
+; MIPS1-NEXT:  $BB2_2: # %entry
+; MIPS1-NEXT:    mflo $2
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    nop
+;
 ; MIPS2-LABEL: udiv_i16:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    divu $zero, $4, $5
@@ -200,6 +229,17 @@ entry:
 }
 
 define signext i32 @udiv_i32(i32 signext %a, i32 signext %b) {
+; MIPS1-LABEL: udiv_i32:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    bnez $5, $BB3_2
+; MIPS1-NEXT:    divu $zero, $4, $5
+; MIPS1-NEXT:  # %bb.1: # %entry
+; MIPS1-NEXT:    break 7
+; MIPS1-NEXT:  $BB3_2: # %entry
+; MIPS1-NEXT:    mflo $2
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    nop
+;
 ; MIPS2-LABEL: udiv_i32:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    divu $zero, $4, $5
@@ -260,6 +300,24 @@ entry:
 }
 
 define signext i64 @udiv_i64(i64 signext %a, i64 signext %b) {
+; MIPS1-LABEL: udiv_i64:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    lui $2, %hi(_gp_disp)
+; MIPS1-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; MIPS1-NEXT:    addiu $sp, $sp, -24
+; MIPS1-NEXT:    .cfi_def_cfa_offset 24
+; MIPS1-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
+; MIPS1-NEXT:    .cfi_offset 31, -4
+; MIPS1-NEXT:    addu $gp, $2, $25
+; MIPS1-NEXT:    lw $25, %call16(__udivdi3)($gp)
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    jalr $25
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    addiu $sp, $sp, 24
+;
 ; MIPS2-LABEL: udiv_i64:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    lui $2, %hi(_gp_disp)
@@ -364,6 +422,34 @@ entry:
 }
 
 define signext i128 @udiv_i128(i128 signext %a, i128 signext %b) {
+; MIPS1-LABEL: udiv_i128:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    lui $2, %hi(_gp_disp)
+; MIPS1-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; MIPS1-NEXT:    addiu $sp, $sp, -40
+; MIPS1-NEXT:    .cfi_def_cfa_offset 40
+; MIPS1-NEXT:    sw $ra, 36($sp) # 4-byte Folded Spill
+; MIPS1-NEXT:    .cfi_offset 31, -4
+; MIPS1-NEXT:    addu $gp, $2, $25
+; MIPS1-NEXT:    lw $1, 60($sp)
+; MIPS1-NEXT:    lw $2, 64($sp)
+; MIPS1-NEXT:    lw $3, 68($sp)
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    sw $3, 28($sp)
+; MIPS1-NEXT:    sw $2, 24($sp)
+; MIPS1-NEXT:    sw $1, 20($sp)
+; MIPS1-NEXT:    lw $1, 56($sp)
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    sw $1, 16($sp)
+; MIPS1-NEXT:    lw $25, %call16(__udivti3)($gp)
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    jalr $25
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    lw $ra, 36($sp) # 4-byte Folded Reload
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    addiu $sp, $sp, 40
+;
 ; MIPS2-LABEL: udiv_i128:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    lui $2, %hi(_gp_disp)
diff --git a/llvm/test/CodeGen/Mips/llvm-ir/urem.ll b/llvm/test/CodeGen/Mips/llvm-ir/urem.ll
index 7bd8df9e48c75..6da5984502d3c 100644
--- a/llvm/test/CodeGen/Mips/llvm-ir/urem.ll
+++ b/llvm/test/CodeGen/Mips/llvm-ir/urem.ll
@@ -1,4 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=mips -mcpu=mips1 -relocation-model=pic \
+; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefix=MIPS1
 ; RUN: llc < %s -mtriple=mips -mcpu=mips2 -relocation-model=pic \
 ; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefixes=MIPS2
 ; RUN: llc < %s -mtriple=mips -mcpu=mips32 -relocation-model=pic \
@@ -35,6 +37,11 @@
 ; RUN:   FileCheck %s -check-prefix=MMR6
 
 define signext i1 @urem_i1(i1 signext %a, i1 signext %b) {
+; MIPS1-LABEL: urem_i1:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    addiu $2, $zero, 0
+;
 ; MIPS2-LABEL: urem_i1:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    jr $ra
@@ -80,6 +87,20 @@ entry:
 }
 
 define signext i8 @urem_i8(i8 signext %a, i8 signext %b) {
+; MIPS1-LABEL: urem_i8:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    andi $1, $5, 255
+; MIPS1-NEXT:    andi $2, $4, 255
+; MIPS1-NEXT:    bnez $1, $BB1_2
+; MIPS1-NEXT:    divu $zero, $2, $1
+; MIPS1-NEXT:  # %bb.1: # %entry
+; MIPS1-NEXT:    break 7
+; MIPS1-NEXT:  $BB1_2: # %entry
+; MIPS1-NEXT:    mfhi $1
+; MIPS1-NEXT:    sll $1, $1, 24
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    sra $2, $1, 24
+;
 ; MIPS2-LABEL: urem_i8:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    andi $1, $5, 255
@@ -186,6 +207,20 @@ entry:
 }
 
 define signext i16 @urem_i16(i16 signext %a, i16 signext %b) {
+; MIPS1-LABEL: urem_i16:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    andi $1, $5, 65535
+; MIPS1-NEXT:    andi $2, $4, 65535
+; MIPS1-NEXT:    bnez $1, $BB2_2
+; MIPS1-NEXT:    divu $zero, $2, $1
+; MIPS1-NEXT:  # %bb.1: # %entry
+; MIPS1-NEXT:    break 7
+; MIPS1-NEXT:  $BB2_2: # %entry
+; MIPS1-NEXT:    mfhi $1
+; MIPS1-NEXT:    sll $1, $1, 16
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    sra $2, $1, 16
+;
 ; MIPS2-LABEL: urem_i16:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    andi $1, $5, 65535
@@ -292,6 +327,17 @@ entry:
 }
 
 define signext i32 @urem_i32(i32 signext %a, i32 signext %b) {
+; MIPS1-LABEL: urem_i32:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    bnez $5, $BB3_2
+; MIPS1-NEXT:    divu $zero, $4, $5
+; MIPS1-NEXT:  # %bb.1: # %entry
+; MIPS1-NEXT:    break 7
+; MIPS1-NEXT:  $BB3_2: # %entry
+; MIPS1-NEXT:    mfhi $2
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    nop
+;
 ; MIPS2-LABEL: urem_i32:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    divu $zero, $4, $5
@@ -352,6 +398,24 @@ entry:
 }
 
 define signext i64 @urem_i64(i64 signext %a, i64 signext %b) {
+; MIPS1-LABEL: urem_i64:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    lui $2, %hi(_gp_disp)
+; MIPS1-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; MIPS1-NEXT:    addiu $sp, $sp, -24
+; MIPS1-NEXT:    .cfi_def_cfa_offset 24
+; MIPS1-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
+; MIPS1-NEXT:    .cfi_offset 31, -4
+; MIPS1-NEXT:    addu $gp, $2, $25
+; MIPS1-NEXT:    lw $25, %call16(__umoddi3)($gp)
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    jalr $25
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    addiu $sp, $sp, 24
+;
 ; MIPS2-LABEL: urem_i64:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    lui $2, %hi(_gp_disp)
@@ -456,6 +520,34 @@ entry:
 }
 
 define signext i128 @urem_i128(i128 signext %a, i128 signext %b) {
+; MIPS1-LABEL: urem_i128:
+; MIPS1:       # %bb.0: # %entry
+; MIPS1-NEXT:    lui $2, %hi(_gp_disp)
+; MIPS1-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; MIPS1-NEXT:    addiu $sp, $sp, -40
+; MIPS1-NEXT:    .cfi_def_cfa_offset 40
+; MIPS1-NEXT:    sw $ra, 36($sp) # 4-byte Folded Spill
+; MIPS1-NEXT:    .cfi_offset 31, -4
+; MIPS1-NEXT:    addu $gp, $2, $25
+; MIPS1-NEXT:    lw $1, 60($sp)
+; MIPS1-NEXT:    lw $2, 64($sp)
+; MIPS1-NEXT:    lw $3, 68($sp)
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    sw $3, 28($sp)
+; MIPS1-NEXT:    sw $2, 24($sp)
+; MIPS1-NEXT:    sw $1, 20($sp)
+; MIPS1-NEXT:    lw $1, 56($sp)
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    sw $1, 16($sp)
+; MIPS1-NEXT:    lw $25, %call16(__umodti3)($gp)
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    jalr $25
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    lw $ra, 36($sp) # 4-byte Folded Reload
+; MIPS1-NEXT:    nop
+; MIPS1-NEXT:    jr $ra
+; MIPS1-NEXT:    addiu $sp, $sp, 40
+;
 ; MIPS2-LABEL: urem_i128:
 ; MIPS2:       # %bb.0: # %entry
 ; MIPS2-NEXT:    lui $2, %hi(_gp_disp)



More information about the llvm-commits mailing list