Skip to content

Commit 6d298fe

Browse files
Fix ARM64 LEA legalization
1 parent 34967a4 commit 6d298fe

File tree

7 files changed

+176
-130
lines changed

7 files changed

+176
-130
lines changed

lib/Backend/IR.cpp

Lines changed: 0 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -2520,54 +2520,6 @@ Instr::HoistSrc2(Js::OpCode assignOpcode, RegNum regNum, StackSym *newSym)
25202520
return newInstr;
25212521
}
25222522

2523-
///----------------------------------------------------------------------------
2524-
///
2525-
/// Instr::HoistIndirOffset
2526-
///
2527-
/// Replace the offset of the given indir with a new symbol, which becomes the indir index.
2528-
/// Assign the new symbol by creating an assignment from the constant offset.
2529-
///
2530-
///----------------------------------------------------------------------------
2531-
2532-
Instr *
2533-
Instr::HoistIndirOffset(IR::IndirOpnd *indirOpnd, RegNum regNum)
2534-
{
2535-
int32 offset = indirOpnd->GetOffset();
2536-
if (indirOpnd->GetIndexOpnd())
2537-
{
2538-
Assert(indirOpnd->GetBaseOpnd());
2539-
return HoistIndirOffsetAsAdd(indirOpnd, indirOpnd->GetBaseOpnd(), offset, regNum);
2540-
}
2541-
IntConstOpnd *offsetOpnd = IntConstOpnd::New(offset, TyInt32, this->m_func);
2542-
RegOpnd *indexOpnd = RegOpnd::New(StackSym::New(TyMachReg, this->m_func), regNum, TyMachReg, this->m_func);
2543-
2544-
#if defined(DBG) && defined(_M_ARM)
2545-
if (regNum == SCRATCH_REG)
2546-
{
2547-
AssertMsg(indirOpnd->GetBaseOpnd()->GetReg()!= SCRATCH_REG, "Why both are SCRATCH_REG");
2548-
if (this->GetSrc1() && this->GetSrc1()->IsRegOpnd())
2549-
{
2550-
Assert(this->GetSrc1()->AsRegOpnd()->GetReg() != SCRATCH_REG);
2551-
}
2552-
if (this->GetSrc2() && this->GetSrc2()->IsRegOpnd())
2553-
{
2554-
Assert(this->GetSrc2()->AsRegOpnd()->GetReg() != SCRATCH_REG);
2555-
}
2556-
if (this->GetDst() && this->GetDst()->IsRegOpnd())
2557-
{
2558-
Assert(this->GetDst()->AsRegOpnd()->GetReg() != SCRATCH_REG);
2559-
}
2560-
}
2561-
#endif
2562-
// Clear the offset and add a new reg as the index.
2563-
indirOpnd->SetOffset(0);
2564-
indirOpnd->SetIndexOpnd(indexOpnd);
2565-
2566-
Instr *instrAssign = Lowerer::InsertMove(indexOpnd, offsetOpnd, this);
2567-
indexOpnd->m_sym->SetIsIntConst(offset);
2568-
return instrAssign;
2569-
}
2570-
25712523
IndirOpnd *
25722524
Instr::HoistMemRefAddress(MemRefOpnd *const memRefOpnd, const Js::OpCode loadOpCode)
25732525
{
@@ -2640,71 +2592,6 @@ Opnd *Instr::DeepReplace(Opnd *const oldOpnd, Opnd *const newOpnd)
26402592
return Replace(oldOpnd, newOpnd);
26412593
}
26422594

