Skip to content

Commit d021b56

Browse files
Move the "do not zero-extend setcc" optimization to lower (#53778)
* Strongly type StoreInd lowering * Improve clarity of code through the use of helpers * Move the "do not zero-extend setcc" to lowering It is XARCH-specific and moving it eliminates questionable code that is trying to compensate for CSE changing the store. * Delete now unnecessary copying of the relop type
1 parent c786e4f commit d021b56

File tree

5 files changed

+33
-44
lines changed

5 files changed

+33
-44
lines changed

src/coreclr/jit/lower.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ GenTree* Lowering::LowerNode(GenTree* node)
116116
break;
117117

118118
case GT_STOREIND:
119-
LowerStoreIndirCommon(node->AsIndir());
119+
LowerStoreIndirCommon(node->AsStoreInd());
120120
break;
121121

122122
case GT_ADD:
@@ -3558,7 +3558,7 @@ void Lowering::LowerStoreSingleRegCallStruct(GenTreeBlk* store)
35583558
{
35593559
store->ChangeType(regType);
35603560
store->SetOper(GT_STOREIND);
3561-
LowerStoreIndirCommon(store);
3561+
LowerStoreIndirCommon(store->AsStoreInd());
35623562
return;
35633563
}
35643564
else
@@ -4100,7 +4100,7 @@ void Lowering::InsertPInvokeMethodProlog()
41004100
// The init routine sets InlinedCallFrame's m_pNext, so we just set the thead's top-of-stack
41014101
GenTree* frameUpd = CreateFrameLinkUpdate(PushFrame);
41024102
firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, frameUpd));
4103-
ContainCheckStoreIndir(frameUpd->AsIndir());
4103+
ContainCheckStoreIndir(frameUpd->AsStoreInd());
41044104
DISPTREERANGE(firstBlockRange, frameUpd);
41054105
}
41064106
#endif // TARGET_64BIT
@@ -4163,7 +4163,7 @@ void Lowering::InsertPInvokeMethodEpilog(BasicBlock* returnBB DEBUGARG(GenTree*
41634163
{
41644164
GenTree* frameUpd = CreateFrameLinkUpdate(PopFrame);
41654165
returnBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, frameUpd));
4166-
ContainCheckStoreIndir(frameUpd->AsIndir());
4166+
ContainCheckStoreIndir(frameUpd->AsStoreInd());
41674167
}
41684168
}
41694169

@@ -4325,7 +4325,7 @@ void Lowering::InsertPInvokeCallProlog(GenTreeCall* call)
43254325
// Stubs do this once per stub, not once per call.
43264326
GenTree* frameUpd = CreateFrameLinkUpdate(PushFrame);
43274327
BlockRange().InsertBefore(insertBefore, LIR::SeqTree(comp, frameUpd));
4328-
ContainCheckStoreIndir(frameUpd->AsIndir());
4328+
ContainCheckStoreIndir(frameUpd->AsStoreInd());
43294329
}
43304330
#endif // TARGET_64BIT
43314331

@@ -4335,7 +4335,7 @@ void Lowering::InsertPInvokeCallProlog(GenTreeCall* call)
43354335
// [tcb + offsetOfGcState] = 0
43364336
GenTree* storeGCState = SetGCState(0);
43374337
BlockRange().InsertBefore(insertBefore, LIR::SeqTree(comp, storeGCState));
4338-
ContainCheckStoreIndir(storeGCState->AsIndir());
4338+
ContainCheckStoreIndir(storeGCState->AsStoreInd());
43394339

43404340
// Indicate that codegen has switched this thread to preemptive GC.
43414341
// This tree node doesn't generate any code, but impacts LSRA and gc reporting.
@@ -4381,7 +4381,7 @@ void Lowering::InsertPInvokeCallEpilog(GenTreeCall* call)
43814381

43824382
GenTree* tree = SetGCState(1);
43834383
BlockRange().InsertBefore(insertionPoint, LIR::SeqTree(comp, tree));
4384-
ContainCheckStoreIndir(tree->AsIndir());
4384+
ContainCheckStoreIndir(tree->AsStoreInd());
43854385

