Skip to content

Commit 51eee20

Browse files
authored
[Mips] Fix clang crashes when assembling invalid MIPS beql instructions with --arch=mips (#156413)
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. Fixes #151453.
1 parent ef4598f commit 51eee20

File tree

3 files changed

+22
-4
lines changed

3 files changed

+22
-4
lines changed

llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3677,7 +3677,7 @@ bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
36773677
Out, STI))
36783678
return true;
36793679

3680-
if (IsLikely) {
3680+
if (IsLikely && MemOffsetOp.isExpr()) {
36813681
TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
36823682
MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
36833683
TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);

llvm/lib/Target/Mips/MipsInstrInfo.td

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,16 @@ def calltarget : Operand<iPTR> {
855855

856856
def imm64: Operand<i64>;
857857

858+
def ConstantImmAsmOperandClass : AsmOperandClass {
859+
let Name = "ConstantImm";
860+
let PredicateMethod = "isConstantImm";
861+
let RenderMethod = "addImmOperands";
862+
}
863+
864+
def ConstantImm64: Operand<i64> {
865+
let ParserMatchClass = ConstantImmAsmOperandClass;
866+
}
867+
858868
def simm19_lsl2 : Operand<i32> {
859869
let EncoderMethod = "getSimm19Lsl2Encoding";
860870
let DecoderMethod = "DecodeSimm19Lsl2";
@@ -2947,10 +2957,10 @@ def : MipsInstAlias<"nor\t$rs, $imm", (NORImm GPR32Opnd:$rs, GPR32Opnd:$rs,
29472957

29482958
let hasDelaySlot = 1, isCTI = 1 in {
29492959
def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2950-
(ins imm64:$imm64, brtarget:$offset),
2960+
(ins ConstantImm64:$imm64, brtarget:$offset),
29512961
"bne\t$rt, $imm64, $offset">;
29522962
def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2953-
(ins imm64:$imm64, brtarget:$offset),
2963+
(ins ConstantImm64:$imm64, brtarget:$offset),
29542964
"beq\t$rt, $imm64, $offset">;
29552965

29562966
class CondBranchPseudo<string instr_asm> :
@@ -2978,7 +2988,7 @@ def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
29782988

29792989
let isCTI = 1 in
29802990
class CondBranchImmPseudo<string instr_asm> :
2981-
MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
2991+
MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, ConstantImm64:$imm, brtarget:$offset),
29822992
!strconcat(instr_asm, "\t$rs, $imm, $offset")>;
29832993

29842994
def BEQLImmMacro : CondBranchImmPseudo<"beql">, ISA_MIPS2_NOT_32R6_64R6;

llvm/test/MC/Mips/branch-pseudos-bad.s

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# RUN: not llvm-mc %s -triple=mips -mcpu=mips32 2>&1 | FileCheck %s
22

3+
# CHECK: error: invalid operand for instruction
4+
beql $t0, ($t0), 1
5+
# CHECK: error: invalid operand for instruction
6+
bne $t0, ($t0), 1
7+
# CHECK: error: invalid operand for instruction
8+
beq $t0, ($t0), 1
9+
10+
311
# Check for errors when using conditional branch pseudos after .set noat.
412
.set noat
513
local_label:

0 commit comments

Comments
 (0)