[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