[llvm] Mips: Improve MipsAsmParser::expandDivRem (PR #172967)

YunQiang Su via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 19 00:00:15 PST 2025


https://github.com/wzssyqa updated https://github.com/llvm/llvm-project/pull/172967

>From 2bc5fb10c5684b8a028be5f2ba91d0e8037bb17f Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Fri, 19 Dec 2025 15:50:00 +0800
Subject: [PATCH 1/2] Mips: Improve MipsAsmParser::expandDivRem

Fixes: #172965

In fact MipsAsmParser::expandDivRem is in a so bad status:
1. Div may not execute at all in most case
   .set    reorder
   bnez    $3, $tmp0
   div     $zero, $2, $3
   break   7
$tmp0:

   `.set reorder` may insert a nop after bnez, which will
skip `div` if $3 is not zero.

2. `break   6` is wrong here.
---
 .../Target/Mips/AsmParser/MipsAsmParser.cpp   |  65 +--
 .../Target/Mips/MCTargetDesc/MipsABIInfo.cpp  |   4 +
 llvm/lib/Target/Mips/MipsISelLowering.cpp     |   6 +-
 llvm/test/CodeGen/Mips/divrem-inline-asm.ll   | 370 ++++++++++++++++++
 4 files changed, 389 insertions(+), 56 deletions(-)
 create mode 100644 llvm/test/CodeGen/Mips/divrem-inline-asm.ll

diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 6b28531764db9..582b2c91c8052 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -68,6 +68,7 @@ class MCInstrInfo;
 } // end namespace llvm
 
 extern cl::opt<bool> EmitJalrReloc;
