[llvm] [Mips] mips1 DivByZeroTrap (PR #81311)

via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 9 11:57:17 PST 2024


https://github.com/cmccord-dev created https://github.com/llvm/llvm-project/pull/81311

Inserts bnez + break instead of teq $zero for mips1 target

Fixes #80554 

I updated the llvmir sdiv/udiv test as well.

This is my first contribution, please let me know if there is anything else I need to do!

>From 3f23ae8ac0d29699ae9aa418b66c1a5adaf733bc Mon Sep 17 00:00:00 2001
From: eiowlta <cassandra.l.mccord at gmail.com>
Date: Fri, 9 Feb 2024 21:41:41 +0200
Subject: [PATCH] [Mips] mips1 DivByZeroTrap

---
 llvm/lib/Target/Mips/MipsISelLowering.cpp |  63 ++++--
 llvm/test/CodeGen/Mips/llvm-ir/sdiv.ll    | 220 ++++++++++++++----
 llvm/test/CodeGen/Mips/llvm-ir/udiv.ll    | 264 +++++++++++++++++-----
 3 files changed, 426 insertions(+), 121 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index b2812f87914df7..c600e8756a169a 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -1268,24 +1268,53 @@ addLiveIn(MachineFunction &MF, unsigned PReg, const TargetRegisterClass *RC)
 static MachineBasicBlock *insertDivByZeroTrap(MachineInstr &MI,
                                               MachineBasicBlock &MBB,
                                               const TargetInstrInfo &TII,
-                                              bool Is64Bit, bool IsMicroMips) {
+                                              bool Is64Bit, bool IsMicroMips,
+                                              bool IsMips1) {
   if (NoZeroDivCheck)
     return &MBB;
 
-  // 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))
-            .addReg(Divisor.getReg(), getKillRegState(Divisor.isKill()))
-            .addReg(Mips::ZERO)
-            .addImm(7);
 
-  // Use the 32-bit sub-register if this is a 64-bit division.
-  if (Is64Bit)
-    MIB->getOperand(0).setSubReg(Mips::sub_32);
+  if (IsMips1) {
+
+    // Insert "beq $divisor_reg, $zero, label"
+    // Insert "break 7"
+    DebugLoc DL = MI.getDebugLoc();
+    MachineBasicBlock *BMBB = MBB.splitAt(MI, true);
+    MachineInstrBuilder MIB;
+    // Add branch after div
+    MIB = BuildMI(MBB, std::next(MI.getIterator()), DL, TII.get(Mips::BNE))
+              .addReg(Divisor.getReg(), getKillRegState(Divisor.isKill()))
+              .addReg(Mips::ZERO);
+
+    // insert break at start of next block
+    BuildMI(*BMBB, BMBB->instr_front(), DL, TII.get(Mips::BREAK))
+        .addImm(0)
+        .addImm(7);
+
+    // split break into own block
+    MachineBasicBlock *EndMBB = BMBB->splitAt(BMBB->front(), true);
+    // add branch target
+    MBB.addSuccessor(EndMBB);
+    MIB.addMBB(EndMBB);
+
+    Divisor.setIsKill(false);
+    return EndMBB;
 
+  } else {
+    MachineBasicBlock::iterator I(MI);
+    // Insert instruction "teq $divisor_reg, $zero, 7".
+    MachineInstrBuilder MIB;
+    MIB = BuildMI(MBB, std::next(I), MI.getDebugLoc(),
+                  TII.get(IsMicroMips ? Mips::TEQ_MM : Mips::TEQ))
+              .addReg(Divisor.getReg(), getKillRegState(Divisor.isKill()))
+              .addReg(Mips::ZERO)
+              .addImm(7);
+
+    // Use the 32-bit sub-register if this is a 64-bit division.
+    if (Is64Bit)
+      MIB->getOperand(0).setSubReg(Mips::sub_32);
+  }
   // Clear Divisor's kill flag.
   Divisor.setIsKill(false);
 
@@ -1415,8 +1444,8 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
   case Mips::DIVU:
   case Mips::MOD:
   case Mips::MODU:
-    return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), false,
-                               false);
+    return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), false, false,
+                               !Subtarget.hasMips2());
   case Mips::SDIV_MM_Pseudo:
   case Mips::UDIV_MM_Pseudo:
   case Mips::SDIV_MM:
@@ -1425,14 +1454,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, true,
+                               false);
   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, false,
+                               false);
 
   case Mips::PseudoSELECT_I:
   case Mips::PseudoSELECT_I64:
diff --git a/llvm/test/CodeGen/Mips/llvm-ir/sdiv.ll b/llvm/test/CodeGen/Mips/llvm-ir/sdiv.ll
index af3d4f50f3fe4f..73ad5d3f9f2bbe 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-prefixes=GP32,GP32R0R1
 ; RUN: llc < %s -mtriple=mips -mcpu=mips2 -relocation-model=pic \
 ; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R0R2
 ; RUN: llc < %s -mtriple=mips -mcpu=mips32 -relocation-model=pic \
@@ -70,6 +72,19 @@ entry:
 }
 
 define signext i8 @sdiv_i8(i8 signext %a, i8 signext %b) {
+; GP32R0R1-LABEL: sdiv_i8:
+; GP32R0R1:       # %bb.0: # %entry
+; GP32R0R1-NEXT:    div $zero, $4, $5
+; GP32R0R1-NEXT:    bnez $5, $BB1_2
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:  # %bb.1: # %entry
+; GP32R0R1-NEXT:    break 0, 7
+; GP32R0R1-NEXT:  $BB1_2: # %entry
+; GP32R0R1-NEXT:    mflo $1
+; GP32R0R1-NEXT:    sll $1, $1, 24
+; GP32R0R1-NEXT:    jr $ra
+; GP32R0R1-NEXT:    sra $2, $1, 24
+;
 ; GP32R0R2-LABEL: sdiv_i8:
 ; GP32R0R2:       # %bb.0: # %entry
 ; GP32R0R2-NEXT:    div $zero, $4, $5
@@ -138,6 +153,19 @@ entry:
 }
 
 define signext i16 @sdiv_i16(i16 signext %a, i16 signext %b) {
+; GP32R0R1-LABEL: sdiv_i16:
+; GP32R0R1:       # %bb.0: # %entry
+; GP32R0R1-NEXT:    div $zero, $4, $5
+; GP32R0R1-NEXT:    bnez $5, $BB2_2
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:  # %bb.1: # %entry
+; GP32R0R1-NEXT:    break 0, 7
+; GP32R0R1-NEXT:  $BB2_2: # %entry
+; GP32R0R1-NEXT:    mflo $1
+; GP32R0R1-NEXT:    sll $1, $1, 16
+; GP32R0R1-NEXT:    jr $ra
+; GP32R0R1-NEXT:    sra $2, $1, 16
+;
 ; GP32R0R2-LABEL: sdiv_i16:
 ; GP32R0R2:       # %bb.0: # %entry
 ; GP32R0R2-NEXT:    div $zero, $4, $5
@@ -206,12 +234,30 @@ entry:
 }
 
 define signext i32 @sdiv_i32(i32 signext %a, i32 signext %b) {
-; GP32-LABEL: sdiv_i32:
-; GP32:       # %bb.0: # %entry
-; GP32-NEXT:    div $zero, $4, $5
-; GP32-NEXT:    teq $5, $zero, 7
-; GP32-NEXT:    jr $ra
-; GP32-NEXT:    mflo $2
+; GP32R0R1-LABEL: sdiv_i32:
+; GP32R0R1:       # %bb.0: # %entry
+; GP32R0R1-NEXT:    div $zero, $4, $5
+; GP32R0R1-NEXT:    bnez $5, $BB3_2
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:  # %bb.1: # %entry
+; GP32R0R1-NEXT:    break 0, 7
+; GP32R0R1-NEXT:  $BB3_2: # %entry
+; GP32R0R1-NEXT:    jr $ra
+; GP32R0R1-NEXT:    mflo $2
+;
+; GP32R0R2-LABEL: sdiv_i32:
+; GP32R0R2:       # %bb.0: # %entry
+; GP32R0R2-NEXT:    div $zero, $4, $5
+; GP32R0R2-NEXT:    teq $5, $zero, 7
+; GP32R0R2-NEXT:    jr $ra
+; GP32R0R2-NEXT:    mflo $2
+;
+; GP32R2R5-LABEL: sdiv_i32:
+; GP32R2R5:       # %bb.0: # %entry
+; GP32R2R5-NEXT:    div $zero, $4, $5
+; GP32R2R5-NEXT:    teq $5, $zero, 7
+; GP32R2R5-NEXT:    jr $ra
+; GP32R2R5-NEXT:    mflo $2
 ;
 ; GP32R6-LABEL: sdiv_i32:
 ; GP32R6:       # %bb.0: # %entry
@@ -250,21 +296,55 @@ entry:
 }
 
 define signext i64 @sdiv_i64(i64 signext %a, i64 signext %b) {
-; GP32-LABEL: sdiv_i64:
-; GP32:       # %bb.0: # %entry
-; GP32-NEXT:    lui $2, %hi(_gp_disp)
-; GP32-NEXT:    addiu $2, $2, %lo(_gp_disp)
-; GP32-NEXT:    addiu $sp, $sp, -24
-; GP32-NEXT:    .cfi_def_cfa_offset 24
-; GP32-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
-; GP32-NEXT:    .cfi_offset 31, -4
-; GP32-NEXT:    addu $gp, $2, $25
-; GP32-NEXT:    lw $25, %call16(__divdi3)($gp)
-; GP32-NEXT:    jalr $25
-; GP32-NEXT:    nop
-; GP32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
-; GP32-NEXT:    jr $ra
-; GP32-NEXT:    addiu $sp, $sp, 24
+; GP32R0R1-LABEL: sdiv_i64:
+; GP32R0R1:       # %bb.0: # %entry
+; GP32R0R1-NEXT:    lui $2, %hi(_gp_disp)
+; GP32R0R1-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; GP32R0R1-NEXT:    addiu $sp, $sp, -24
+; GP32R0R1-NEXT:    .cfi_def_cfa_offset 24
+; GP32R0R1-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
+; GP32R0R1-NEXT:    .cfi_offset 31, -4
+; GP32R0R1-NEXT:    addu $gp, $2, $25
+; GP32R0R1-NEXT:    lw $25, %call16(__divdi3)($gp)
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:    jalr $25
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:    jr $ra
+; GP32R0R1-NEXT:    addiu $sp, $sp, 24
+;
+; GP32R0R2-LABEL: sdiv_i64:
+; GP32R0R2:       # %bb.0: # %entry
+; GP32R0R2-NEXT:    lui $2, %hi(_gp_disp)
+; GP32R0R2-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; GP32R0R2-NEXT:    addiu $sp, $sp, -24
+; GP32R0R2-NEXT:    .cfi_def_cfa_offset 24
+; GP32R0R2-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
+; GP32R0R2-NEXT:    .cfi_offset 31, -4
+; GP32R0R2-NEXT:    addu $gp, $2, $25
+; GP32R0R2-NEXT:    lw $25, %call16(__divdi3)($gp)
+; GP32R0R2-NEXT:    jalr $25
+; GP32R0R2-NEXT:    nop
+; GP32R0R2-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
+; GP32R0R2-NEXT:    jr $ra
+; GP32R0R2-NEXT:    addiu $sp, $sp, 24
+;
+; GP32R2R5-LABEL: sdiv_i64:
+; GP32R2R5:       # %bb.0: # %entry
+; GP32R2R5-NEXT:    lui $2, %hi(_gp_disp)
+; GP32R2R5-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; GP32R2R5-NEXT:    addiu $sp, $sp, -24
+; GP32R2R5-NEXT:    .cfi_def_cfa_offset 24
+; GP32R2R5-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
+; GP32R2R5-NEXT:    .cfi_offset 31, -4
+; GP32R2R5-NEXT:    addu $gp, $2, $25
+; GP32R2R5-NEXT:    lw $25, %call16(__divdi3)($gp)
+; GP32R2R5-NEXT:    jalr $25
+; GP32R2R5-NEXT:    nop
+; GP32R2R5-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
+; GP32R2R5-NEXT:    jr $ra
+; GP32R2R5-NEXT:    addiu $sp, $sp, 24
 ;
 ; GP32R6-LABEL: sdiv_i64:
 ; GP32R6:       # %bb.0: # %entry
@@ -332,29 +412,81 @@ entry:
 }
 
 define signext i128 @sdiv_i128(i128 signext %a, i128 signext %b) {
-; GP32-LABEL: sdiv_i128:
-; GP32:       # %bb.0: # %entry
-; GP32-NEXT:    lui $2, %hi(_gp_disp)
-; GP32-NEXT:    addiu $2, $2, %lo(_gp_disp)
-; GP32-NEXT:    addiu $sp, $sp, -40
-; GP32-NEXT:    .cfi_def_cfa_offset 40
-; GP32-NEXT:    sw $ra, 36($sp) # 4-byte Folded Spill
-; GP32-NEXT:    .cfi_offset 31, -4
-; GP32-NEXT:    addu $gp, $2, $25
-; GP32-NEXT:    lw $1, 60($sp)
-; GP32-NEXT:    lw $2, 64($sp)
-; GP32-NEXT:    lw $3, 68($sp)
-; GP32-NEXT:    sw $3, 28($sp)
-; GP32-NEXT:    sw $2, 24($sp)
-; GP32-NEXT:    sw $1, 20($sp)
-; GP32-NEXT:    lw $1, 56($sp)
-; GP32-NEXT:    sw $1, 16($sp)
-; GP32-NEXT:    lw $25, %call16(__divti3)($gp)
-; GP32-NEXT:    jalr $25
-; GP32-NEXT:    nop
-; GP32-NEXT:    lw $ra, 36($sp) # 4-byte Folded Reload
-; GP32-NEXT:    jr $ra
-; GP32-NEXT:    addiu $sp, $sp, 40
+; GP32R0R1-LABEL: sdiv_i128:
+; GP32R0R1:       # %bb.0: # %entry
+; GP32R0R1-NEXT:    lui $2, %hi(_gp_disp)
+; GP32R0R1-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; GP32R0R1-NEXT:    addiu $sp, $sp, -40
+; GP32R0R1-NEXT:    .cfi_def_cfa_offset 40
+; GP32R0R1-NEXT:    sw $ra, 36($sp) # 4-byte Folded Spill
+; GP32R0R1-NEXT:    .cfi_offset 31, -4
+; GP32R0R1-NEXT:    addu $gp, $2, $25
+; GP32R0R1-NEXT:    lw $1, 60($sp)
+; GP32R0R1-NEXT:    lw $2, 64($sp)
+; GP32R0R1-NEXT:    lw $3, 68($sp)
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:    sw $3, 28($sp)
+; GP32R0R1-NEXT:    sw $2, 24($sp)
+; GP32R0R1-NEXT:    sw $1, 20($sp)
+; GP32R0R1-NEXT:    lw $1, 56($sp)
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:    sw $1, 16($sp)
+; GP32R0R1-NEXT:    lw $25, %call16(__divti3)($gp)
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:    jalr $25
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:    lw $ra, 36($sp) # 4-byte Folded Reload
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:    jr $ra
+; GP32R0R1-NEXT:    addiu $sp, $sp, 40
+;
+; GP32R0R2-LABEL: sdiv_i128:
+; GP32R0R2:       # %bb.0: # %entry
+; GP32R0R2-NEXT:    lui $2, %hi(_gp_disp)
+; GP32R0R2-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; GP32R0R2-NEXT:    addiu $sp, $sp, -40
+; GP32R0R2-NEXT:    .cfi_def_cfa_offset 40
+; GP32R0R2-NEXT:    sw $ra, 36($sp) # 4-byte Folded Spill
+; GP32R0R2-NEXT:    .cfi_offset 31, -4
+; GP32R0R2-NEXT:    addu $gp, $2, $25
+; GP32R0R2-NEXT:    lw $1, 60($sp)
+; GP32R0R2-NEXT:    lw $2, 64($sp)
+; GP32R0R2-NEXT:    lw $3, 68($sp)
+; GP32R0R2-NEXT:    sw $3, 28($sp)
+; GP32R0R2-NEXT:    sw $2, 24($sp)
+; GP32R0R2-NEXT:    sw $1, 20($sp)
+; GP32R0R2-NEXT:    lw $1, 56($sp)
+; GP32R0R2-NEXT:    sw $1, 16($sp)
+; GP32R0R2-NEXT:    lw $25, %call16(__divti3)($gp)
+; GP32R0R2-NEXT:    jalr $25
+; GP32R0R2-NEXT:    nop
+; GP32R0R2-NEXT:    lw $ra, 36($sp) # 4-byte Folded Reload
+; GP32R0R2-NEXT:    jr $ra
+; GP32R0R2-NEXT:    addiu $sp, $sp, 40
+;
+; GP32R2R5-LABEL: sdiv_i128:
+; GP32R2R5:       # %bb.0: # %entry
+; GP32R2R5-NEXT:    lui $2, %hi(_gp_disp)
+; GP32R2R5-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; GP32R2R5-NEXT:    addiu $sp, $sp, -40
+; GP32R2R5-NEXT:    .cfi_def_cfa_offset 40
+; GP32R2R5-NEXT:    sw $ra, 36($sp) # 4-byte Folded Spill
+; GP32R2R5-NEXT:    .cfi_offset 31, -4
+; GP32R2R5-NEXT:    addu $gp, $2, $25
+; GP32R2R5-NEXT:    lw $1, 60($sp)
+; GP32R2R5-NEXT:    lw $2, 64($sp)
+; GP32R2R5-NEXT:    lw $3, 68($sp)
+; GP32R2R5-NEXT:    sw $3, 28($sp)
+; GP32R2R5-NEXT:    sw $2, 24($sp)
+; GP32R2R5-NEXT:    sw $1, 20($sp)
+; GP32R2R5-NEXT:    lw $1, 56($sp)
+; GP32R2R5-NEXT:    sw $1, 16($sp)
+; GP32R2R5-NEXT:    lw $25, %call16(__divti3)($gp)
+; GP32R2R5-NEXT:    jalr $25
+; GP32R2R5-NEXT:    nop
+; GP32R2R5-NEXT:    lw $ra, 36($sp) # 4-byte Folded Reload
+; GP32R2R5-NEXT:    jr $ra
+; GP32R2R5-NEXT:    addiu $sp, $sp, 40
 ;
 ; GP32R6-LABEL: sdiv_i128:
 ; GP32R6:       # %bb.0: # %entry
diff --git a/llvm/test/CodeGen/Mips/llvm-ir/udiv.ll b/llvm/test/CodeGen/Mips/llvm-ir/udiv.ll
index e3dd347e723bc8..71dcefbc090c14 100644
--- a/llvm/test/CodeGen/Mips/llvm-ir/udiv.ll
+++ b/llvm/test/CodeGen/Mips/llvm-ir/udiv.ll
@@ -1,14 +1,16 @@
 ; 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-prefixes=GP32,GP32R0R1
 ; RUN: llc < %s -mtriple=mips -mcpu=mips2 -relocation-model=pic \
-; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32
+; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R0R2
 ; RUN: llc < %s -mtriple=mips -mcpu=mips32 -relocation-model=pic \
-; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32
+; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R0R2
 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r2 -relocation-model=pic \
-; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32
+; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5
 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -relocation-model=pic \
-; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32
+; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5
 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r5 -relocation-model=pic \
-; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32
+; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5
 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -relocation-model=pic \
 ; RUN:   -mips-jalr-reloc=false | FileCheck %s -check-prefix=GP32R6
 
@@ -70,12 +72,30 @@ entry:
 }
 
 define zeroext i8 @udiv_i8(i8 zeroext %a, i8 zeroext %b) {
-; GP32-LABEL: udiv_i8:
-; GP32:       # %bb.0: # %entry
-; GP32-NEXT:    divu $zero, $4, $5
-; GP32-NEXT:    teq $5, $zero, 7
-; GP32-NEXT:    jr $ra
-; GP32-NEXT:    mflo $2
+; GP32R0R1-LABEL: udiv_i8:
+; GP32R0R1:       # %bb.0: # %entry
+; GP32R0R1-NEXT:    divu $zero, $4, $5
+; GP32R0R1-NEXT:    bnez $5, $BB1_2
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:  # %bb.1: # %entry
+; GP32R0R1-NEXT:    break 0, 7
+; GP32R0R1-NEXT:  $BB1_2: # %entry
+; GP32R0R1-NEXT:    jr $ra
+; GP32R0R1-NEXT:    mflo $2
+;
+; GP32R0R2-LABEL: udiv_i8:
+; GP32R0R2:       # %bb.0: # %entry
+; GP32R0R2-NEXT:    divu $zero, $4, $5
+; GP32R0R2-NEXT:    teq $5, $zero, 7
+; GP32R0R2-NEXT:    jr $ra
+; GP32R0R2-NEXT:    mflo $2
+;
+; GP32R2R5-LABEL: udiv_i8:
+; GP32R2R5:       # %bb.0: # %entry
+; GP32R2R5-NEXT:    divu $zero, $4, $5
+; GP32R2R5-NEXT:    teq $5, $zero, 7
+; GP32R2R5-NEXT:    jr $ra
+; GP32R2R5-NEXT:    mflo $2
 ;
 ; GP32R6-LABEL: udiv_i8:
 ; GP32R6:       # %bb.0: # %entry
@@ -114,12 +134,30 @@ entry:
 }
 
 define zeroext i16 @udiv_i16(i16 zeroext %a, i16 zeroext %b) {
-; GP32-LABEL: udiv_i16:
-; GP32:       # %bb.0: # %entry
-; GP32-NEXT:    divu $zero, $4, $5
-; GP32-NEXT:    teq $5, $zero, 7
-; GP32-NEXT:    jr $ra
-; GP32-NEXT:    mflo $2
+; GP32R0R1-LABEL: udiv_i16:
+; GP32R0R1:       # %bb.0: # %entry
+; GP32R0R1-NEXT:    divu $zero, $4, $5
+; GP32R0R1-NEXT:    bnez $5, $BB2_2
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:  # %bb.1: # %entry
+; GP32R0R1-NEXT:    break 0, 7
+; GP32R0R1-NEXT:  $BB2_2: # %entry
+; GP32R0R1-NEXT:    jr $ra
+; GP32R0R1-NEXT:    mflo $2
+;
+; GP32R0R2-LABEL: udiv_i16:
+; GP32R0R2:       # %bb.0: # %entry
+; GP32R0R2-NEXT:    divu $zero, $4, $5
+; GP32R0R2-NEXT:    teq $5, $zero, 7
+; GP32R0R2-NEXT:    jr $ra
+; GP32R0R2-NEXT:    mflo $2
+;
+; GP32R2R5-LABEL: udiv_i16:
+; GP32R2R5:       # %bb.0: # %entry
+; GP32R2R5-NEXT:    divu $zero, $4, $5
+; GP32R2R5-NEXT:    teq $5, $zero, 7
+; GP32R2R5-NEXT:    jr $ra
+; GP32R2R5-NEXT:    mflo $2
 ;
 ; GP32R6-LABEL: udiv_i16:
 ; GP32R6:       # %bb.0: # %entry
@@ -158,12 +196,30 @@ entry:
 }
 
 define signext i32 @udiv_i32(i32 signext %a, i32 signext %b) {
-; GP32-LABEL: udiv_i32:
-; GP32:       # %bb.0: # %entry
-; GP32-NEXT:    divu $zero, $4, $5
-; GP32-NEXT:    teq $5, $zero, 7
-; GP32-NEXT:    jr $ra
-; GP32-NEXT:    mflo $2
+; GP32R0R1-LABEL: udiv_i32:
+; GP32R0R1:       # %bb.0: # %entry
+; GP32R0R1-NEXT:    divu $zero, $4, $5
+; GP32R0R1-NEXT:    bnez $5, $BB3_2
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:  # %bb.1: # %entry
+; GP32R0R1-NEXT:    break 0, 7
+; GP32R0R1-NEXT:  $BB3_2: # %entry
+; GP32R0R1-NEXT:    jr $ra
+; GP32R0R1-NEXT:    mflo $2
+;
+; GP32R0R2-LABEL: udiv_i32:
+; GP32R0R2:       # %bb.0: # %entry
+; GP32R0R2-NEXT:    divu $zero, $4, $5
+; GP32R0R2-NEXT:    teq $5, $zero, 7
+; GP32R0R2-NEXT:    jr $ra
+; GP32R0R2-NEXT:    mflo $2
+;
+; GP32R2R5-LABEL: udiv_i32:
+; GP32R2R5:       # %bb.0: # %entry
+; GP32R2R5-NEXT:    divu $zero, $4, $5
+; GP32R2R5-NEXT:    teq $5, $zero, 7
+; GP32R2R5-NEXT:    jr $ra
+; GP32R2R5-NEXT:    mflo $2
 ;
 ; GP32R6-LABEL: udiv_i32:
 ; GP32R6:       # %bb.0: # %entry
@@ -202,21 +258,55 @@ entry:
 }
 
 define signext i64 @udiv_i64(i64 signext %a, i64 signext %b) {
-; GP32-LABEL: udiv_i64:
-; GP32:       # %bb.0: # %entry
-; GP32-NEXT:    lui $2, %hi(_gp_disp)
-; GP32-NEXT:    addiu $2, $2, %lo(_gp_disp)
-; GP32-NEXT:    addiu $sp, $sp, -24
-; GP32-NEXT:    .cfi_def_cfa_offset 24
-; GP32-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
-; GP32-NEXT:    .cfi_offset 31, -4
-; GP32-NEXT:    addu $gp, $2, $25
-; GP32-NEXT:    lw $25, %call16(__udivdi3)($gp)
-; GP32-NEXT:    jalr $25
-; GP32-NEXT:    nop
-; GP32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
-; GP32-NEXT:    jr $ra
-; GP32-NEXT:    addiu $sp, $sp, 24
+; GP32R0R1-LABEL: udiv_i64:
+; GP32R0R1:       # %bb.0: # %entry
+; GP32R0R1-NEXT:    lui $2, %hi(_gp_disp)
+; GP32R0R1-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; GP32R0R1-NEXT:    addiu $sp, $sp, -24
+; GP32R0R1-NEXT:    .cfi_def_cfa_offset 24
+; GP32R0R1-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
+; GP32R0R1-NEXT:    .cfi_offset 31, -4
+; GP32R0R1-NEXT:    addu $gp, $2, $25
+; GP32R0R1-NEXT:    lw $25, %call16(__udivdi3)($gp)
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:    jalr $25
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:    jr $ra
+; GP32R0R1-NEXT:    addiu $sp, $sp, 24
+;
+; GP32R0R2-LABEL: udiv_i64:
+; GP32R0R2:       # %bb.0: # %entry
+; GP32R0R2-NEXT:    lui $2, %hi(_gp_disp)
+; GP32R0R2-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; GP32R0R2-NEXT:    addiu $sp, $sp, -24
+; GP32R0R2-NEXT:    .cfi_def_cfa_offset 24
+; GP32R0R2-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
+; GP32R0R2-NEXT:    .cfi_offset 31, -4
+; GP32R0R2-NEXT:    addu $gp, $2, $25
+; GP32R0R2-NEXT:    lw $25, %call16(__udivdi3)($gp)
+; GP32R0R2-NEXT:    jalr $25
+; GP32R0R2-NEXT:    nop
+; GP32R0R2-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
+; GP32R0R2-NEXT:    jr $ra
+; GP32R0R2-NEXT:    addiu $sp, $sp, 24
+;
+; GP32R2R5-LABEL: udiv_i64:
+; GP32R2R5:       # %bb.0: # %entry
+; GP32R2R5-NEXT:    lui $2, %hi(_gp_disp)
+; GP32R2R5-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; GP32R2R5-NEXT:    addiu $sp, $sp, -24
+; GP32R2R5-NEXT:    .cfi_def_cfa_offset 24
+; GP32R2R5-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
+; GP32R2R5-NEXT:    .cfi_offset 31, -4
+; GP32R2R5-NEXT:    addu $gp, $2, $25
+; GP32R2R5-NEXT:    lw $25, %call16(__udivdi3)($gp)
+; GP32R2R5-NEXT:    jalr $25
+; GP32R2R5-NEXT:    nop
+; GP32R2R5-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
+; GP32R2R5-NEXT:    jr $ra
+; GP32R2R5-NEXT:    addiu $sp, $sp, 24
 ;
 ; GP32R6-LABEL: udiv_i64:
 ; GP32R6:       # %bb.0: # %entry
@@ -284,29 +374,81 @@ entry:
 }
 
 define signext i128 @udiv_i128(i128 signext %a, i128 signext %b) {
-; GP32-LABEL: udiv_i128:
-; GP32:       # %bb.0: # %entry
-; GP32-NEXT:    lui $2, %hi(_gp_disp)
-; GP32-NEXT:    addiu $2, $2, %lo(_gp_disp)
-; GP32-NEXT:    addiu $sp, $sp, -40
-; GP32-NEXT:    .cfi_def_cfa_offset 40
-; GP32-NEXT:    sw $ra, 36($sp) # 4-byte Folded Spill
-; GP32-NEXT:    .cfi_offset 31, -4
-; GP32-NEXT:    addu $gp, $2, $25
-; GP32-NEXT:    lw $1, 60($sp)
-; GP32-NEXT:    lw $2, 64($sp)
-; GP32-NEXT:    lw $3, 68($sp)
-; GP32-NEXT:    sw $3, 28($sp)
-; GP32-NEXT:    sw $2, 24($sp)
-; GP32-NEXT:    sw $1, 20($sp)
-; GP32-NEXT:    lw $1, 56($sp)
-; GP32-NEXT:    sw $1, 16($sp)
-; GP32-NEXT:    lw $25, %call16(__udivti3)($gp)
-; GP32-NEXT:    jalr $25
-; GP32-NEXT:    nop
-; GP32-NEXT:    lw $ra, 36($sp) # 4-byte Folded Reload
-; GP32-NEXT:    jr $ra
-; GP32-NEXT:    addiu $sp, $sp, 40
+; GP32R0R1-LABEL: udiv_i128:
+; GP32R0R1:       # %bb.0: # %entry
+; GP32R0R1-NEXT:    lui $2, %hi(_gp_disp)
+; GP32R0R1-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; GP32R0R1-NEXT:    addiu $sp, $sp, -40
+; GP32R0R1-NEXT:    .cfi_def_cfa_offset 40
+; GP32R0R1-NEXT:    sw $ra, 36($sp) # 4-byte Folded Spill
+; GP32R0R1-NEXT:    .cfi_offset 31, -4
+; GP32R0R1-NEXT:    addu $gp, $2, $25
+; GP32R0R1-NEXT:    lw $1, 60($sp)
+; GP32R0R1-NEXT:    lw $2, 64($sp)
+; GP32R0R1-NEXT:    lw $3, 68($sp)
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:    sw $3, 28($sp)
+; GP32R0R1-NEXT:    sw $2, 24($sp)
+; GP32R0R1-NEXT:    sw $1, 20($sp)
+; GP32R0R1-NEXT:    lw $1, 56($sp)
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:    sw $1, 16($sp)
+; GP32R0R1-NEXT:    lw $25, %call16(__udivti3)($gp)
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:    jalr $25
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:    lw $ra, 36($sp) # 4-byte Folded Reload
+; GP32R0R1-NEXT:    nop
+; GP32R0R1-NEXT:    jr $ra
+; GP32R0R1-NEXT:    addiu $sp, $sp, 40
+;
+; GP32R0R2-LABEL: udiv_i128:
+; GP32R0R2:       # %bb.0: # %entry
+; GP32R0R2-NEXT:    lui $2, %hi(_gp_disp)
+; GP32R0R2-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; GP32R0R2-NEXT:    addiu $sp, $sp, -40
+; GP32R0R2-NEXT:    .cfi_def_cfa_offset 40
+; GP32R0R2-NEXT:    sw $ra, 36($sp) # 4-byte Folded Spill
+; GP32R0R2-NEXT:    .cfi_offset 31, -4
+; GP32R0R2-NEXT:    addu $gp, $2, $25
+; GP32R0R2-NEXT:    lw $1, 60($sp)
+; GP32R0R2-NEXT:    lw $2, 64($sp)
+; GP32R0R2-NEXT:    lw $3, 68($sp)
+; GP32R0R2-NEXT:    sw $3, 28($sp)
+; GP32R0R2-NEXT:    sw $2, 24($sp)
+; GP32R0R2-NEXT:    sw $1, 20($sp)
+; GP32R0R2-NEXT:    lw $1, 56($sp)
+; GP32R0R2-NEXT:    sw $1, 16($sp)
+; GP32R0R2-NEXT:    lw $25, %call16(__udivti3)($gp)
+; GP32R0R2-NEXT:    jalr $25
+; GP32R0R2-NEXT:    nop
+; GP32R0R2-NEXT:    lw $ra, 36($sp) # 4-byte Folded Reload
+; GP32R0R2-NEXT:    jr $ra
+; GP32R0R2-NEXT:    addiu $sp, $sp, 40
+;
+; GP32R2R5-LABEL: udiv_i128:
+; GP32R2R5:       # %bb.0: # %entry
+; GP32R2R5-NEXT:    lui $2, %hi(_gp_disp)
+; GP32R2R5-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; GP32R2R5-NEXT:    addiu $sp, $sp, -40
+; GP32R2R5-NEXT:    .cfi_def_cfa_offset 40
+; GP32R2R5-NEXT:    sw $ra, 36($sp) # 4-byte Folded Spill
+; GP32R2R5-NEXT:    .cfi_offset 31, -4
+; GP32R2R5-NEXT:    addu $gp, $2, $25
+; GP32R2R5-NEXT:    lw $1, 60($sp)
+; GP32R2R5-NEXT:    lw $2, 64($sp)
+; GP32R2R5-NEXT:    lw $3, 68($sp)
+; GP32R2R5-NEXT:    sw $3, 28($sp)
+; GP32R2R5-NEXT:    sw $2, 24($sp)
+; GP32R2R5-NEXT:    sw $1, 20($sp)
+; GP32R2R5-NEXT:    lw $1, 56($sp)
+; GP32R2R5-NEXT:    sw $1, 16($sp)
+; GP32R2R5-NEXT:    lw $25, %call16(__udivti3)($gp)
+; GP32R2R5-NEXT:    jalr $25
+; GP32R2R5-NEXT:    nop
+; GP32R2R5-NEXT:    lw $ra, 36($sp) # 4-byte Folded Reload
+; GP32R2R5-NEXT:    jr $ra
+; GP32R2R5-NEXT:    addiu $sp, $sp, 40
 ;
 ; GP32R6-LABEL: udiv_i128:
 ; GP32R6:       # %bb.0: # %entry



More information about the llvm-commits mailing list