43864386
tree = CreateReturnTrapSeq();
43874387
BlockRange().InsertBefore(insertionPoint, LIR::SeqTree(comp, tree));
@@ -4396,7 +4396,7 @@ void Lowering::InsertPInvokeCallEpilog(GenTreeCall* call)
43964396
{
43974397
tree = CreateFrameLinkUpdate(PopFrame);
43984398
BlockRange().InsertBefore(insertionPoint, LIR::SeqTree(comp, tree));
4399-
ContainCheckStoreIndir(tree->AsIndir());
4399+
ContainCheckStoreIndir(tree->AsStoreInd());
44004400
}
44014401
#else
44024402
const CORINFO_EE_INFO::InlinedCallFrameInfo& callFrameInfo = comp->eeGetEEInfo()->inlinedCallFrameInfo;
@@ -6421,7 +6421,7 @@ void Lowering::ContainCheckNode(GenTree* node)
64216421
ContainCheckReturnTrap(node->AsOp());
64226422
break;
64236423
case GT_STOREIND:
6424-
ContainCheckStoreIndir(node->AsIndir());
6424+
ContainCheckStoreIndir(node->AsStoreInd());
64256425
break;
64266426
case GT_IND:
64276427
ContainCheckIndir(node->AsIndir());
@@ -6604,9 +6604,8 @@ void Lowering::ContainCheckBitCast(GenTree* node)
66046604
// Arguments:
66056605
// ind - the store indirection node we are lowering.
66066606
//
6607-
void Lowering::LowerStoreIndirCommon(GenTreeIndir* ind)
6607+
void Lowering::LowerStoreIndirCommon(GenTreeStoreInd* ind)
66086608
{
6609-
assert(ind->OperIs(GT_STOREIND));
66106609
assert(ind->TypeGet() != TYP_STRUCT);
66116610
TryCreateAddrMode(ind->Addr(), true);
66126611
if (!comp->codeGen->gcInfo.gcIsWriteBarrierStoreIndNode(ind))
@@ -6806,6 +6805,6 @@ bool Lowering::TryTransformStoreObjAsStoreInd(GenTreeBlk* blkNode)
68066805
{
68076806
assert(src->TypeIs(regType) || src->IsCnsIntOrI() || src->IsCall());
68086807
}
6809-
LowerStoreIndirCommon(blkNode);
6808+
LowerStoreIndirCommon(blkNode->AsStoreInd());
68106809
return true;
68116810
}

src/coreclr/jit/lower.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class Lowering final : public Phase
8989
void ContainCheckBitCast(GenTree* node);
9090
void ContainCheckCallOperands(GenTreeCall* call);
9191
void ContainCheckIndir(GenTreeIndir* indirNode);
92-
void ContainCheckStoreIndir(GenTreeIndir* indirNode);
92+
void ContainCheckStoreIndir(GenTreeStoreInd* indirNode);
9393
void ContainCheckMul(GenTreeOp* node);
9494
void ContainCheckShiftRotate(GenTreeOp* node);
9595
void ContainCheckStoreLoc(GenTreeLclVarCommon* storeLoc) const;
@@ -292,9 +292,9 @@ class Lowering final : public Phase
292292
#endif // defined(TARGET_XARCH)
293293

294294
// Per tree node member functions
295-
void LowerStoreIndirCommon(GenTreeIndir* ind);
295+
void LowerStoreIndirCommon(GenTreeStoreInd* ind);
296296
void LowerIndir(GenTreeIndir* ind);
297-
void LowerStoreIndir(GenTreeIndir* node);
297+
void LowerStoreIndir(GenTreeStoreInd* node);
298298
GenTree* LowerAdd(GenTreeOp* node);
299299
bool LowerUnsignedDivOrMod(GenTreeOp* divMod);
300300
GenTree* LowerConstIntDivOrMod(GenTree* node);

src/coreclr/jit/lowerarmarch.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ void Lowering::LowerStoreLoc(GenTreeLclVarCommon* storeLoc)
218218
// Return Value:
219219
// None.
220220
//
221-
void Lowering::LowerStoreIndir(GenTreeIndir* node)
221+
void Lowering::LowerStoreIndir(GenTreeStoreInd* node)
222222
{
223223
ContainCheckStoreIndir(node);
224224
}
@@ -1376,11 +1376,11 @@ void Lowering::ContainCheckCallOperands(GenTreeCall* call)
13761376
// Arguments:
13771377
// node - pointer to the node
13781378
//
1379-
void Lowering::ContainCheckStoreIndir(GenTreeIndir* node)
1379+
void Lowering::ContainCheckStoreIndir(GenTreeStoreInd* node)
13801380
{
13811381
#ifdef TARGET_ARM64
1382-
GenTree* src = node->AsOp()->gtOp2;
1383-
if (!varTypeIsFloating(src->TypeGet()) && src->IsIntegralConst(0))
1382+
GenTree* src = node->Data();
1383+
if (src->IsIntegralConst(0))
13841384
{
13851385
// an integer zero for 'src' can be contained.
13861386
MakeSrcContained(node, src);

src/coreclr/jit/lowerxarch.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,11 @@ void Lowering::LowerStoreLoc(GenTreeLclVarCommon* storeLoc)
110110
// Return Value:
111111
// None.
112112
//
113-
void Lowering::LowerStoreIndir(GenTreeIndir* node)
113+
void Lowering::LowerStoreIndir(GenTreeStoreInd* node)
114114
{
115115
// Mark all GT_STOREIND nodes to indicate that it is not known
116116
// whether it represents a RMW memory op.
117-
node->AsStoreInd()->SetRMWStatusDefault();
117+
node->SetRMWStatusDefault();
118118

119119
if (!varTypeIsFloating(node))
120120
{
@@ -130,10 +130,10 @@ void Lowering::LowerStoreIndir(GenTreeIndir* node)
130130
return;
131131
}
132132
}
133-
else if (node->AsStoreInd()->Data()->OperIs(GT_CNS_DBL))
133+
else if (node->Data()->IsCnsFltOrDbl())
134134
{
135135
// Optimize *x = DCON to *x = ICON which is slightly faster on xarch
136-
GenTree* data = node->AsStoreInd()->Data();
136+
GenTree* data = node->Data();
137137
double dblCns = data->AsDblCon()->gtDconVal;
138138
ssize_t intCns = 0;
139139
var_types type = TYP_UNKNOWN;
@@ -162,6 +162,13 @@ void Lowering::LowerStoreIndir(GenTreeIndir* node)
162162
node->ChangeType(type);
163163
}
164164
}
165+
166+
// Optimization: do not unnecessarily zero-extend the result of setcc.
167+
if (varTypeIsByte(node) && (node->Data()->OperIsCompare() || node->Data()->OperIs(GT_SETCC)))
168+
{
169+
node->Data()->ChangeType(TYP_BYTE);
170+
}
171+
165172
ContainCheckStoreIndir(node);
166173
}
167174

