Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/coreclr/jit/codegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3930,9 +3930,9 @@ void CodeGen::genCodeForCmpXchg(GenTreeCmpXchg* treeNode)
{
assert(treeNode->OperIs(GT_CMPXCHG));

GenTree* addr = treeNode->gtOpLocation; // arg1
GenTree* data = treeNode->gtOpValue; // arg2
GenTree* comparand = treeNode->gtOpComparand; // arg3
GenTree* addr = treeNode->Addr(); // arg1
GenTree* data = treeNode->Data(); // arg2
GenTree* comparand = treeNode->Comparand(); // arg3

regNumber targetReg = treeNode->GetRegNum();
regNumber dataReg = data->GetRegNum();
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/jit/codegenriscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2670,9 +2670,9 @@ void CodeGen::genCodeForCmpXchg(GenTreeCmpXchg* treeNode)
{
assert(treeNode->OperIs(GT_CMPXCHG));

GenTree* locOp = treeNode->gtOpLocation;
GenTree* valOp = treeNode->gtOpValue;
GenTree* comparandOp = treeNode->gtOpComparand;
GenTree* locOp = treeNode->Addr();
GenTree* valOp = treeNode->Data();
GenTree* comparandOp = treeNode->Comparand();

regNumber target = treeNode->GetRegNum();
regNumber loc = locOp->GetRegNum();
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4396,9 +4396,9 @@ void CodeGen::genCodeForCmpXchg(GenTreeCmpXchg* tree)
var_types targetType = tree->TypeGet();
regNumber targetReg = tree->GetRegNum();

GenTree* location = tree->gtOpLocation; // arg1
GenTree* value = tree->gtOpValue; // arg2
GenTree* comparand = tree->gtOpComparand; // arg3
GenTree* location = tree->Addr(); // arg1
GenTree* value = tree->Data(); // arg2
GenTree* comparand = tree->Comparand(); // arg3

assert(location->GetRegNum() != REG_NA && location->GetRegNum() != REG_RAX);
assert(value->GetRegNum() != REG_NA && value->GetRegNum() != REG_RAX);
Expand Down
9 changes: 6 additions & 3 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -2899,6 +2899,9 @@ class Compiler
var_types gtTypeForNullCheck(GenTree* tree);
void gtChangeOperToNullCheck(GenTree* tree, BasicBlock* block);

GenTree* gtNewAtomicNode(
genTreeOps oper, var_types type, GenTree* addr, GenTree* value, GenTree* comparand = nullptr);

GenTree* gtNewTempStore(unsigned tmp,
GenTree* val,
unsigned curLevel = CHECK_SPILL_NONE,
Expand Down Expand Up @@ -11263,17 +11266,17 @@ class GenTreeVisitor
{
GenTreeCmpXchg* const cmpXchg = node->AsCmpXchg();

result = WalkTree(&cmpXchg->gtOpLocation, cmpXchg);
result = WalkTree(&cmpXchg->Addr(), cmpXchg);
if (result == fgWalkResult::WALK_ABORT)
{
return result;
}
result = WalkTree(&cmpXchg->gtOpValue, cmpXchg);
result = WalkTree(&cmpXchg->Data(), cmpXchg);
if (result == fgWalkResult::WALK_ABORT)
{
return result;
}
result = WalkTree(&cmpXchg->gtOpComparand, cmpXchg);
result = WalkTree(&cmpXchg->Comparand(), cmpXchg);
if (result == fgWalkResult::WALK_ABORT)
{
return result;
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/jit/compiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4656,15 +4656,15 @@ void GenTree::VisitOperands(TVisitor visitor)
case GT_CMPXCHG:
{
GenTreeCmpXchg* const cmpXchg = this->AsCmpXchg();
if (visitor(cmpXchg->gtOpLocation) == VisitResult::Abort)
if (visitor(cmpXchg->Addr()) == VisitResult::Abort)
{
return;
}
if (visitor(cmpXchg->gtOpValue) == VisitResult::Abort)
if (visitor(cmpXchg->Data()) == VisitResult::Abort)
{
return;
}
visitor(cmpXchg->gtOpComparand);
visitor(cmpXchg->Comparand());
return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/earlyprop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ GenTree* Compiler::optEarlyPropRewriteTree(GenTree* tree, LocalNumberToNullCheck
optPropKind propKind = optPropKind::OPK_INVALID;
bool folded = false;

if (tree->OperIsIndirOrArrMetaData())
if (tree->OperIsIndirOrArrMetaData() && !tree->OperIsAtomicZeroDiffQuirk())
{
// optFoldNullCheck takes care of updating statement info if a null check is removed.
folded = optFoldNullCheck(tree, nullCheckMap);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/fgprofile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,7 @@ GenTree* BlockCountInstrumentor::CreateCounterIncrement(Compiler* comp, uint8_t*
GenTree* addressNode = comp->gtNewIconHandleNode(reinterpret_cast<size_t>(counterAddr), GTF_ICON_BBC_PTR);

// Interlocked increment
result = comp->gtNewOperNode(GT_XADD, countType, addressNode, comp->gtNewIconNode(1, countType));
result = comp->gtNewAtomicNode(GT_XADD, countType, addressNode, comp->gtNewIconNode(1, countType));
}

if (scalable)
Expand Down
98 changes: 67 additions & 31 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2994,9 +2994,9 @@ bool GenTree::Compare(GenTree* op1, GenTree* op2, bool swapOK)
return GenTreeFieldList::Equals(op1->AsFieldList(), op2->AsFieldList());

case GT_CMPXCHG:
return Compare(op1->AsCmpXchg()->gtOpLocation, op2->AsCmpXchg()->gtOpLocation) &&
Compare(op1->AsCmpXchg()->gtOpValue, op2->AsCmpXchg()->gtOpValue) &&
Compare(op1->AsCmpXchg()->gtOpComparand, op2->AsCmpXchg()->gtOpComparand);
return Compare(op1->AsCmpXchg()->Addr(), op2->AsCmpXchg()->Addr()) &&
Compare(op1->AsCmpXchg()->Data(), op2->AsCmpXchg()->Data()) &&
Compare(op1->AsCmpXchg()->Comparand(), op2->AsCmpXchg()->Comparand());

case GT_STORE_DYN_BLK:
return Compare(op1->AsStoreDynBlk()->Addr(), op2->AsStoreDynBlk()->Addr()) &&
Expand Down Expand Up @@ -3546,9 +3546,9 @@ unsigned Compiler::gtHashValue(GenTree* tree)
break;

case GT_CMPXCHG:
hash = genTreeHashAdd(hash, gtHashValue(tree->AsCmpXchg()->gtOpLocation));
hash = genTreeHashAdd(hash, gtHashValue(tree->AsCmpXchg()->gtOpValue));
hash = genTreeHashAdd(hash, gtHashValue(tree->AsCmpXchg()->gtOpComparand));
hash = genTreeHashAdd(hash, gtHashValue(tree->AsCmpXchg()->Addr()));
hash = genTreeHashAdd(hash, gtHashValue(tree->AsCmpXchg()->Data()));
hash = genTreeHashAdd(hash, gtHashValue(tree->AsCmpXchg()->Comparand()));
break;

case GT_STORE_DYN_BLK:
Expand Down Expand Up @@ -6203,27 +6203,31 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
break;

case GT_CMPXCHG:
{
GenTree* addr = tree->AsCmpXchg()->Addr();
level = gtSetEvalOrder(addr);
costSz = addr->GetCostSz();

level = gtSetEvalOrder(tree->AsCmpXchg()->gtOpLocation);
costSz = tree->AsCmpXchg()->gtOpLocation->GetCostSz();

lvl2 = gtSetEvalOrder(tree->AsCmpXchg()->gtOpValue);
GenTree* value = tree->AsCmpXchg()->Data();
lvl2 = gtSetEvalOrder(value);
if (level < lvl2)
{
level = lvl2;
}
costSz += tree->AsCmpXchg()->gtOpValue->GetCostSz();
costSz += value->GetCostSz();

lvl2 = gtSetEvalOrder(tree->AsCmpXchg()->gtOpComparand);
GenTree* comparand = tree->AsCmpXchg()->Comparand();
lvl2 = gtSetEvalOrder(comparand);
if (level < lvl2)
{
level = lvl2;
}
costSz += tree->AsCmpXchg()->gtOpComparand->GetCostSz();
costSz += comparand->GetCostSz();

costEx = MAX_COST; // Seriously, what could be more expensive than lock cmpxchg?
costSz += 5; // size of lock cmpxchg [reg+C], reg
break;
}
break;

case GT_STORE_DYN_BLK:
level = gtSetEvalOrder(tree->AsStoreDynBlk()->Addr());
Expand Down Expand Up @@ -6522,19 +6526,19 @@ bool GenTree::TryGetUse(GenTree* operand, GenTree*** pUse)
case GT_CMPXCHG:
{
GenTreeCmpXchg* const cmpXchg = this->AsCmpXchg();
if (operand == cmpXchg->gtOpLocation)
if (operand == cmpXchg->Addr())
{
*pUse = &cmpXchg->gtOpLocation;
*pUse = &cmpXchg->Addr();
return true;
}
if (operand == cmpXchg->gtOpValue)
if (operand == cmpXchg->Data())
{
*pUse = &cmpXchg->gtOpValue;
*pUse = &cmpXchg->Data();
return true;
}
if (operand == cmpXchg->gtOpComparand)
if (operand == cmpXchg->Comparand())
{
*pUse = &cmpXchg->gtOpComparand;
*pUse = &cmpXchg->Comparand();
return true;
}
return false;
Expand Down Expand Up @@ -6999,7 +7003,7 @@ ExceptionSetFlags GenTree::OperExceptions(Compiler* comp)
#endif // FEATURE_HW_INTRINSICS

default:
assert(!OperMayOverflow() && !OperIsIndirOrArrMetaData());
assert(!OperMayOverflow() && (!OperIsIndirOrArrMetaData() || OperIsAtomicZeroDiffQuirk()));
return ExceptionSetFlags::None;
}
}
Expand Down Expand Up @@ -8344,6 +8348,38 @@ GenTree* Compiler::gtNewStoreValueNode(
return store;
}

//------------------------------------------------------------------------
// gtNewAtomicNode: Create a new atomic operation node.
//
// Arguments:
// oper - The atomic oper
// type - Type to store/load
// addr - Destination ("location") address
// value - Value
// comparand - Comparand value for a CMPXCHG
//
// Return Value:
// The created node.
//
GenTree* Compiler::gtNewAtomicNode(genTreeOps oper, var_types type, GenTree* addr, GenTree* value, GenTree* comparand)
{
assert(GenTree::OperIsAtomicOp(oper) && ((oper == GT_CMPXCHG) == (comparand != nullptr)));
GenTree* node;
if (comparand != nullptr)
{
node = new (this, GT_CMPXCHG) GenTreeCmpXchg(type, addr, value, comparand);
addr->gtFlags |= GTF_DONT_CSE;
}
else
{
node = new (this, oper) GenTreeIndir(oper, type, addr, value);
}

// All atomics are opaque global stores.
node->AddAllEffectsFlags(GTF_ASG | GTF_GLOB_REF);
return node;
}

//------------------------------------------------------------------------
// FixupInitBlkValue: Fixup the init value for an initBlk operation
//
Expand Down Expand Up @@ -9333,9 +9369,9 @@ GenTree* Compiler::gtCloneExpr(
case GT_CMPXCHG:
copy = new (this, GT_CMPXCHG)
GenTreeCmpXchg(tree->TypeGet(),
gtCloneExpr(tree->AsCmpXchg()->gtOpLocation, addFlags, deepVarNum, deepVarVal),
gtCloneExpr(tree->AsCmpXchg()->gtOpValue, addFlags, deepVarNum, deepVarVal),
gtCloneExpr(tree->AsCmpXchg()->gtOpComparand, addFlags, deepVarNum, deepVarVal));
gtCloneExpr(tree->AsCmpXchg()->Addr(), addFlags, deepVarNum, deepVarVal),
gtCloneExpr(tree->AsCmpXchg()->Data(), addFlags, deepVarNum, deepVarVal),
gtCloneExpr(tree->AsCmpXchg()->Comparand(), addFlags, deepVarNum, deepVarVal));
break;

case GT_STORE_DYN_BLK:
Expand Down Expand Up @@ -9977,7 +10013,7 @@ GenTreeUseEdgeIterator::GenTreeUseEdgeIterator(GenTree* node)
return;

case GT_CMPXCHG:
m_edge = &m_node->AsCmpXchg()->gtOpLocation;
m_edge = &m_node->AsCmpXchg()->Addr();
assert(*m_edge != nullptr);
m_advance = &GenTreeUseEdgeIterator::AdvanceCmpXchg;
return;
Expand Down Expand Up @@ -10026,11 +10062,11 @@ void GenTreeUseEdgeIterator::AdvanceCmpXchg()
switch (m_state)
{
case 0:
m_edge = &m_node->AsCmpXchg()->gtOpValue;
m_edge = &m_node->AsCmpXchg()->Data();
m_state = 1;
break;
case 1:
m_edge = &m_node->AsCmpXchg()->gtOpComparand;
m_edge = &m_node->AsCmpXchg()->Comparand();
m_advance = &GenTreeUseEdgeIterator::Terminate;
break;
default:
Expand Down Expand Up @@ -12629,9 +12665,9 @@ void Compiler::gtDispTree(GenTree* tree,

if (!topOnly)
{
gtDispChild(tree->AsCmpXchg()->gtOpLocation, indentStack, IIArc, nullptr, topOnly);
gtDispChild(tree->AsCmpXchg()->gtOpValue, indentStack, IIArc, nullptr, topOnly);
gtDispChild(tree->AsCmpXchg()->gtOpComparand, indentStack, IIArcBottom, nullptr, topOnly);
gtDispChild(tree->AsCmpXchg()->Addr(), indentStack, IIArc, nullptr, topOnly);
gtDispChild(tree->AsCmpXchg()->Data(), indentStack, IIArc, nullptr, topOnly);
gtDispChild(tree->AsCmpXchg()->Comparand(), indentStack, IIArcBottom, nullptr, topOnly);
}
break;

Expand Down Expand Up @@ -17489,7 +17525,7 @@ GenTreeLclVar* GenTree::IsImplicitByrefParameterValuePostMorph(Compiler* compile
{
#if FEATURE_IMPLICIT_BYREFS && !defined(TARGET_LOONGARCH64) // TODO-LOONGARCH64-CQ: enable this.

if (!OperIsIndir())
if (!OperIsLoad())
{
return nullptr;
}
Expand Down
Loading