diff --git a/src/coreclr/jit/codegenwasm.cpp b/src/coreclr/jit/codegenwasm.cpp index 40d370eac6ca09..ba7418403d9ae7 100644 --- a/src/coreclr/jit/codegenwasm.cpp +++ b/src/coreclr/jit/codegenwasm.cpp @@ -613,6 +613,10 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) genIntrinsic(treeNode->AsIntrinsic()); break; + case GT_PINVOKE_PROLOG: + // TODO-WASM-CQ re-establish the global stack pointer here? + break; + default: #ifdef DEBUG NYIRAW(GenTree::OpName(treeNode->OperGet())); diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp index ae64f2e754dffc..650238099a70f7 100644 --- a/src/coreclr/jit/fgbasic.cpp +++ b/src/coreclr/jit/fgbasic.cpp @@ -2305,12 +2305,12 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed else { lvaTable[varNum].lvHasLdAddrOp = 1; - if (!info.compIsStatic && (varNum == 0)) + if (!info.compIsStatic && (varNum == info.compThisArg)) { // Addr taken on "this" pointer is significant, // go ahead to mark it as permanently addr-exposed here. // This may be conservative, but probably not very. - lvaSetVarAddrExposed(0 DEBUGARG(AddressExposedReason::TOO_CONSERVATIVE)); + lvaSetVarAddrExposed(info.compThisArg DEBUGARG(AddressExposedReason::TOO_CONSERVATIVE)); } } } // isInlining diff --git a/src/coreclr/jit/fgwasm.cpp b/src/coreclr/jit/fgwasm.cpp index 9d6afde1aa44bb..5a5d2e82638d23 100644 --- a/src/coreclr/jit/fgwasm.cpp +++ b/src/coreclr/jit/fgwasm.cpp @@ -1418,35 +1418,39 @@ PhaseStatus Compiler::fgWasmControlFlow() const unsigned trueNum = block->GetTrueTarget()->bbPreorderNum; const unsigned falseNum = block->GetFalseTarget()->bbPreorderNum; - // We don't expect degenerate BBJ_COND - // - assert(trueNum != falseNum); + if (trueNum == falseNum) + { + // If branch is degenerate update to BBJ_ALWAYS + fgRemoveConditionalJump(block); + } + else + { + // If the true target is the next block, reverse the branch + // + const bool reverseCondition = trueNum == (cursor + 1); - // If the true target is the next block, reverse the branch - // - const bool reverseCondition = trueNum == (cursor + 1); + if (reverseCondition) + { + JITDUMP("Reversing condition in " FMT_BB " to allow fall through to " FMT_BB "\n", block->bbNum, + block->GetTrueTarget()->bbNum); - if (reverseCondition) - { - JITDUMP("Reversing condition in " FMT_BB " to allow fall through to " FMT_BB "\n", block->bbNum, - block->GetTrueTarget()->bbNum); + GenTree* const test = block->GetLastLIRNode(); + assert(test->OperIs(GT_JTRUE)); + { + GenTree* const cond = gtReverseCond(test->AsOp()->gtOp1); + // Ensure `gtReverseCond` did not create a new node. + assert(cond == test->AsOp()->gtOp1); + test->AsOp()->gtOp1 = cond; + } - GenTree* const test = block->GetLastLIRNode(); - assert(test->OperIs(GT_JTRUE)); + // Rewire the flow + // + std::swap(block->TrueEdgeRef(), block->FalseEdgeRef()); + } + else { - GenTree* const cond = gtReverseCond(test->AsOp()->gtOp1); - // Ensure `gtReverseCond` did not create a new node. - assert(cond == test->AsOp()->gtOp1); - test->AsOp()->gtOp1 = cond; + JITDUMP("NOT Reversing condition in " FMT_BB "\n", block->bbNum); } - - // Rewire the flow - // - std::swap(block->TrueEdgeRef(), block->FalseEdgeRef()); - } - else - { - JITDUMP("NOT Reversing condition in " FMT_BB "\n", block->bbNum); } } } diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index cb84da4829a87c..a7eb56c4add4ea 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -13340,6 +13340,10 @@ const char* Compiler::gtGetWellKnownArgNameForArgMsg(WellKnownArg arg) return "exec ctx"; case WellKnownArg::AsyncSynchronizationContext: return "sync ctx"; + case WellKnownArg::WasmShadowStackPointer: + return "wasm sp"; + case WellKnownArg::WasmPortableEntryPoint: + return "wasm pep"; default: return nullptr; } diff --git a/src/coreclr/jit/regallocwasm.cpp b/src/coreclr/jit/regallocwasm.cpp index 6612cafe2a9bfc..e03db3a6910585 100644 --- a/src/coreclr/jit/regallocwasm.cpp +++ b/src/coreclr/jit/regallocwasm.cpp @@ -402,15 +402,16 @@ void WasmRegAlloc::RewriteLocalStackStore(GenTreeLclVarCommon* lclNode) // into the store's address mode. We can utilize a contained LEA, but that will require some liveness work. var_types storeType = lclNode->TypeGet(); + bool isStruct = storeType == TYP_STRUCT; uint16_t offset = lclNode->GetLclOffs(); - ClassLayout* layout = lclNode->GetLayout(m_compiler); + ClassLayout* layout = isStruct ? lclNode->GetLayout(m_compiler) : nullptr; lclNode->SetOper(GT_LCL_ADDR); lclNode->ChangeType(TYP_I_IMPL); lclNode->AsLclFld()->SetLclOffs(offset); GenTree* store; GenTreeFlags indFlags = GTF_IND_NONFAULTING | GTF_IND_TGT_NOT_HEAP; - if (storeType == TYP_STRUCT) + if (isStruct) { store = m_compiler->gtNewStoreBlkNode(layout, lclNode, value, indFlags); } @@ -600,7 +601,7 @@ void WasmRegAlloc::ResolveReferences() auto allocPhysReg = [&](regNumber virtReg, LclVarDsc* varDsc) { regNumber physReg; - if ((varDsc != nullptr) && varDsc->lvIsRegArg) + if ((varDsc != nullptr) && varDsc->lvIsRegArg && !varDsc->lvIsStructField) { unsigned lclNum = m_compiler->lvaGetLclNum(varDsc); const ABIPassingInformation& abiInfo = m_compiler->lvaGetParameterABIInfo(lclNum); diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 61a731709dcf4d..dd0b0a3695813a 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -13689,8 +13689,6 @@ void Compiler::fgValueNumberHelperCallFunc(GenTreeCall* call, VNFunc vnf, ValueN { // Ignore the Wasm shadow stack pointer argument. // - // The Wasm shadow stack pointer is not counted in VNFuncArity - // so nArgs does not need adjusting. curArg = curArg->GetNext(); } #endif // defined(TARGET_WASM) @@ -13786,8 +13784,17 @@ void Compiler::fgValueNumberHelperCallFunc(GenTreeCall* call, VNFunc vnf, ValueN // Add the accumulated exceptions. call->gtVNPair = vnStore->VNPWithExc(call->gtVNPair, vnpExc); } - assert(curArg == nullptr || generateUniqueVN); // All arguments should be processed or we generate unique VN and do - // not care. + +#if defined(TARGET_WASM) + if (!generateUniqueVN && (curArg != nullptr)) + { + // We should have processed all arguments except for the PE arg, which we can ignore + assert(curArg->GetWellKnownArg() == WellKnownArg::WasmPortableEntryPoint); + } +#else + // All arguments should be processed or we generate unique VN and do not care. + assert(curArg == nullptr || generateUniqueVN); +#endif } //--------------------------------------------------------------------------------