@@ -4588,17 +4595,18 @@ void Lowering::ContainCheckIndir(GenTreeIndir* node)
45884595
// Arguments:
45894596
// node - pointer to the node
45904597
//
4591-
void Lowering::ContainCheckStoreIndir(GenTreeIndir* node)
4598+
void Lowering::ContainCheckStoreIndir(GenTreeStoreInd* node)
45924599
{
45934600
// If the source is a containable immediate, make it contained, unless it is
45944601
// an int-size or larger store of zero to memory, because we can generate smaller code
45954602
// by zeroing a register and then storing it.
4596-
GenTree* src = node->AsOp()->gtOp2;
4603+
GenTree* src = node->Data();
45974604
if (IsContainableImmed(node, src) &&
4598-
(!src->IsIntegralConst(0) || varTypeIsSmall(node) || node->gtGetOp1()->OperGet() == GT_CLS_VAR_ADDR))
4605+
(!src->IsIntegralConst(0) || varTypeIsSmall(node) || node->Addr()->OperIs(GT_CLS_VAR_ADDR)))
45994606
{
46004607
MakeSrcContained(node, src);
46014608
}
4609+
46024610
ContainCheckIndir(node);
46034611
}
46044612

src/coreclr/jit/morph.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12087,23 +12087,8 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac)
1208712087
tree->AsOp()->gtOp2 = op2 = op2->AsCast()->CastOp();
1208812088
}
1208912089
}
12090-
else if (op2->OperIsCompare() && varTypeIsByte(effectiveOp1->TypeGet()))
12091-
{
12092-
/* We don't need to zero extend the setcc instruction */
12093-
op2->gtType = TYP_BYTE;
12094-
}
1209512090
}
12096-
// If we introduced a CSE we may need to undo the optimization above
12097-
// (i.e. " op2->gtType = TYP_BYTE;" which depends upon op1 being a GT_IND of a byte type)
12098-
// When we introduce the CSE we remove the GT_IND and subsitute a GT_LCL_VAR in it place.
12099-
else if (op2->OperIsCompare() && (op2->gtType == TYP_BYTE) && (op1->gtOper == GT_LCL_VAR))
12100-
{
12101-
unsigned varNum = op1->AsLclVarCommon()->GetLclNum();
12102-
LclVarDsc* varDsc = &lvaTable[varNum];
1210312091

12104-
/* We again need to zero extend the setcc instruction */
12105-
op2->gtType = varDsc->TypeGet();
12106-
}
1210712092
fgAssignSetVarDef(tree);
1210812093

1210912094
/* We can't CSE the LHS of an assignment */
@@ -12345,9 +12330,6 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac)
1234512330
gtReverseCond(op1);
1234612331
}
1234712332

12348-
/* Propagate gtType of tree into op1 in case it is TYP_BYTE for setcc optimization */
12349-
op1->gtType = tree->gtType;
12350-
1235112333
noway_assert((op1->gtFlags & GTF_RELOP_JMP_USED) == 0);
1235212334
op1->gtFlags |= tree->gtFlags & (GTF_RELOP_JMP_USED | GTF_RELOP_QMARK | GTF_DONT_CSE);
1235312335

0 commit comments

Comments
 (0)