+extern cl::opt<bool> NoZeroDivCheck;
 
 namespace {
 
@@ -4237,7 +4238,7 @@ bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
     if (!ATReg)
       return true;
 
-    if (ImmValue == 0) {
+    if (!NoZeroDivCheck && ImmValue == 0) {
       if (UseTraps)
         TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
       else
@@ -4269,7 +4270,7 @@ bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
   // break, insert the trap/break and exit. This gives a different result to
   // GAS. GAS has an inconsistency/missed optimization in that not all cases
   // are handled equivalently. As the observed behaviour is the same, we're ok.
-  if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
+  if (!NoZeroDivCheck && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
     if (UseTraps) {
       TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
       return false;
@@ -4290,62 +4291,24 @@ bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
   MCSymbol *BrTarget;
   MCOperand LabelOp;
 
-  if (UseTraps) {
-    TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
-  } else {
-    // Branch to the li instruction.
-    BrTarget = Context.createTempSymbol();
-    LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
-    TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
-  }
-
   TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
+  if (!NoZeroDivCheck) {
+    if (UseTraps) {
+      TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
+    } else {
+      // Branch to the li instruction.
+      BrTarget = Context.createTempSymbol();
+      LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
+      TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
+    }
 
-  if (!UseTraps)
-    TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
+    if (!UseTraps)
+      TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
 
-  if (!Signed) {
     if (!UseTraps)
       TOut.getStreamer().emitLabel(BrTarget);
-
-    TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
-    return false;
-  }
-
-  MCRegister ATReg = getATReg(IDLoc);
-  if (!ATReg)
-    return true;
-
-  if (!UseTraps)
-    TOut.getStreamer().emitLabel(BrTarget);
-
-  TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
-
-  // Temporary label for the second branch target.
-  MCSymbol *BrTargetEnd = Context.createTempSymbol();
-  MCOperand LabelOpEnd =
-      MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
-
-  // Branch to the mflo instruction.
-  TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
-
-  if (IsMips64) {
-    TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
-    TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
-  } else {
-    TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
-  }
-
-  if (UseTraps)
-    TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
-  else {
-    // Branch to the mflo instruction.
-    TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
-    TOut.emitNop(IDLoc, STI);
-    TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
   }
 
-  TOut.getStreamer().emitLabel(BrTargetEnd);
   TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
   return false;
 }
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
index d7809e27e23f3..663d04f26bd45 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
@@ -20,6 +20,10 @@ cl::opt<bool>
 EmitJalrReloc("mips-jalr-reloc", cl::Hidden,
               cl::desc("MIPS: Emit R_{MICRO}MIPS_JALR relocation with jalr"),
               cl::init(true));
+cl::opt<bool>
+NoZeroDivCheck("mno-check-zero-division", cl::Hidden,
+               cl::desc("MIPS: Don't trap on integer division by zero."),
+               cl::init(false));
 
 namespace {
 static const MCPhysReg O32IntRegs[4] = {Mips::A0, Mips::A1, Mips::A2, Mips::A3};
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index d99985c28b619..461a7b63de61b 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -83,12 +83,8 @@ using namespace llvm;
 
 STATISTIC(NumTailCalls, "Number of tail calls");
 
-static cl::opt<bool>
-NoZeroDivCheck("mno-check-zero-division", cl::Hidden,
-               cl::desc("MIPS: Don't trap on integer division by zero."),
-               cl::init(false));
-
 extern cl::opt<bool> EmitJalrReloc;
+extern cl::opt<bool> NoZeroDivCheck;
 
 static const MCPhysReg Mips64DPRegs[8] = {
   Mips::D12_64, Mips::D13_64, Mips::D14_64, Mips::D15_64,
diff --git a/llvm/test/CodeGen/Mips/divrem-inline-asm.ll b/llvm/test/CodeGen/Mips/divrem-inline-asm.ll
new file mode 100644
index 0000000000000..9dea24582138a
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/divrem-inline-asm.ll
@@ -0,0 +1,370 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=mips64 -mcpu=mips64   -verify-machineinstrs    -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,ACC64,ACC64-TRAP
+; RUN: llc -mtriple=mips64 -mcpu=mips64r2 -verify-machineinstrs    -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,ACC64,ACC64-TRAP
+
+; RUN: llc -mtriple=mips64 -mcpu=mips64   -mno-check-zero-division -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,ACC64,NOCHECK
+; RUN: llc -mtriple=mips64 -mcpu=mips64r2 -mno-check-zero-division -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,ACC64,NOCHECK
+
+; FileCheck Prefixes:
+;   ALL - All targets
+;   ACC64 - Same as ACC32 but only for 64-bit targets
+;   GPR64 - Same as GPR32 but only for 64-bit targets
+;   ACC64-TRAP - Same as TRAP and ACC64 combined
+;   GPR64-TRAP - Same as TRAP and GPR64 combined
+;   NOCHECK - Division by zero will not be detected
+
+
+define i32 @inline_asm_div() {
+; ACC64-TRAP-LABEL: inline_asm_div:
+; ACC64-TRAP:       # %bb.0: # %entry
+; ACC64-TRAP-NEXT:    addiu $2, $zero, 2
+; ACC64-TRAP-NEXT:    addiu $3, $zero, 1
+; ACC64-TRAP-NEXT:    #APP
+; ACC64-TRAP-NEXT:    .set push
+; ACC64-TRAP-NEXT:    .set at
+; ACC64-TRAP-NEXT:    .set macro
+; ACC64-TRAP-NEXT:    .set reorder
+; ACC64-TRAP-EMPTY:
+; ACC64-TRAP-NEXT:    div $zero, $2, $3
+; ACC64-TRAP-NEXT:    bnez $3, .Ltmp0
+; ACC64-TRAP-NEXT:    break 7
+; ACC64-TRAP-NEXT:  .Ltmp0:
+; ACC64-TRAP-NEXT:    mflo $2
+; ACC64-TRAP-EMPTY:
+; ACC64-TRAP-NEXT:    .set pop
+; ACC64-TRAP-NEXT:    #NO_APP
+; ACC64-TRAP-NEXT:    jr $ra
+; ACC64-TRAP-NEXT:    nop
+;
+; NOCHECK-LABEL: inline_asm_div:
+; NOCHECK:       # %bb.0: # %entry
+; NOCHECK-NEXT:    addiu $2, $zero, 2
+; NOCHECK-NEXT:    addiu $3, $zero, 1
+; NOCHECK-NEXT:    #APP
+; NOCHECK-NEXT:    .set push
+; NOCHECK-NEXT:    .set at
+; NOCHECK-NEXT:    .set macro
+; NOCHECK-NEXT:    .set reorder
+; NOCHECK-EMPTY:
+; NOCHECK-NEXT:    div $zero, $2, $3
+; NOCHECK-NEXT:    mflo $2
+; NOCHECK-EMPTY:
+; NOCHECK-NEXT:    .set pop
+; NOCHECK-NEXT:    #NO_APP
+; NOCHECK-NEXT:    jr $ra
+; NOCHECK-NEXT:    nop
+entry:
+  %0 = tail call i32 asm sideeffect "div $0, $1, $2", "=r,r,r,~{hi},~{lo},~{$1}"(i32 2, i32 1)
+  ret i32 %0
+}
+
+define i32 @inline_asm_rem() {
+; ACC64-TRAP-LABEL: inline_asm_rem:
+; ACC64-TRAP:       # %bb.0: # %entry
+; ACC64-TRAP-NEXT:    addiu $2, $zero, 2
+; ACC64-TRAP-NEXT:    addiu $3, $zero, 1
+; ACC64-TRAP-NEXT:    #APP
+; ACC64-TRAP-NEXT:    .set push
+; ACC64-TRAP-NEXT:    .set at
+; ACC64-TRAP-NEXT:    .set macro
+; ACC64-TRAP-NEXT:    .set reorder
+; ACC64-TRAP-EMPTY:
+; ACC64-TRAP-NEXT:    div $zero, $2, $3
+; ACC64-TRAP-NEXT:    bnez $3, .Ltmp1
+; ACC64-TRAP-NEXT:    break 7
+; ACC64-TRAP-NEXT:  .Ltmp1:
+; ACC64-TRAP-NEXT:    mfhi $2
+; ACC64-TRAP-EMPTY:
+; ACC64-TRAP-NEXT:    .set pop
+; ACC64-TRAP-NEXT:    #NO_APP
+; ACC64-TRAP-NEXT:    jr $ra
+; ACC64-TRAP-NEXT:    nop
+;
+; NOCHECK-LABEL: inline_asm_rem:
+; NOCHECK:       # %bb.0: # %entry
+; NOCHECK-NEXT:    addiu $2, $zero, 2
+; NOCHECK-NEXT:    addiu $3, $zero, 1
+; NOCHECK-NEXT:    #APP
+; NOCHECK-NEXT:    .set push
+; NOCHECK-NEXT:    .set at
+; NOCHECK-NEXT:    .set macro
+; NOCHECK-NEXT:    .set reorder
+; NOCHECK-EMPTY:
+; NOCHECK-NEXT:    div $zero, $2, $3
+; NOCHECK-NEXT:    mfhi $2
+; NOCHECK-EMPTY:
+; NOCHECK-NEXT:    .set pop
+; NOCHECK-NEXT:    #NO_APP
+; NOCHECK-NEXT:    jr $ra
+; NOCHECK-NEXT:    nop
+entry:
+  %0 = tail call i32 asm sideeffect "rem $0, $1, $2", "=r,r,r,~{hi},~{lo},~{$1}"(i32 2, i32 1)
+  ret i32 %0
+}
+
+define i64 @inline_asm_ddiv() {
+; ACC64-TRAP-LABEL: inline_asm_ddiv:
+; ACC64-TRAP:       # %bb.0: # %entry
+; ACC64-TRAP-NEXT:    daddiu $2, $zero, 2
+; ACC64-TRAP-NEXT:    daddiu $3, $zero, 1
+; ACC64-TRAP-NEXT:    #APP
+; ACC64-TRAP-NEXT:    .set push
+; ACC64-TRAP-NEXT:    .set at
+; ACC64-TRAP-NEXT:    .set macro
+; ACC64-TRAP-NEXT:    .set reorder
+; ACC64-TRAP-EMPTY:
+; ACC64-TRAP-NEXT:    ddiv $zero, $2, $3
+; ACC64-TRAP-NEXT:    bne $3, $zero, .Ltmp2
+; ACC64-TRAP-NEXT:    break 7
+; ACC64-TRAP-NEXT:  .Ltmp2:
+; ACC64-TRAP-NEXT:    mflo $2
+; ACC64-TRAP-EMPTY:
+; ACC64-TRAP-NEXT:    .set pop
+; ACC64-TRAP-NEXT:    #NO_APP
+; ACC64-TRAP-NEXT:    jr $ra
+; ACC64-TRAP-NEXT:    nop
+;
+; NOCHECK-LABEL: inline_asm_ddiv:
+; NOCHECK:       # %bb.0: # %entry
+; NOCHECK-NEXT:    daddiu $2, $zero, 2
+; NOCHECK-NEXT:    daddiu $3, $zero, 1
+; NOCHECK-NEXT:    #APP
+; NOCHECK-NEXT:    .set push
+; NOCHECK-NEXT:    .set at
+; NOCHECK-NEXT:    .set macro
+; NOCHECK-NEXT:    .set reorder
+; NOCHECK-EMPTY:
+; NOCHECK-NEXT:    ddiv $zero, $2, $3
+; NOCHECK-NEXT:    mflo $2
+; NOCHECK-EMPTY:
+; NOCHECK-NEXT:    .set pop
+; NOCHECK-NEXT:    #NO_APP
+; NOCHECK-NEXT:    jr $ra
+; NOCHECK-NEXT:    nop
+entry:
+  %0 = tail call i64 asm sideeffect "ddiv $1, $2", "=r,r,r,~{hi},~{lo},~{$1}"(i64 2, i64 1)
+  ret i64 %0
+}
+
+define i64 @inline_asm_drem() {
+; ACC64-TRAP-LABEL: inline_asm_drem:
+; ACC64-TRAP:       # %bb.0: # %entry
+; ACC64-TRAP-NEXT:    daddiu $2, $zero, 2
+; ACC64-TRAP-NEXT:    daddiu $3, $zero, 1
+; ACC64-TRAP-NEXT:    #APP
+; ACC64-TRAP-NEXT:    .set push
+; ACC64-TRAP-NEXT:    .set at
+; ACC64-TRAP-NEXT:    .set macro
+; ACC64-TRAP-NEXT:    .set reorder
+; ACC64-TRAP-EMPTY:
+; ACC64-TRAP-NEXT:    ddiv $zero, $2, $3
+; ACC64-TRAP-NEXT:    bne $3, $zero, .Ltmp3
+; ACC64-TRAP-NEXT:    break 7
+; ACC64-TRAP-NEXT:  .Ltmp3:
+; ACC64-TRAP-NEXT:    mfhi $2
+; ACC64-TRAP-EMPTY:
+; ACC64-TRAP-NEXT:    .set pop
+; ACC64-TRAP-NEXT:    #NO_APP
+; ACC64-TRAP-NEXT:    jr $ra
+; ACC64-TRAP-NEXT:    nop
+;
+; NOCHECK-LABEL: inline_asm_drem:
+; NOCHECK:       # %bb.0: # %entry
+; NOCHECK-NEXT:    daddiu $2, $zero, 2
+; NOCHECK-NEXT:    daddiu $3, $zero, 1
+; NOCHECK-NEXT:    #APP
+; NOCHECK-NEXT:    .set push
+; NOCHECK-NEXT:    .set at
+; NOCHECK-NEXT:    .set macro
+; NOCHECK-NEXT:    .set reorder
+; NOCHECK-EMPTY:
+; NOCHECK-NEXT:    ddiv $zero, $2, $3
+; NOCHECK-NEXT:    mfhi $2
+; NOCHECK-EMPTY:
+; NOCHECK-NEXT:    .set pop
+; NOCHECK-NEXT:    #NO_APP
+; NOCHECK-NEXT:    jr $ra
+; NOCHECK-NEXT:    nop
+entry:
+  %0 = tail call i64 asm sideeffect "drem $1, $2", "=r,r,r,~{hi},~{lo},~{$1}"(i64 2, i64 1)
+  ret i64 %0
+}
+
+define i32 @inline_asm_divu() {
+; ACC64-TRAP-LABEL: inline_asm_divu:
+; ACC64-TRAP:       # %bb.0: # %entry
+; ACC64-TRAP-NEXT:    addiu $2, $zero, 2
+; ACC64-TRAP-NEXT:    addiu $3, $zero, 1
+; ACC64-TRAP-NEXT:    #APP
+; ACC64-TRAP-NEXT:    .set push
+; ACC64-TRAP-NEXT:    .set at
+; ACC64-TRAP-NEXT:    .set macro
+; ACC64-TRAP-NEXT:    .set reorder
+; ACC64-TRAP-EMPTY:
+; ACC64-TRAP-NEXT:    divu $zero, $2, $3
+; ACC64-TRAP-NEXT:    bnez $3, .Ltmp4
+; ACC64-TRAP-NEXT:    break 7
+; ACC64-TRAP-NEXT:  .Ltmp4:
+; ACC64-TRAP-NEXT:    mflo $2
+; ACC64-TRAP-EMPTY:
+; ACC64-TRAP-NEXT:    .set pop
+; ACC64-TRAP-NEXT:    #NO_APP
+; ACC64-TRAP-NEXT:    jr $ra
+; ACC64-TRAP-NEXT:    nop
+;
+; NOCHECK-LABEL: inline_asm_divu:
+; NOCHECK:       # %bb.0: # %entry
+; NOCHECK-NEXT:    addiu $2, $zero, 2
+; NOCHECK-NEXT:    addiu $3, $zero, 1
+; NOCHECK-NEXT:    #APP
+; NOCHECK-NEXT:    .set push
+; NOCHECK-NEXT:    .set at
+; NOCHECK-NEXT:    .set macro
+; NOCHECK-NEXT:    .set reorder
+; NOCHECK-EMPTY:
+; NOCHECK-NEXT:    divu $zero, $2, $3
+; NOCHECK-NEXT:    mflo $2
+; NOCHECK-EMPTY:
+; NOCHECK-NEXT:    .set pop
+; NOCHECK-NEXT:    #NO_APP
+; NOCHECK-NEXT:    jr $ra
+; NOCHECK-NEXT:    nop
+entry:
+  %0 = tail call i32 asm sideeffect "divu $0, $1, $2", "=r,r,r,~{hi},~{lo},~{$1}"(i32 2, i32 1)
+  ret i32 %0
+}
+
+define i32 @inline_asm_remu() {
+; ACC64-TRAP-LABEL: inline_asm_remu:
+; ACC64-TRAP:       # %bb.0: # %entry
+; ACC64-TRAP-NEXT:    addiu $2, $zero, 2
+; ACC64-TRAP-NEXT:    addiu $3, $zero, 1
+; ACC64-TRAP-NEXT:    #APP
+; ACC64-TRAP-NEXT:    .set push
+; ACC64-TRAP-NEXT:    .set at
+; ACC64-TRAP-NEXT:    .set macro
+; ACC64-TRAP-NEXT:    .set reorder
+; ACC64-TRAP-EMPTY:
+; ACC64-TRAP-NEXT:    divu $zero, $2, $3
+; ACC64-TRAP-NEXT:    bnez $3, .Ltmp5
+; ACC64-TRAP-NEXT:    break 7
+; ACC64-TRAP-NEXT:  .Ltmp5:
+; ACC64-TRAP-NEXT:    mfhi $2
+; ACC64-TRAP-EMPTY:
+; ACC64-TRAP-NEXT:    .set pop
+; ACC64-TRAP-NEXT:    #NO_APP
+; ACC64-TRAP-NEXT:    jr $ra
+; ACC64-TRAP-NEXT:    nop
+;
+; NOCHECK-LABEL: inline_asm_remu:
+; NOCHECK:       # %bb.0: # %entry
+; NOCHECK-NEXT:    addiu $2, $zero, 2
+; NOCHECK-NEXT:    addiu $3, $zero, 1
+; NOCHECK-NEXT:    #APP
+; NOCHECK-NEXT:    .set push
+; NOCHECK-NEXT:    .set at
+; NOCHECK-NEXT:    .set macro
+; NOCHECK-NEXT:    .set reorder
+; NOCHECK-EMPTY:
+; NOCHECK-NEXT:    divu $zero, $2, $3
+; NOCHECK-NEXT:    mfhi $2
+; NOCHECK-EMPTY:
+; NOCHECK-NEXT:    .set pop
+; NOCHECK-NEXT:    #NO_APP
+; NOCHECK-NEXT:    jr $ra
+; NOCHECK-NEXT:    nop
+entry:
+  %0 = tail call i32 asm sideeffect "remu $0, $1, $2", "=r,r,r,~{hi},~{lo},~{$1}"(i32 2, i32 1)
+  ret i32 %0
+}
+
+define i64 @inline_asm_ddivu() {
+; ACC64-TRAP-LABEL: inline_asm_ddivu:
+; ACC64-TRAP:       # %bb.0: # %entry
+; ACC64-TRAP-NEXT:    daddiu $2, $zero, 2
+; ACC64-TRAP-NEXT:    daddiu $3, $zero, 1
+; ACC64-TRAP-NEXT:    #APP
+; ACC64-TRAP-NEXT:    .set push
+; ACC64-TRAP-NEXT:    .set at
+; ACC64-TRAP-NEXT:    .set macro
+; ACC64-TRAP-NEXT:    .set reorder
+; ACC64-TRAP-EMPTY:
+; ACC64-TRAP-NEXT:    ddivu $zero, $2, $3
+; ACC64-TRAP-NEXT:    bne $3, $zero, .Ltmp6
+; ACC64-TRAP-NEXT:    break 7
+; ACC64-TRAP-NEXT:  .Ltmp6:
+; ACC64-TRAP-NEXT:    mflo $2
+; ACC64-TRAP-EMPTY:
+; ACC64-TRAP-NEXT:    .set pop
+; ACC64-TRAP-NEXT:    #NO_APP
+; ACC64-TRAP-NEXT:    jr $ra
+; ACC64-TRAP-NEXT:    nop
+;
+; NOCHECK-LABEL: inline_asm_ddivu:
+; NOCHECK:       # %bb.0: # %entry
+; NOCHECK-NEXT:    daddiu $2, $zero, 2
+; NOCHECK-NEXT:    daddiu $3, $zero, 1
+; NOCHECK-NEXT:    #APP
+; NOCHECK-NEXT:    .set push
+; NOCHECK-NEXT:    .set at
+; NOCHECK-NEXT:    .set macro
+; NOCHECK-NEXT:    .set reorder
+; NOCHECK-EMPTY:
+; NOCHECK-NEXT:    ddivu $zero, $2, $3
+; NOCHECK-NEXT:    mflo $2
+; NOCHECK-EMPTY:
+; NOCHECK-NEXT:    .set pop
+; NOCHECK-NEXT:    #NO_APP
+; NOCHECK-NEXT:    jr $ra
+; NOCHECK-NEXT:    nop
+entry:
+  %0 = tail call i64 asm sideeffect "ddivu $1, $2", "=r,r,r,~{hi},~{lo},~{$1}"(i64 2, i64 1)
+  ret i64 %0
+}
+
+define i64 @inline_asm_dremu() {
+; ACC64-TRAP-LABEL: inline_asm_dremu:
+; ACC64-TRAP:       # %bb.0: # %entry
+; ACC64-TRAP-NEXT:    daddiu $2, $zero, 2
+; ACC64-TRAP-NEXT:    daddiu $3, $zero, 1
+; ACC64-TRAP-NEXT:    #APP
+; ACC64-TRAP-NEXT:    .set push
+; ACC64-TRAP-NEXT:    .set at
+; ACC64-TRAP-NEXT:    .set macro
+; ACC64-TRAP-NEXT:    .set reorder
+; ACC64-TRAP-EMPTY:
+; ACC64-TRAP-NEXT:    ddivu $zero, $2, $3
+; ACC64-TRAP-NEXT:    bne $3, $zero, .Ltmp7
+; ACC64-TRAP-NEXT:    break 7
+; ACC64-TRAP-NEXT:  .Ltmp7:
+; ACC64-TRAP-NEXT:    mfhi $2
+; ACC64-TRAP-EMPTY:
+; ACC64-TRAP-NEXT:    .set pop
+; ACC64-TRAP-NEXT:    #NO_APP
+; ACC64-TRAP-NEXT:    jr $ra
+; ACC64-TRAP-NEXT:    nop
+;
+; NOCHECK-LABEL: inline_asm_dremu:
+; NOCHECK:       # %bb.0: # %entry
+; NOCHECK-NEXT:    daddiu $2, $zero, 2
+; NOCHECK-NEXT:    daddiu $3, $zero, 1
+; NOCHECK-NEXT:    #APP
+; NOCHECK-NEXT:    .set push
+; NOCHECK-NEXT:    .set at
+; NOCHECK-NEXT:    .set macro
+; NOCHECK-NEXT:    .set reorder
+; NOCHECK-EMPTY:
+; NOCHECK-NEXT:    ddivu $zero, $2, $3
+; NOCHECK-NEXT:    mfhi $2
+; NOCHECK-EMPTY:
+; NOCHECK-NEXT:    .set pop
+; NOCHECK-NEXT:    #NO_APP
+; NOCHECK-NEXT:    jr $ra
+; NOCHECK-NEXT:    nop
+entry:
+  %0 = tail call i64 asm sideeffect "dremu $1, $2", "=r,r,r,~{hi},~{lo},~{$1}"(i64 2, i64 1)
+  ret i64 %0
+}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; ACC64: {{.*}}
+; ALL: {{.*}}

>From 40847e76cc72dd48b84024b99d393fb601a40e95 Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Fri, 19 Dec 2025 15:59:59 +0800
Subject: [PATCH 2/2] Fix code format

---
 llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp  | 3 ++-
 llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp | 6 +++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 582b2c91c8052..24f9f73fc41de 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -4298,7 +4298,8 @@ bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
     } else {
       // Branch to the li instruction.
       BrTarget = Context.createTempSymbol();
-      LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
+      LabelOp =
+          MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
       TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
     }
 
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
index 663d04f26bd45..59c8e7c72224e 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
@@ -21,9 +21,9 @@ EmitJalrReloc("mips-jalr-reloc", cl::Hidden,
               cl::desc("MIPS: Emit R_{MICRO}MIPS_JALR relocation with jalr"),
               cl::init(true));
 cl::opt<bool>
-NoZeroDivCheck("mno-check-zero-division", cl::Hidden,
-               cl::desc("MIPS: Don't trap on integer division by zero."),
-               cl::init(false));
+    NoZeroDivCheck("mno-check-zero-division", cl::Hidden,
+                   cl::desc("MIPS: Don't trap on integer division by zero."),
+                   cl::init(false));
 
 namespace {
 static const MCPhysReg O32IntRegs[4] = {Mips::A0, Mips::A1, Mips::A2, Mips::A3};



More information about the llvm-commits mailing list