diff --git a/eng/pipelines/libraries/run-test-job.yml b/eng/pipelines/libraries/run-test-job.yml
index faa5ab29e3002..58bcd933f3daf 100644
--- a/eng/pipelines/libraries/run-test-job.yml
+++ b/eng/pipelines/libraries/run-test-job.yml
@@ -143,10 +143,7 @@ jobs:
- jitstress2
- jitstress2_tiered
- zapdisable
- # tailcallstress currently has hundreds of failures on Linux/arm32, so disable it.
- # Tracked by https://github.com/dotnet/runtime/issues/38892.
- - ${{ if or(eq(parameters.osGroup, 'Windows_NT'), ne(parameters.archType, 'arm')) }}:
- - tailcallstress
+ - tailcallstress
${{ if in(parameters.coreclrTestGroup, 'jitstressregs' ) }}:
scenarios:
- jitstressregs1
diff --git a/src/coreclr/src/jit/gentree.h b/src/coreclr/src/jit/gentree.h
index 7e25365730720..5c3a94395db6f 100644
--- a/src/coreclr/src/jit/gentree.h
+++ b/src/coreclr/src/jit/gentree.h
@@ -4201,6 +4201,7 @@ struct GenTreeCall final : public GenTree
#define GTF_CALL_M_ALLOC_SIDE_EFFECTS 0x00400000 // GT_CALL -- this is a call to an allocator with side effects
#define GTF_CALL_M_SUPPRESS_GC_TRANSITION 0x00800000 // GT_CALL -- suppress the GC transition (i.e. during a pinvoke) but a separate GC safe point is required.
#define GTF_CALL_M_EXP_RUNTIME_LOOKUP 0x01000000 // GT_CALL -- this call needs to be tranformed into CFG for the dynamic dictionary expansion feature.
+#define GTF_CALL_M_STRESS_TAILCALL 0x02000000 // GT_CALL -- the call is NOT "tail" prefixed but GTF_CALL_M_EXPLICIT_TAILCALL was added because of tail call stress mode
// clang-format on
@@ -4315,6 +4316,13 @@ struct GenTreeCall final : public GenTree
return (gtCallMoreFlags & GTF_CALL_M_EXPLICIT_TAILCALL) != 0;
}
+ // Returns true if this call didn't have an explicit tail. prefix in the IL
+ // but was marked as an explicit tail call because of tail call stress mode.
+ bool IsStressTailCall() const
+ {
+ return (gtCallMoreFlags & GTF_CALL_M_STRESS_TAILCALL) != 0;
+ }
+
// This method returning "true" implies that tail call flowgraph morhphing has
// performed final checks and committed to making a tail call.
bool IsTailCall() const
diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp
index 2823851cd094c..f03f639431208 100644
--- a/src/coreclr/src/jit/importer.cpp
+++ b/src/coreclr/src/jit/importer.cpp
@@ -7526,11 +7526,13 @@ enum
PREFIX_TAILCALL_EXPLICIT = 0x00000001, // call has "tail" IL prefix
PREFIX_TAILCALL_IMPLICIT =
0x00000010, // call is treated as having "tail" prefix even though there is no "tail" IL prefix
- PREFIX_TAILCALL = (PREFIX_TAILCALL_EXPLICIT | PREFIX_TAILCALL_IMPLICIT),
- PREFIX_VOLATILE = 0x00000100,
- PREFIX_UNALIGNED = 0x00001000,
- PREFIX_CONSTRAINED = 0x00010000,
- PREFIX_READONLY = 0x00100000
+ PREFIX_TAILCALL_STRESS =
+ 0x00000100, // call doesn't "tail" IL prefix but is treated as explicit because of tail call stress
+ PREFIX_TAILCALL = (PREFIX_TAILCALL_EXPLICIT | PREFIX_TAILCALL_IMPLICIT | PREFIX_TAILCALL_STRESS),
+ PREFIX_VOLATILE = 0x00001000,
+ PREFIX_UNALIGNED = 0x00010000,
+ PREFIX_CONSTRAINED = 0x00100000,
+ PREFIX_READONLY = 0x01000000
};
/********************************************************************************
@@ -8674,6 +8676,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
{
const bool isExplicitTailCall = (tailCallFlags & PREFIX_TAILCALL_EXPLICIT) != 0;
const bool isImplicitTailCall = (tailCallFlags & PREFIX_TAILCALL_IMPLICIT) != 0;
+ const bool isStressTailCall = (tailCallFlags & PREFIX_TAILCALL_STRESS) != 0;
// Exactly one of these should be true.
assert(isExplicitTailCall != isImplicitTailCall);
@@ -8740,6 +8743,12 @@ var_types Compiler::impImportCall(OPCODE opcode,
// for in-lining.
call->AsCall()->gtCallMoreFlags |= GTF_CALL_M_EXPLICIT_TAILCALL;
JITDUMP("\nGTF_CALL_M_EXPLICIT_TAILCALL set for call [%06u]\n", dspTreeID(call));
+
+ if (isStressTailCall)
+ {
+ call->AsCall()->gtCallMoreFlags |= GTF_CALL_M_STRESS_TAILCALL;
+ JITDUMP("\nGTF_CALL_M_STRESS_TAILCALL set for call [%06u]\n", dspTreeID(call));
+ }
}
else
{
@@ -14209,6 +14218,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
// Stress the tailcall.
JITDUMP(" (Tailcall stress: prefixFlags |= PREFIX_TAILCALL_EXPLICIT)");
prefixFlags |= PREFIX_TAILCALL_EXPLICIT;
+ prefixFlags |= PREFIX_TAILCALL_STRESS;
}
else
{
diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp
index ea30779946ef2..b173993d6bb55 100644
--- a/src/coreclr/src/jit/morph.cpp
+++ b/src/coreclr/src/jit/morph.cpp
@@ -7235,7 +7235,7 @@ GenTree* Compiler::fgMorphPotentialTailCall(GenTreeCall* call)
// We still must check for any struct parameters and set 'hasStructParam'
// so that we won't transform the recursive tail call into a loop.
//
- if (call->IsImplicitTailCall())
+ if (call->IsImplicitTailCall() || call->IsStressTailCall())
{
if (varDsc->lvHasLdAddrOp && !lvaIsImplicitByRefLocal(varNum))
{
@@ -8793,7 +8793,7 @@ GenTree* Compiler::fgMorphCall(GenTreeCall* call)
assert(!call->CanTailCall());
#if FEATURE_MULTIREG_RET
- if (fgGlobalMorph && call->HasMultiRegRetVal())
+ if (fgGlobalMorph && call->HasMultiRegRetVal() && varTypeIsStruct(call->TypeGet()))
{
// The tail call has been rejected so we must finish the work deferred
// by impFixupCallStructReturn for multi-reg-returning calls and transform
@@ -8810,23 +8810,14 @@ GenTree* Compiler::fgMorphCall(GenTreeCall* call)
lvaGrabTemp(false DEBUGARG("Return value temp for multi-reg return (rejected tail call)."));
lvaTable[tmpNum].lvIsMultiRegRet = true;
- GenTree* assg = nullptr;
- if (varTypeIsStruct(call->TypeGet()))
- {
- CORINFO_CLASS_HANDLE structHandle = call->gtRetClsHnd;
- assert(structHandle != NO_CLASS_HANDLE);
- const bool unsafeValueClsCheck = false;
- lvaSetStruct(tmpNum, structHandle, unsafeValueClsCheck);
- var_types structType = lvaTable[tmpNum].lvType;
- GenTree* dst = gtNewLclvNode(tmpNum, structType);
- assg = gtNewAssignNode(dst, call);
- }
- else
- {
- assg = gtNewTempAssign(tmpNum, call);
- }
-
- assg = fgMorphTree(assg);
+ CORINFO_CLASS_HANDLE structHandle = call->gtRetClsHnd;
+ assert(structHandle != NO_CLASS_HANDLE);
+ const bool unsafeValueClsCheck = false;
+ lvaSetStruct(tmpNum, structHandle, unsafeValueClsCheck);
+ var_types structType = lvaTable[tmpNum].lvType;
+ GenTree* dst = gtNewLclvNode(tmpNum, structType);
+ GenTree* assg = gtNewAssignNode(dst, call);
+ assg = fgMorphTree(assg);
// Create the assignment statement and insert it before the current statement.
Statement* assgStmt = gtNewStmt(assg, compCurStmt->GetILOffsetX());
diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets
index e6c8104ed5571..a2f45d4d14017 100644
--- a/src/coreclr/tests/issues.targets
+++ b/src/coreclr/tests/issues.targets
@@ -67,9 +67,6 @@
https://github.com/dotnet/runtime/issues/5933
-
- https://github.com/dotnet/runtime/issues/8017
-
https://github.com/dotnet/runtime/issues/11213
diff --git a/src/libraries/System.Collections.Concurrent/tests/ProducerConsumerCollectionTests.cs b/src/libraries/System.Collections.Concurrent/tests/ProducerConsumerCollectionTests.cs
index c6393faa9359b..ef699764e4214 100644
--- a/src/libraries/System.Collections.Concurrent/tests/ProducerConsumerCollectionTests.cs
+++ b/src/libraries/System.Collections.Concurrent/tests/ProducerConsumerCollectionTests.cs
@@ -98,7 +98,6 @@ public void Ctor_InitializeFromCollection_ContainsExpectedItems(int numItems)
}
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))]
- [SkipOnCoreClr("https://github.com/dotnet/runtime/issues/39398", RuntimeTestModes.TailcallStress)]
public void Add_TakeFromAnotherThread_ExpectedItemsTaken()
{
IProducerConsumerCollection c = CreateProducerConsumerCollection();
diff --git a/src/libraries/System.Drawing.Common/tests/FontTests.cs b/src/libraries/System.Drawing.Common/tests/FontTests.cs
index 067ff89a7be6e..f731cdb9ddada 100644
--- a/src/libraries/System.Drawing.Common/tests/FontTests.cs
+++ b/src/libraries/System.Drawing.Common/tests/FontTests.cs
@@ -784,7 +784,6 @@ public void SizeInPoints_Get_ReturnsExpected(GraphicsUnit unit)
[InlineData(FontStyle.Strikeout | FontStyle.Bold | FontStyle.Italic, 255, true, "@", 700)]
[InlineData(FontStyle.Regular, 0, false, "", 400)]
[InlineData(FontStyle.Regular, 10, false, "", 400)]
- [SkipOnCoreClr("https://github.com/dotnet/runtime/issues/38889", RuntimeTestModes.TailcallStress)]
public void ToLogFont_Invoke_ReturnsExpected(FontStyle fontStyle, byte gdiCharSet, bool gdiVerticalFont, string expectedNamePrefix, int expectedWeight)
{
using (FontFamily family = FontFamily.GenericMonospace)
@@ -818,7 +817,6 @@ public void ToLogFont_Invoke_ReturnsExpected(FontStyle fontStyle, byte gdiCharSe
[InlineData(TextRenderingHint.SingleBitPerPixel)]
[InlineData(TextRenderingHint.SingleBitPerPixelGridFit)]
[InlineData(TextRenderingHint.ClearTypeGridFit)]
- [SkipOnCoreClr("https://github.com/dotnet/runtime/issues/38889", RuntimeTestModes.TailcallStress)]
public void ToLogFont_InvokeGraphics_ReturnsExpected(TextRenderingHint textRenderingHint)
{
using (FontFamily family = FontFamily.GenericMonospace)
diff --git a/src/libraries/System.Net.HttpListener/tests/AssemblyInfo.cs b/src/libraries/System.Net.HttpListener/tests/AssemblyInfo.cs
deleted file mode 100644
index 5bfc6fc542f55..0000000000000
--- a/src/libraries/System.Net.HttpListener/tests/AssemblyInfo.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using Xunit;
-
-[assembly: SkipOnCoreClr("https://github.com/dotnet/runtime/issues/39309", RuntimeTestModes.TailcallStress)]
diff --git a/src/libraries/System.Net.HttpListener/tests/System.Net.HttpListener.Tests.csproj b/src/libraries/System.Net.HttpListener/tests/System.Net.HttpListener.Tests.csproj
index 9da20596f8144..3d8ebf1e50be3 100644
--- a/src/libraries/System.Net.HttpListener/tests/System.Net.HttpListener.Tests.csproj
+++ b/src/libraries/System.Net.HttpListener/tests/System.Net.HttpListener.Tests.csproj
@@ -5,7 +5,6 @@
$(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent)-OSX
-
diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/AiaTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/AiaTests.cs
index d05290b14d417..bfdb42328a730 100644
--- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/AiaTests.cs
+++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/AiaTests.cs
@@ -42,7 +42,6 @@ public static void EmptyAiaResponseIsIgnored()
}
[Fact]
- [SkipOnCoreClr("https://github.com/dotnet/runtime/issues/38887", RuntimeTestModes.TailcallStress)]
public static void DisableAiaOptionWorks()
{
CertificateAuthority.BuildPrivatePki(
diff --git a/src/tests/JIT/opt/OSR/tailrecursetry.csproj b/src/tests/JIT/opt/OSR/tailrecursetry.csproj
index 9620f75474a93..c79a0af1d255a 100644
--- a/src/tests/JIT/opt/OSR/tailrecursetry.csproj
+++ b/src/tests/JIT/opt/OSR/tailrecursetry.csproj
@@ -3,6 +3,10 @@
Exe
True
+
+ true
diff --git a/src/tests/profiler/unittest/getappdomainstaticaddress.csproj b/src/tests/profiler/unittest/getappdomainstaticaddress.csproj
index c5769302e8590..09f11fb4e5279 100644
--- a/src/tests/profiler/unittest/getappdomainstaticaddress.csproj
+++ b/src/tests/profiler/unittest/getappdomainstaticaddress.csproj
@@ -6,10 +6,6 @@
true
0
true
-
- true
true