2643-
Instr *
2644-
Instr::HoistIndirOffsetAsAdd(IR::IndirOpnd *orgOpnd, IR::Opnd *baseOpnd, int offset, RegNum regNum)
2645-
{
2646-
IR::RegOpnd *newBaseOpnd = IR::RegOpnd::New(StackSym::New(TyMachPtr, this->m_func), regNum, TyMachPtr, this->m_func);
2647-
2648-
IR::IntConstOpnd *src2 = IR::IntConstOpnd::New(offset, TyInt32, this->m_func);
2649-
IR::Instr * instrAdd = IR::Instr::New(Js::OpCode::ADD, newBaseOpnd, baseOpnd, src2, this->m_func);
2650-
2651-
this->InsertBefore(instrAdd);
2652-
2653-
orgOpnd->ReplaceBaseOpnd(newBaseOpnd);
2654-
orgOpnd->SetOffset(0);
2655-
2656-
return instrAdd;
2657-
}
2658-
2659-
Instr *
2660-
Instr::HoistIndirIndexOpndAsAdd(IR::IndirOpnd *orgOpnd, IR::Opnd *baseOpnd, IR::Opnd *indexOpnd, RegNum regNum)
2661-
{
2662-
IR::RegOpnd *newBaseOpnd = IR::RegOpnd::New(StackSym::New(TyMachPtr, this->m_func), regNum, TyMachPtr, this->m_func);
2663-
2664-
IR::Instr * instrAdd = IR::Instr::New(Js::OpCode::ADD, newBaseOpnd, baseOpnd, indexOpnd->UseWithNewType(TyMachPtr, this->m_func), this->m_func);
2665-
2666-
this->InsertBefore(instrAdd);
2667-
2668-
orgOpnd->ReplaceBaseOpnd(newBaseOpnd);
2669-
orgOpnd->SetIndexOpnd(nullptr);
2670-
2671-
return instrAdd;
2672-
}
2673-
2674-
Instr *
2675-
Instr::HoistSymOffsetAsAdd(IR::SymOpnd *orgOpnd, IR::Opnd *baseOpnd, int offset, RegNum regNum)
2676-
{
2677-
IR::IndirOpnd *newIndirOpnd = IR::IndirOpnd::New(baseOpnd->AsRegOpnd(), 0, TyMachPtr, this->m_func);
2678-
this->Replace(orgOpnd, newIndirOpnd); // Replace SymOpnd with IndirOpnd
2679-
return this->HoistIndirOffsetAsAdd(newIndirOpnd, baseOpnd, offset, regNum);
2680-
}
2681-
2682-
///----------------------------------------------------------------------------
2683-
///
2684-
/// Instr::HoistSymOffset
2685-
///
2686-
/// Replace the given sym with an indir using the given base and offset.
2687-
/// (This is used, for instance, to hoist a sym offset that is too large to encode.)
2688-
///
2689-
///----------------------------------------------------------------------------
2690-
2691-
Instr *
2692-
Instr::HoistSymOffset(SymOpnd *symOpnd, RegNum baseReg, uint32 offset, RegNum regNum)
2693-
{
2694-
IR::RegOpnd *baseOpnd = IR::RegOpnd::New(nullptr, baseReg, TyMachPtr, this->m_func);
2695-
IR::IndirOpnd *indirOpnd = IR::IndirOpnd::New(baseOpnd, offset, symOpnd->GetType(), this->m_func);
2696-
if (symOpnd == this->GetDst())
2697-
{
2698-
this->ReplaceDst(indirOpnd);
2699-
}
2700-
else
2701-
{
2702-
this->ReplaceSrc(symOpnd, indirOpnd);
2703-
}
2704-
2705-
return this->HoistIndirOffset(indirOpnd, regNum);
2706-
}
2707-
27082595
Opnd *
27092596
Instr::UnlinkSrc(Opnd *src)
27102597
{

lib/Backend/IR.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -265,11 +265,6 @@ class Instr
265265
void FreeSrc2();
266266
Opnd * ReplaceSrc2(Opnd * newSrc);
267267
Instr * HoistSrc2(Js::OpCode assignOpcode, RegNum regNum = RegNOREG, StackSym *newSym = nullptr);
268-
Instr * HoistIndirOffset(IndirOpnd *indirOpnd, RegNum regNum = RegNOREG);
269-
Instr * HoistSymOffset(SymOpnd *symOpnd, RegNum baseReg, uint32 offset, RegNum regNum = RegNOREG);
270-
Instr * HoistIndirOffsetAsAdd(IndirOpnd *orgOpnd, IR::Opnd *baseOpnd, int offset, RegNum regNum);
271-
Instr * HoistSymOffsetAsAdd(SymOpnd *orgOpnd, IR::Opnd *baseOpnd, int offset, RegNum regNum);
272-
Instr * HoistIndirIndexOpndAsAdd(IR::IndirOpnd *orgOpnd, IR::Opnd *baseOpnd, IR::Opnd *indexOpnd, RegNum regNum);
273268
IndirOpnd * HoistMemRefAddress(MemRefOpnd *const memRefOpnd, const Js::OpCode loadOpCode);
274269
Opnd * UnlinkSrc(Opnd *src);
275270
Opnd * ReplaceSrc(Opnd *oldSrc, Opnd * newSrc);

lib/Backend/Lower.cpp

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14881,6 +14881,110 @@ IR::RegOpnd *Lowerer::GenerateArrayTest(
1488114881
return arrayOpnd;
1488214882
}
1488314883

14884+
///----------------------------------------------------------------------------
14885+
///
14886+
/// Instr::HoistIndirOffset
14887+
///
14888+
/// Replace the offset of the given indir with a new symbol, which becomes the indir index.
14889+
/// Assign the new symbol by creating an assignment from the constant offset.
14890+
///
14891+
///----------------------------------------------------------------------------
14892+
14893+
IR::Instr *Lowerer::HoistIndirOffset(IR::Instr* instr, IR::IndirOpnd *indirOpnd, RegNum regNum)
14894+
{
14895+
int32 offset = indirOpnd->GetOffset();
14896+
if (indirOpnd->GetIndexOpnd())
14897+
{
14898+
Assert(indirOpnd->GetBaseOpnd());
14899+
return Lowerer::HoistIndirOffsetAsAdd(instr, indirOpnd, indirOpnd->GetBaseOpnd(), offset, regNum);
14900+
}
14901+
IR::IntConstOpnd *offsetOpnd = IR::IntConstOpnd::New(offset, TyInt32, instr->m_func);
14902+
IR::RegOpnd *indexOpnd = IR::RegOpnd::New(StackSym::New(TyMachReg, instr->m_func), regNum, TyMachReg, instr->m_func);
14903+
14904+
#if defined(DBG) && defined(_M_ARM)
14905+
if (regNum == SCRATCH_REG)
14906+
{
14907+
AssertMsg(indirOpnd->GetBaseOpnd()->GetReg()!= SCRATCH_REG, "Why both are SCRATCH_REG");
14908+
if (instr->GetSrc1() && instr->GetSrc1()->IsRegOpnd())
14909+
{
14910+
Assert(instr->GetSrc1()->AsRegOpnd()->GetReg() != SCRATCH_REG);
14911+
}
14912+
if (instr->GetSrc2() && instr->GetSrc2()->IsRegOpnd())
14913+
{
14914+
Assert(instr->GetSrc2()->AsRegOpnd()->GetReg() != SCRATCH_REG);
14915+
}
14916+
if (instr->GetDst() && instr->GetDst()->IsRegOpnd())
14917+
{
14918+
Assert(instr->GetDst()->AsRegOpnd()->GetReg() != SCRATCH_REG);
14919+
}
14920+
}
14921+
#endif
14922+
// Clear the offset and add a new reg as the index.
14923+
indirOpnd->SetOffset(0);
14924+
indirOpnd->SetIndexOpnd(indexOpnd);
14925+
14926+
IR::Instr *instrAssign = Lowerer::InsertMove(indexOpnd, offsetOpnd, instr);
14927+
indexOpnd->m_sym->SetIsIntConst(offset);
14928+
return instrAssign;
14929+
}
14930+
14931+
IR::Instr *Lowerer::HoistIndirOffsetAsAdd(IR::Instr* instr, IR::IndirOpnd *orgOpnd, IR::Opnd *baseOpnd, int offset, RegNum regNum)
14932+
{
14933+
IR::RegOpnd *newBaseOpnd = IR::RegOpnd::New(StackSym::New(TyMachPtr, instr->m_func), regNum, TyMachPtr, instr->m_func);
14934+
14935+
IR::IntConstOpnd *src2 = IR::IntConstOpnd::New(offset, TyInt32, instr->m_func);
14936+
IR::Instr * instrAdd = Lowerer::InsertAdd(false, newBaseOpnd, baseOpnd, src2, instr);
14937+
14938+
orgOpnd->ReplaceBaseOpnd(newBaseOpnd);
14939+
orgOpnd->SetOffset(0);
14940+
14941+
return instrAdd;
14942+
}
14943+
14944+
IR::Instr *Lowerer::HoistIndirIndexOpndAsAdd(IR::Instr* instr, IR::IndirOpnd *orgOpnd, IR::Opnd *baseOpnd, IR::Opnd *indexOpnd, RegNum regNum)
14945+
{
14946+
IR::RegOpnd *newBaseOpnd = IR::RegOpnd::New(StackSym::New(TyMachPtr, instr->m_func), regNum, TyMachPtr, instr->m_func);
14947+
14948+
IR::Instr * instrAdd = Lowerer::InsertAdd(false, newBaseOpnd, baseOpnd, indexOpnd->UseWithNewType(TyMachPtr, instr->m_func), instr);
14949+
14950+
orgOpnd->ReplaceBaseOpnd(newBaseOpnd);
14951+
orgOpnd->SetIndexOpnd(nullptr);
14952+
14953+
return instrAdd;
14954+
}
14955+
14956+
///----------------------------------------------------------------------------
14957+
///
14958+
/// Instr::HoistSymOffset
14959+
///
14960+
/// Replace the given sym with an indir using the given base and offset.
14961+
/// (This is used, for instance, to hoist a sym offset that is too large to encode.)
14962+
///
14963+
///----------------------------------------------------------------------------
14964+
14965+
IR::Instr *Lowerer::HoistSymOffset(IR::Instr *instr, IR::SymOpnd *symOpnd, RegNum baseReg, uint32 offset, RegNum regNum)
14966+
{
14967+
IR::RegOpnd *baseOpnd = IR::RegOpnd::New(nullptr, baseReg, TyMachPtr, instr->m_func);
14968+
IR::IndirOpnd *indirOpnd = IR::IndirOpnd::New(baseOpnd, offset, symOpnd->GetType(), instr->m_func);
14969+
if (symOpnd == instr->GetDst())
14970+
{
14971+
instr->ReplaceDst(indirOpnd);
14972+
}
14973+
else
14974+
{
14975+
instr->ReplaceSrc(symOpnd, indirOpnd);
14976+
}
14977+
14978+
return Lowerer::HoistIndirOffset(instr, indirOpnd, regNum);
14979+
}
14980+
14981+
IR::Instr *Lowerer::HoistSymOffsetAsAdd(IR::Instr* instr, IR::SymOpnd *orgOpnd, IR::Opnd *baseOpnd, int offset, RegNum regNum)
14982+
{
14983+
IR::IndirOpnd *newIndirOpnd = IR::IndirOpnd::New(baseOpnd->AsRegOpnd(), 0, TyMachPtr, instr->m_func);
14984+
instr->Replace(orgOpnd, newIndirOpnd); // Replace SymOpnd with IndirOpnd
14985+
return Lowerer::HoistIndirOffsetAsAdd(instr, newIndirOpnd, baseOpnd, offset, regNum);
14986+
}
14987+
1488414988
IR::LabelInstr *Lowerer::InsertLabel(const bool isHelper, IR::Instr *const insertBeforeInstr)
1488514989
{
1488614990
Assert(insertBeforeInstr);

lib/Backend/Lower.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,12 @@ class Lowerer
362362
void GenerateFastBrBReturn(IR::Instr * instr);
363363

364364
public:
365+
static IR::Instr *Lowerer::HoistIndirOffset(IR::Instr* instr, IR::IndirOpnd *indirOpnd, RegNum regNum);
366+
static IR::Instr *Lowerer::HoistIndirOffsetAsAdd(IR::Instr* instr, IR::IndirOpnd *orgOpnd, IR::Opnd *baseOpnd, int offset, RegNum regNum);
367+
static IR::Instr *Lowerer::HoistIndirIndexOpndAsAdd(IR::Instr* instr, IR::IndirOpnd *orgOpnd, IR::Opnd *baseOpnd, IR::Opnd *indexOpnd, RegNum regNum);
368+
static IR::Instr *Lowerer::HoistSymOffset(IR::Instr *instr, IR::SymOpnd *symOpnd, RegNum baseReg, uint32 offset, RegNum regNum);
369+
static IR::Instr *Lowerer::HoistSymOffsetAsAdd(IR::Instr* instr, IR::SymOpnd *orgOpnd, IR::Opnd *baseOpnd, int offset, RegNum regNum);
370+
365371
static IR::LabelInstr * InsertLabel(const bool isHelper, IR::Instr *const insertBeforeInstr);
366372

367373
static IR::Instr * InsertMove(IR::Opnd *dst, IR::Opnd *src, IR::Instr *const insertBeforeInstr, bool generateWriteBarrier = true);

lib/Backend/arm/LegalizeMD.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ void LegalizeMD::LegalizeIndirOffset(IR::Instr * instr, IR::IndirOpnd * indirOpn
266266

267267
if (indirOpnd->GetIndexOpnd() != NULL && offset != 0)
268268
{
269-
IR::Instr *addInstr = instr->HoistIndirOffset(indirOpnd, fPostRegAlloc ? SCRATCH_REG : RegNOREG);
269+
IR::Instr *addInstr = Lowerer::HoistIndirOffset(instr, indirOpnd, fPostRegAlloc ? SCRATCH_REG : RegNOREG);
270270
LegalizeMD::LegalizeInstr(addInstr, fPostRegAlloc);
271271
return;
272272
}
@@ -288,7 +288,7 @@ void LegalizeMD::LegalizeIndirOffset(IR::Instr * instr, IR::IndirOpnd * indirOpn
288288
}
289289

290290
// Offset is too large, so hoist it and replace it with an index, only valid for Thumb & Thumb2
291-
IR::Instr *addInstr = instr->HoistIndirOffset(indirOpnd, fPostRegAlloc ? SCRATCH_REG : RegNOREG);
291+
IR::Instr *addInstr = Lowerer::HoistIndirOffset(instr, indirOpnd, fPostRegAlloc ? SCRATCH_REG : RegNOREG);
292292
LegalizeMD::LegalizeInstr(addInstr, fPostRegAlloc);
293293
}
294294

@@ -334,7 +334,7 @@ void LegalizeMD::LegalizeSymOffset(
334334
}
335335

336336
IR::RegOpnd *baseOpnd = IR::RegOpnd::New(NULL, baseReg, TyMachPtr, instr->m_func);
337-
IR::Instr* instrAdd = instr->HoistSymOffsetAsAdd(symOpnd, baseOpnd, offset, fPostRegAlloc ? SCRATCH_REG : RegNOREG);
337+
IR::Instr* instrAdd = Lowerer::HoistSymOffsetAsAdd(instr, symOpnd, baseOpnd, offset, fPostRegAlloc ? SCRATCH_REG : RegNOREG);
338338
LegalizeMD::LegalizeInstr(instrAdd, fPostRegAlloc);
339339
return;
340340
}
@@ -351,7 +351,7 @@ void LegalizeMD::LegalizeSymOffset(
351351
}
352352
else
353353
{
354-
newInstr = instr->HoistSymOffset(symOpnd, baseReg, offset, fPostRegAlloc ? SCRATCH_REG : RegNOREG);
354+
newInstr = Lowerer::HoistSymOffset(instr, symOpnd, baseReg, offset, fPostRegAlloc ? SCRATCH_REG : RegNOREG);
355355
LegalizeMD::LegalizeInstr(newInstr, fPostRegAlloc);
356356
}
357357
}
@@ -621,14 +621,14 @@ void LegalizeMD::LegalizeIndirOpndForVFP(IR::Instr* insertInstr, IR::IndirOpnd *
621621
indexOpnd = newIndexOpnd;
622622
}
623623

