Skip to content

Commit c907d7d

Browse files
authored
Mips: Improve MipsAsmParser::expandDivRem (#172967)
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.
1 parent 40d97e9 commit c907d7d

File tree

12 files changed

+1559
-1233
lines changed

12 files changed

+1559
-1233
lines changed

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

Lines changed: 15 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class MCInstrInfo;
6868
} // end namespace llvm
6969

7070
extern cl::opt<bool> EmitJalrReloc;
71+
extern cl::opt<bool> NoZeroDivCheck;
7172

7273
namespace {
7374

@@ -4237,7 +4238,7 @@ bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
42374238
if (!ATReg)
42384239
return true;
42394240

4240-
if (ImmValue == 0) {
4241+
if (!NoZeroDivCheck && ImmValue == 0) {
42414242
if (UseTraps)
42424243
TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
42434244
else
@@ -4269,7 +4270,7 @@ bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
42694270
// break, insert the trap/break and exit. This gives a different result to
42704271
// GAS. GAS has an inconsistency/missed optimization in that not all cases
42714272
// are handled equivalently. As the observed behaviour is the same, we're ok.
4272-
if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4273+
if (!NoZeroDivCheck && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
42734274
if (UseTraps) {
42744275
TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
42754276
return false;
@@ -4290,62 +4291,25 @@ bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
42904291
MCSymbol *BrTarget;
42914292
MCOperand LabelOp;
42924293

4293-
if (UseTraps) {
4294-
TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4295-
} else {
4296-
// Branch to the li instruction.
4297-
BrTarget = Context.createTempSymbol();
4298-
LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4299-
TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4300-
}
4301-
43024294
TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4295+
if (!NoZeroDivCheck) {
4296+
if (UseTraps) {
4297+
TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4298+
} else {
4299+
// Branch to the li instruction.
4300+
BrTarget = Context.createTempSymbol();
4301+
LabelOp =
4302+
MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4303+
TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4304+
}
43034305

4304-
if (!UseTraps)
4305-
TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4306+
if (!UseTraps)
4307+
TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
43064308

4307-
if (!Signed) {
43084309
if (!UseTraps)
43094310
TOut.getStreamer().emitLabel(BrTarget);
4310-
4311-
TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4312-
return false;
4313-
}
4314-
4315-
MCRegister ATReg = getATReg(IDLoc);
4316-
if (!ATReg)
4317-
return true;
4318-
4319-
if (!UseTraps)
4320-
TOut.getStreamer().emitLabel(BrTarget);
4321-
4322-
TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4323-
4324-
// Temporary label for the second branch target.
4325-
MCSymbol *BrTargetEnd = Context.createTempSymbol();
4326-
MCOperand LabelOpEnd =
4327-
MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4328-
4329-
// Branch to the mflo instruction.
4330-
TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4331-
4332-
if (IsMips64) {
4333-
TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4334-
TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4335-
} else {
4336-
TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4337-
}
4338-
4339-
if (UseTraps)
4340-
TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4341-
else {
4342-
// Branch to the mflo instruction.
4343-
TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4344-
TOut.emitNop(IDLoc, STI);
4345-
TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
43464311
}
43474312

4348-
TOut.getStreamer().emitLabel(BrTargetEnd);
43494313
TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
43504314
return false;
43514315
}

llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ cl::opt<bool>
2020
EmitJalrReloc("mips-jalr-reloc", cl::Hidden,
2121
cl::desc("MIPS: Emit R_{MICRO}MIPS_JALR relocation with jalr"),
2222
cl::init(true));
23+
cl::opt<bool>
24+
NoZeroDivCheck("mno-check-zero-division", cl::Hidden,
25+
cl::desc("MIPS: Don't trap on integer division by zero."),
26+
cl::init(false));
2327

2428
namespace {
2529
static const MCPhysReg O32IntRegs[4] = {Mips::A0, Mips::A1, Mips::A2, Mips::A3};

llvm/lib/Target/Mips/MipsISelLowering.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,8 @@ using namespace llvm;
8383

8484
STATISTIC(NumTailCalls, "Number of tail calls");
8585

86-
static cl::opt<bool>
87-
NoZeroDivCheck("mno-check-zero-division", cl::Hidden,
88-
cl::desc("MIPS: Don't trap on integer division by zero."),
89-
cl::init(false));
90-
9186
extern cl::opt<bool> EmitJalrReloc;
87+
extern cl::opt<bool> NoZeroDivCheck;
9288

9389
static const MCPhysReg Mips64DPRegs[8] = {
9490
Mips::D12_64, Mips::D13_64, Mips::D14_64, Mips::D15_64,

0 commit comments

Comments
 (0)