Skip to content

Commit 13bee3a

Browse files
yingopqc-rhodes
authored andcommitted
[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. (cherry picked from commit 51eee20)
1 parent 0d1b924 commit 13bee3a

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
@@ -3676,7 +3676,7 @@ bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
36763676
Out, STI))
36773677
return true;
36783678

3679-
if (IsLikely) {
3679+
if (IsLikely && MemOffsetOp.isExpr()) {
36803680
TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
36813681
MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
36823682
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
@@ -858,6 +858,16 @@ def calltarget : Operand<iPTR> {
858858

859859
def imm64: Operand<i64>;
860860

861+
def ConstantImmAsmOperandClass : AsmOperandClass {
862+
let Name = "ConstantImm";
863+
let PredicateMethod = "isConstantImm";
864+
let RenderMethod = "addImmOperands";
865+
}
866+
867+
def ConstantImm64: Operand<i64> {
868+
let ParserMatchClass = ConstantImmAsmOperandClass;
869+
}
870+
861871
def simm19_lsl2 : Operand<i32> {
862872
let EncoderMethod = "getSimm19Lsl2Encoding";
863873
let DecoderMethod = "DecodeSimm19Lsl2";
@@ -2950,10 +2960,10 @@ def : MipsInstAlias<"nor\t$rs, $imm", (NORImm GPR32Opnd:$rs, GPR32Opnd:$rs,
29502960

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

29592969
class CondBranchPseudo<string instr_asm> :
@@ -2981,7 +2991,7 @@ def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
29812991

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

29872997
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)