624-
insertInstr->HoistIndirIndexOpndAsAdd(indirOpnd, baseOpnd, indexOpnd, fPostRegAlloc? SCRATCH_REG : RegNOREG);
624+
Lowerer::HoistIndirIndexOpndAsAdd(insertInstr, indirOpnd, baseOpnd, indexOpnd, fPostRegAlloc? SCRATCH_REG : RegNOREG);
625625
}
626626

627627
if (IS_CONST_UINT10((offset < 0? -offset: offset)))
628628
{
629629
return;
630630
}
631-
IR::Instr* instrAdd = insertInstr->HoistIndirOffsetAsAdd(indirOpnd, indirOpnd->GetBaseOpnd(), offset, fPostRegAlloc ? SCRATCH_REG : RegNOREG);
631+
IR::Instr* instrAdd = Lowerer::HoistIndirOffsetAsAdd(insertInstr, indirOpnd, indirOpnd->GetBaseOpnd(), offset, fPostRegAlloc ? SCRATCH_REG : RegNOREG);
632632
LegalizeMD::LegalizeInstr(instrAdd, fPostRegAlloc);
633633
}
634634

lib/Backend/arm64/EncoderMD.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ void EncoderMD::CanonicalizeLea(IR::Instr * instr)
152152
indirOpnd->Free(this->m_func);
153153
}
154154
instr->m_opcode = Js::OpCode::ADD;
155+
Assert(instr->GetSrc1()->GetSize() == instr->GetSrc2()->GetSize());
155156
}
156157

157158
bool

0 commit comments

Comments
 (0)