From 916f454c273f4d8cf12af03d7019bc612fccff26 Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Tue, 12 May 2026 11:12:45 +0300 Subject: [PATCH 1/3] Add missing fences on riscv64 for runtime-async --- src/coreclr/jit/async.cpp | 6 ++++- src/coreclr/jit/codegenloongarch64.cpp | 10 ++++---- src/coreclr/jit/codegenriscv64.cpp | 10 ++++---- .../Compiler/DependencyAnalysis/Relocation.cs | 24 ++++++++++++++----- .../superpmi/superpmi-shared/spmiutil.cpp | 22 +++++++++++++---- src/coreclr/utilcode/util.cpp | 22 +++++++++++++---- 6 files changed, 69 insertions(+), 25 deletions(-) diff --git a/src/coreclr/jit/async.cpp b/src/coreclr/jit/async.cpp index cd4bb35514149e..d08ee0f1be27a9 100644 --- a/src/coreclr/jit/async.cpp +++ b/src/coreclr/jit/async.cpp @@ -2497,6 +2497,9 @@ void AsyncTransformation::CreateResumption(BasicBlock* call LIR::AsRange(resumeBB).InsertAtEnd(LIR::SeqTree(m_compiler, ilOffsetNode)); + GenTree* barrier = m_compiler->gtNewMemoryBarrier(BARRIER_LOAD_ONLY); + LIR::AsRange(resumeBB).InsertAtEnd(barrier); + if (layout.Size > 0) { RestoreFromDataOnResumption(layout, subLayout, resumeBB); @@ -2964,8 +2967,9 @@ void AsyncTransformation::CreateSharedReturnBB() } GenTree* continuation = m_compiler->gtNewLclvNode(GetNewContinuationVar(), TYP_REF); + GenTree* barrier = m_compiler->gtNewMemoryBarrier(BARRIER_STORE_ONLY); GenTree* ret = m_compiler->gtNewOperNode(GT_RETURN_SUSPEND, TYP_VOID, continuation); - LIR::AsRange(m_sharedReturnBB).InsertAtEnd(continuation, ret); + LIR::AsRange(m_sharedReturnBB).InsertAtEnd(barrier, continuation, ret); JITDUMP("Created shared return BB " FMT_BB "\n", m_sharedReturnBB->bbNum); diff --git a/src/coreclr/jit/codegenloongarch64.cpp b/src/coreclr/jit/codegenloongarch64.cpp index 26a80d31204e52..ab5d319d2997d4 100644 --- a/src/coreclr/jit/codegenloongarch64.cpp +++ b/src/coreclr/jit/codegenloongarch64.cpp @@ -5367,13 +5367,15 @@ void CodeGen::genCodeForIndir(GenTreeIndir* tree) genConsumeAddress(tree->Addr()); - if ((tree->gtFlags & GTF_IND_VOLATILE) != 0) - { - instGen_MemoryBarrier(BARRIER_FULL); - } + bool emitBarrier = (tree->gtFlags & GTF_IND_VOLATILE) != 0; GetEmitter()->emitInsLoadStoreOp(ins, emitActualTypeSize(type), targetReg, tree); + if (emitBarrier) + { + instGen_MemoryBarrier(BARRIER_LOAD_ONLY); + } + genProduceReg(tree); } diff --git a/src/coreclr/jit/codegenriscv64.cpp b/src/coreclr/jit/codegenriscv64.cpp index 540d92a906023c..ab553dbf784992 100644 --- a/src/coreclr/jit/codegenriscv64.cpp +++ b/src/coreclr/jit/codegenriscv64.cpp @@ -5169,13 +5169,15 @@ void CodeGen::genCodeForIndir(GenTreeIndir* tree) genConsumeAddress(tree->Addr()); - if ((tree->gtFlags & GTF_IND_VOLATILE) != 0) - { - instGen_MemoryBarrier(BARRIER_FULL); - } + bool emitBarrier = (tree->gtFlags & GTF_IND_VOLATILE) != 0; GetEmitter()->emitInsLoadStoreOp(ins, emitActualTypeSize(type), targetReg, tree); + if (emitBarrier) + { + instGen_MemoryBarrier(BARRIER_LOAD_ONLY); + } + genProduceReg(tree); } diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs index 3ed1f41e378e9d..4ca57a637fdf51 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs @@ -579,12 +579,24 @@ private static unsafe void PutRiscV64AuipcCombo(uint* pCode, long offset, bool i int hi20 = (int)(offset - lo12); Debug.Assert((long)lo12 + (long)hi20 == offset); - // Debug.Assert(GetRiscV64AuipcCombo(pCode, isStype) == 0); - pCode[0] |= (uint)hi20; - int bottomBitsPos = isStype ? 7 : 20; - pCode[1] |= (uint)((lo12 >> 5) << 25); // top 7 bits are in the same spot - pCode[1] |= (uint)((lo12 & 0x1F) << bottomBitsPos); - // Debug.Assert(GetRiscV64AuipcCombo(pCode, isStype) == offset); + // Replace existing immediate bits because RISC-V relocation placeholders may already carry addends. + pCode[0] &= 0x00000FFF; + pCode[0] |= (uint)hi20 & 0xFFFFF000; + + uint lo12Bits = (uint)lo12 & 0xFFF; + if (isStype) + { + pCode[1] &= 0x01FFF07F; + pCode[1] |= (lo12Bits & 0xFE0) << 20; + pCode[1] |= (lo12Bits & 0x01F) << 7; + } + else + { + pCode[1] &= 0x000FFFFF; + pCode[1] |= lo12Bits << 20; + } + + Debug.Assert(GetRiscV64AuipcCombo(pCode, isStype) == offset); } public Relocation(RelocType relocType, int offset, ISymbolNode target) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp b/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp index 5c8b3e559215d9..a614d51a74de2e 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp @@ -518,11 +518,23 @@ void PutRiscV64AuipcCombo(UINT32 * pCode, INT64 offset, bool isStype) INT32 hi20 = INT32(offset - lo12); _ASSERTE(INT64(lo12) + INT64(hi20) == offset); - _ASSERTE(GetRiscV64AuipcCombo(pCode, isStype) == 0); - pCode[0] |= hi20; - int bottomBitsPos = isStype ? 7 : 20; - pCode[1] |= (lo12 >> 5) << 25; // top 7 bits are in the same spot - pCode[1] |= (lo12 & 0x1F) << bottomBitsPos; + // Replace existing immediate bits because RISC-V relocation placeholders may already carry addends. + pCode[0] &= 0x00000FFF; + pCode[0] |= hi20 & 0xFFFFF000; + + UINT32 lo12Bits = UINT32(lo12) & 0xFFF; + if (isStype) + { + pCode[1] &= 0x01FFF07F; + pCode[1] |= (lo12Bits & 0xFE0) << 20; + pCode[1] |= (lo12Bits & 0x01F) << 7; + } + else + { + pCode[1] &= 0x000FFFFF; + pCode[1] |= lo12Bits << 20; + } + _ASSERTE(GetRiscV64AuipcCombo(pCode, isStype) == offset); } diff --git a/src/coreclr/utilcode/util.cpp b/src/coreclr/utilcode/util.cpp index 4cb88c41fe08f2..fac2837f65952f 100644 --- a/src/coreclr/utilcode/util.cpp +++ b/src/coreclr/utilcode/util.cpp @@ -2261,11 +2261,23 @@ void PutRiscV64AuipcCombo(UINT32 * pCode, INT64 offset, bool isStype) INT32 hi20 = INT32(offset - lo12); _ASSERTE(INT64(lo12) + INT64(hi20) == offset); - _ASSERTE(GetRiscV64AuipcCombo(pCode, isStype) == 0); - pCode[0] |= hi20; - int bottomBitsPos = isStype ? 7 : 20; - pCode[1] |= (lo12 >> 5) << 25; // top 7 bits are in the same spot - pCode[1] |= (lo12 & 0x1F) << bottomBitsPos; + // Replace existing immediate bits because RISC-V relocation placeholders may already carry addends. + pCode[0] &= 0x00000FFF; + pCode[0] |= hi20 & 0xFFFFF000; + + UINT32 lo12Bits = UINT32(lo12) & 0xFFF; + if (isStype) + { + pCode[1] &= 0x01FFF07F; + pCode[1] |= (lo12Bits & 0xFE0) << 20; + pCode[1] |= (lo12Bits & 0x01F) << 7; + } + else + { + pCode[1] &= 0x000FFFFF; + pCode[1] |= lo12Bits << 20; + } + _ASSERTE(GetRiscV64AuipcCombo(pCode, isStype) == offset); } From 84eaaeaef97afa5b8f4de06156d455b9281367db Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Tue, 12 May 2026 18:53:52 +0300 Subject: [PATCH 2/3] Address CR feedback --- .../Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs | 1 + src/coreclr/jit/async.cpp | 6 +----- src/coreclr/jit/codegenloongarch64.cpp | 10 ++++------ src/coreclr/jit/codegenriscv64.cpp | 10 ++++------ 4 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs index da990797eb246a..2fa05a6b3d085e 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs @@ -438,6 +438,7 @@ internal unsafe bool HandleSuspended(ref RuntimeAsyncAwaitState state) Debug.Assert((headContinuation.Flags & continueFlags) == 0); + Interlocked.MemoryBarrier(); SetContinuationState(headContinuation); try diff --git a/src/coreclr/jit/async.cpp b/src/coreclr/jit/async.cpp index d08ee0f1be27a9..cd4bb35514149e 100644 --- a/src/coreclr/jit/async.cpp +++ b/src/coreclr/jit/async.cpp @@ -2497,9 +2497,6 @@ void AsyncTransformation::CreateResumption(BasicBlock* call LIR::AsRange(resumeBB).InsertAtEnd(LIR::SeqTree(m_compiler, ilOffsetNode)); - GenTree* barrier = m_compiler->gtNewMemoryBarrier(BARRIER_LOAD_ONLY); - LIR::AsRange(resumeBB).InsertAtEnd(barrier); - if (layout.Size > 0) { RestoreFromDataOnResumption(layout, subLayout, resumeBB); @@ -2967,9 +2964,8 @@ void AsyncTransformation::CreateSharedReturnBB() } GenTree* continuation = m_compiler->gtNewLclvNode(GetNewContinuationVar(), TYP_REF); - GenTree* barrier = m_compiler->gtNewMemoryBarrier(BARRIER_STORE_ONLY); GenTree* ret = m_compiler->gtNewOperNode(GT_RETURN_SUSPEND, TYP_VOID, continuation); - LIR::AsRange(m_sharedReturnBB).InsertAtEnd(barrier, continuation, ret); + LIR::AsRange(m_sharedReturnBB).InsertAtEnd(continuation, ret); JITDUMP("Created shared return BB " FMT_BB "\n", m_sharedReturnBB->bbNum); diff --git a/src/coreclr/jit/codegenloongarch64.cpp b/src/coreclr/jit/codegenloongarch64.cpp index ab5d319d2997d4..26a80d31204e52 100644 --- a/src/coreclr/jit/codegenloongarch64.cpp +++ b/src/coreclr/jit/codegenloongarch64.cpp @@ -5367,15 +5367,13 @@ void CodeGen::genCodeForIndir(GenTreeIndir* tree) genConsumeAddress(tree->Addr()); - bool emitBarrier = (tree->gtFlags & GTF_IND_VOLATILE) != 0; - - GetEmitter()->emitInsLoadStoreOp(ins, emitActualTypeSize(type), targetReg, tree); - - if (emitBarrier) + if ((tree->gtFlags & GTF_IND_VOLATILE) != 0) { - instGen_MemoryBarrier(BARRIER_LOAD_ONLY); + instGen_MemoryBarrier(BARRIER_FULL); } + GetEmitter()->emitInsLoadStoreOp(ins, emitActualTypeSize(type), targetReg, tree); + genProduceReg(tree); } diff --git a/src/coreclr/jit/codegenriscv64.cpp b/src/coreclr/jit/codegenriscv64.cpp index ab553dbf784992..540d92a906023c 100644 --- a/src/coreclr/jit/codegenriscv64.cpp +++ b/src/coreclr/jit/codegenriscv64.cpp @@ -5169,15 +5169,13 @@ void CodeGen::genCodeForIndir(GenTreeIndir* tree) genConsumeAddress(tree->Addr()); - bool emitBarrier = (tree->gtFlags & GTF_IND_VOLATILE) != 0; - - GetEmitter()->emitInsLoadStoreOp(ins, emitActualTypeSize(type), targetReg, tree); - - if (emitBarrier) + if ((tree->gtFlags & GTF_IND_VOLATILE) != 0) { - instGen_MemoryBarrier(BARRIER_LOAD_ONLY); + instGen_MemoryBarrier(BARRIER_FULL); } + GetEmitter()->emitInsLoadStoreOp(ins, emitActualTypeSize(type), targetReg, tree); + genProduceReg(tree); } From 1de239f0a13baf9f91a1571aec46514f69069627 Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Wed, 13 May 2026 01:59:41 +0300 Subject: [PATCH 3/3] Address more feedback and fix tests with -c Debug --- .../Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs | 1 - src/coreclr/jit/codegenriscv64.cpp | 7 ++++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs index 2fa05a6b3d085e..da990797eb246a 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs @@ -438,7 +438,6 @@ internal unsafe bool HandleSuspended(ref RuntimeAsyncAwaitState state) Debug.Assert((headContinuation.Flags & continueFlags) == 0); - Interlocked.MemoryBarrier(); SetContinuationState(headContinuation); try diff --git a/src/coreclr/jit/codegenriscv64.cpp b/src/coreclr/jit/codegenriscv64.cpp index 540d92a906023c..f1f48942f3f418 100644 --- a/src/coreclr/jit/codegenriscv64.cpp +++ b/src/coreclr/jit/codegenriscv64.cpp @@ -940,13 +940,14 @@ void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size, emitter* emit = GetEmitter(); assert(genIsValidIntReg(reg)); - if (EA_IS_RELOC(size)) + emitAttr emitSize = EA_REMOVE_FLG(size, EA_GCREF_FLG | EA_BYREF_FLG); + if (EA_IS_RELOC(emitSize)) { - emit->emitIns_R_AI(INS_addi, size, reg, reg, imm); + emit->emitIns_R_AI(INS_addi, emitSize, reg, reg, imm); } else { - emit->emitLoadImmediate(size, reg, imm); + emit->emitLoadImmediate(emitSize, reg, imm); } regSet.verifyRegUsed(reg);