[llvm] [Mips] Fix clang crashes when assembling invalid MIPS beql instructions with --arch=mips (PR #156413)

via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 10 00:51:28 PDT 2025


https://github.com/yingopq updated https://github.com/llvm/llvm-project/pull/156413

>From 9fd2966ef020083e9101842a793c41519d13bbef Mon Sep 17 00:00:00 2001
From: Ying Huang <ying.huang at oss.cipunited.com>
Date: Mon, 1 Sep 2025 22:38:25 -0400
Subject: [PATCH] [Mips] Fix clang crashes when assembling invalid MIPS beql
 instructions with --arch=mips

>From clang version 4, mips append new instruction BeqImm and
BEQLImm, the second operand format of instruction is imm64:$imm.

1.When Mips process `beql $t0, ($t0), 1`, it think the second operand
was an imm, so match success. Then mips backend process expandBranchImm,
check the second operand `$t0` was not imm, reported asserts.
We can strengthen the second operand matching restrictions.

2.Similarly, when Mips process `beql $t0, (1), 1`, it think the second
was an imm. so match success. Then mips backend process expandBranchImm,
check the third operand `1` was not expression, reported asserts. Permit
the third operand of `beql`  to be imm.

Fix #151453.
---
 llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp |  2 +-
 llvm/lib/Target/Mips/MipsInstrInfo.td            | 16 +++++++++++++---
 llvm/test/MC/Mips/branch-pseudos-bad.s           |  8 ++++++++
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 7b2ee832ae7db..142576a540bf3 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -3677,7 +3677,7 @@ bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
                       Out, STI))
       return true;
 
-    if (IsLikely) {
+    if (IsLikely && MemOffsetOp.isExpr()) {
       TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
               MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
       TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td
index a124e84e9ca5f..44e9a6cedbac6 100644
--- a/llvm/lib/Target/Mips/MipsInstrInfo.td
+++ b/llvm/lib/Target/Mips/MipsInstrInfo.td
@@ -857,6 +857,16 @@ def calltarget  : Operand<iPTR> {
 
 def imm64: Operand<i64>;
 
+def ConstantImmAsmOperandClass : AsmOperandClass {
+  let Name = "ConstantImm";
+  let PredicateMethod = "isConstantImm";
+  let RenderMethod = "addImmOperands";
+}
+
+def ConstantImm64: Operand<i64> {
+  let ParserMatchClass = ConstantImmAsmOperandClass;
+}
+
 def simm19_lsl2 : Operand<i32> {
   let EncoderMethod = "getSimm19Lsl2Encoding";
   let DecoderMethod = "DecodeSimm19Lsl2";
@@ -2949,10 +2959,10 @@ def : MipsInstAlias<"nor\t$rs, $imm", (NORImm GPR32Opnd:$rs, GPR32Opnd:$rs,
 
 let hasDelaySlot = 1, isCTI = 1 in {
 def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
-                               (ins imm64:$imm64, brtarget:$offset),
+                               (ins ConstantImm64:$imm64, brtarget:$offset),
                                "bne\t$rt, $imm64, $offset">;
 def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
-                               (ins imm64:$imm64, brtarget:$offset),
+                               (ins ConstantImm64:$imm64, brtarget:$offset),
                                "beq\t$rt, $imm64, $offset">;
 
 class CondBranchPseudo<string instr_asm> :
@@ -2980,7 +2990,7 @@ def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
 
 let isCTI = 1 in
 class CondBranchImmPseudo<string instr_asm> :
-  MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
+  MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, ConstantImm64:$imm, brtarget:$offset),
                     !strconcat(instr_asm, "\t$rs, $imm, $offset")>;
 
 def BEQLImmMacro : CondBranchImmPseudo<"beql">, ISA_MIPS2_NOT_32R6_64R6;
diff --git a/llvm/test/MC/Mips/branch-pseudos-bad.s b/llvm/test/MC/Mips/branch-pseudos-bad.s
index c23164d904619..9633414d84f4a 100644
--- a/llvm/test/MC/Mips/branch-pseudos-bad.s
+++ b/llvm/test/MC/Mips/branch-pseudos-bad.s
@@ -1,5 +1,13 @@
 # RUN: not llvm-mc %s -triple=mips -mcpu=mips32 2>&1 | FileCheck %s
 
+# CHECK: error: invalid operand for instruction
+  beql $t0, ($t0), 1
+# CHECK: error: invalid operand for instruction
+  bne $t0, ($t0), 1
+# CHECK: error: invalid operand for instruction
+  beq $t0, ($t0), 1
+
+
 # Check for errors when using conditional branch pseudos after .set noat.
   .set noat
 local_label:



More information about the llvm-commits mailing list