Skip to content

Commit ed57bae

Browse files
authored
[NativeAOT] Fix floating pointer register unwinding on Arm32 (#118944)
* NativeAOT specific register window implementation has to match the one in libunwind. * Re-enable test * Make the test more robust
1 parent 80f7aca commit ed57bae

File tree

4 files changed

+41
-26
lines changed

4 files changed

+41
-26
lines changed

src/coreclr/nativeaot/Runtime/unix/UnwindHelpers.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -354,8 +354,8 @@ struct Registers_REGDISPLAY : REGDISPLAY
354354
uint32_t getRegister(int num) const;
355355
void setRegister(int num, uint32_t value, uint32_t location);
356356

357-
double getFloatRegister(int num) const;
358-
void setFloatRegister(int num, double value);
357+
unw_fpreg_t getFloatRegister(int num) const;
358+
void setFloatRegister(int num, unw_fpreg_t value);
359359

360360
libunwind::v128 getVectorRegister(int num) const { abort(); }
361361
void setVectorRegister(int num, libunwind::v128 value) { abort(); }
@@ -516,13 +516,13 @@ void Registers_REGDISPLAY::setRegister(int num, uint32_t value, uint32_t locatio
516516
}
517517
}
518518

519-
double Registers_REGDISPLAY::getFloatRegister(int num) const
519+
unw_fpreg_t Registers_REGDISPLAY::getFloatRegister(int num) const
520520
{
521521
assert(validFloatRegister(num));
522-
return unwindhelpers_bitcast<double>(D[num - UNW_ARM_D8]);
522+
return unwindhelpers_bitcast<unw_fpreg_t>(D[num - UNW_ARM_D8]);
523523
}
524524

525-
void Registers_REGDISPLAY::setFloatRegister(int num, double value)
525+
void Registers_REGDISPLAY::setFloatRegister(int num, unw_fpreg_t value)
526526
{
527527
assert(validFloatRegister(num));
528528
D[num - UNW_ARM_D8] = unwindhelpers_bitcast<uint64_t>(value);

src/tests/Exceptions/UnwindFpBleedTest/UnwindFpBleedTest.cs

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
public class Program
66
{
7+
// Make sure that the JIT doesn't optimize away the loops.
8+
static volatile int iterations = 10;
9+
710
[Fact]
811
public static int TestEntryPoint()
912
{
@@ -18,7 +21,7 @@ public static int TestEntryPoint()
1821
double a8 = 9.0;
1922
double a9 = 10.0;
2023

21-
for (int i = 1; i < 10; i++)
24+
for (int i = 1; i < iterations; i++)
2225
{
2326
a0 *= 1.0;
2427
a1 *= 2.0;
@@ -32,19 +35,31 @@ public static int TestEntryPoint()
3235
a9 *= 10.0;
3336
}
3437

38+
a0 += 0.1;
39+
a1 += 0.2;
40+
a2 += 0.3;
41+
a3 += 0.4;
42+
a4 += 0.5;
43+
a5 += 0.6;
44+
a6 += 0.7;
45+
a7 += 0.8;
46+
a8 += 0.9;
47+
a9 += 1.1;
48+
49+
3550
EHMethod();
3651

3752
bool isExpectedValue =
38-
a0 == 1.0
39-
&& a1 == Math.Pow(2, 10)
40-
&& a2 == Math.Pow(3, 10)
41-
&& a3 == Math.Pow(4, 10)
42-
&& a4 == Math.Pow(5, 10)
43-
&& a5 == Math.Pow(6, 10)
44-
&& a6 == Math.Pow(7, 10)
45-
&& a7 == Math.Pow(8, 10)
46-
&& a8 == Math.Pow(9, 10)
47-
&& a9 == Math.Pow(10, 10);
53+
a0 == 1.1
54+
&& a1 == Math.Pow(2, 10) + 0.2
55+
&& a2 == Math.Pow(3, 10) + 0.3
56+
&& a3 == Math.Pow(4, 10) + 0.4
57+
&& a4 == Math.Pow(5, 10) + 0.5
58+
&& a5 == Math.Pow(6, 10) + 0.6
59+
&& a6 == Math.Pow(7, 10) + 0.7
60+
&& a7 == Math.Pow(8, 10) + 0.8
61+
&& a8 == Math.Pow(9, 10) + 0.9
62+
&& a9 == Math.Pow(10, 10) + 1.1;
4863

4964
return isExpectedValue ? 100 : 1;
5065
}
@@ -71,14 +86,21 @@ static void FloatManipulationMethod()
7186
double a24 = 1, a25 = 2, a26 = 3, a27 = 4, a28 = 5, a29 = 6, a30 = 7, a31 = 8;
7287

7388
// Some busy math to prevent easy optimizations and folding.
74-
for (int i = 0; i < 5; i++)
89+
for (int i = 0; i < iterations; i++)
7590
{
7691
a0 -= 1; a1 -= 2; a2 -= 3; a3 -= 4; a4 -= 5; a5 -= 6; a6 -= 7; a7 -= 8;
7792
a8 -= 9; a9 -= 10; a10 -= 11; a11 -= 12; a12 -= 13; a13 -= 14; a14 -= 15; a15 -= 16;
7893
a16 -= 17; a17 -= 18; a18 -= 19; a19 -= 20; a20 -= 21; a21 -= 22; a22 -= 23; a23 -= 24;
7994
a24 -= 25; a25 -= 26; a26 -= 27; a27 -= 28; a28 -= 29; a29 -= 30; a30 -= 31; a31 -= 32;
80-
}
8195

82-
throw new Exception();
96+
if (i == 7)
97+
{
98+
throw new Exception(
99+
(a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 +
100+
a8 + a9 + a10 + a11 + a12 + a13 + a14 + a15 +
101+
a16 + a17 + a19 + a20 + a21 + a22 + a23 +
102+
a24 + a25 + a26 + a27 + a28 + a29 + a30 + a31).ToString());
103+
}
104+
}
83105
}
84106
}

src/tests/Exceptions/UnwindFpBleedTest/UnwindFpBleedTest.csproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
<Project Sdk="Microsoft.NET.Sdk">
2-
<PropertyGroup>
3-
<!-- Needed for mechanical merging of all remaining tests, this particular project may not actually need process isolation -->
4-
<RequiresProcessIsolation>true</RequiresProcessIsolation>
5-
</PropertyGroup>
62
<ItemGroup>
73
<Compile Include="UnwindFpBleedTest.cs" />
84
</ItemGroup>

src/tests/issues.targets

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,6 @@
232232
<ExcludeList Include="$(XunitTestBinBase)/JIT/Regression/JitBlue/DevDiv_590771/DevDiv_590771/*">
233233
<Issue>needs triage</Issue>
234234
</ExcludeList>
235-
<ExcludeList Include="$(XunitTestBinBase)/Exceptions/UnwindFpBleedTest/UnwindFpBleedTest/*">
236-
<Issue>Windows's unwinder in ARM64v8 queue doesn't contain FP unwind fix</Issue>
237-
</ExcludeList>
238235
</ItemGroup>
239236

240237
<!-- Windows all architecture excludes -->

0 commit comments

Comments
 (0)