Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arm64 codegen bug. #56522

Closed
sandreenko opened this issue Jul 29, 2021 · 12 comments · Fixed by #56919
Closed

Arm64 codegen bug. #56522

sandreenko opened this issue Jul 29, 2021 · 12 comments · Fixed by #56919

Comments

@sandreenko
Copy link
Contributor

Such tests produces different results with COMPlus_JitDoValueNumber=0 and COMPlus_JitDoValueNumber=1:

The issue is in TestConvertFromFloatToU8.

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
using System.Reflection;
using System.Reflection.Emit;

namespace CheckGenericSbyte
{
    class Program
    {

        static int failedCount = 0;

        static readonly bool ExpectException = true;
        static readonly bool DontExpectException = false;

        static readonly bool UnspecifiedBehaviour = true;

        [MethodImpl(MethodImplOptions.NoInlining)]
        static void GenerateTest<F, T>(F from, OpCode fromOpcode, OpCode convOpcode, bool exceptionExpected, T expectedTo, bool undefined = false) where F : struct where T : struct, IEquatable<T>
        {
            bool checkResult = !exceptionExpected && !undefined;
            Debug.Assert(!exceptionExpected || !checkResult);
            Debug.Assert(checkResult || expectedTo.Equals(default(T)));

            Type[] args = new Type[] { }; // No args.
            Type returnType = typeof(T);
            Console.WriteLine("Run test from " + typeof(F).FullName + ", value " + from.ToString() + " To " + typeof(T).FullName + "with Op " + convOpcode.Name + " exception expected: " + exceptionExpected);
            string name = "DynamicConvertFrom" + typeof(F).FullName + "To" + typeof(T).FullName + from.ToString() + "Op" + convOpcode.Name;
            DynamicMethod dm = new DynamicMethod(name, returnType, args);

            ILGenerator generator = dm.GetILGenerator();

            if (typeof(F) == typeof(int)) generator.Emit(fromOpcode, (int)(object)from);
            else if (typeof(F) == typeof(long)) generator.Emit(fromOpcode, (long)(object)from);
            else if (typeof(F) == typeof(nint)) generator.Emit(fromOpcode, (nint)(object)from);
            else if (typeof(F) == typeof(float)) generator.Emit(fromOpcode, (float)(object)from);
            else if (typeof(F) == typeof(double)) generator.Emit(fromOpcode, (double)(object)from);
            else
            {
                throw new NotSupportedException();
            }

            generator.Emit(convOpcode);
            generator.Emit(OpCodes.Ret);

            try
            {
                T res = (T)dm.Invoke(null, BindingFlags.Default, null, new object[] { }, null);
                if (exceptionExpected)
                {
                    failedCount++;
                    Console.WriteLine("No exception in " + name);
                }
                if (checkResult && !expectedTo.Equals(res))
                {
                    failedCount++;
                    Console.WriteLine("Wrong result in " + name);
                }
            }
            catch
            {
                if (!exceptionExpected)
                {
                    failedCount++;
                    Console.WriteLine("Not expected exception in " + name);
                }
            }
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        static void TestConvertFromFloatToU8()
        {
            OpCode sourceOp = OpCodes.Ldc_R4;

            OpCode convNoOvf = OpCodes.Conv_U8;
            GenerateTest<float, ulong>(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour);

            OpCode convOvf = OpCodes.Conv_Ovf_U8;
            GenerateTest<float, ulong>(long.MinValue, sourceOp, convOvf, ExpectException, 0);

            OpCode convOvfUn = OpCodes.Conv_Ovf_U8_Un;
            GenerateTest<float, ulong>(int.MinValue, sourceOp, convOvfUn, ExpectException, 0);
            GenerateTest<float, ulong>(long.MinValue, sourceOp, convOvfUn, ExpectException, 0);

            TestSimple(long.MinValue, (float)long.MinValue);
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        public static void TestSimple(float f, object f1)
        {
            Console.WriteLine("Test Simple value is " + f + ", f1 is " + f1.ToString());
            Debug.Assert(f < -1E-9);
        }

        static int Main(string[] args)
        {
            TestConvertFromFloatToU8();
            return 100;
        }
    }
}

It looks like we do wrong CSE in TestConvertFromFloatToU8 and we pass 0 instead of long.MinValue in some cases:

seandree@seandreemac TestConvertFromIntegral % export COMPlus_JitDoValueNumber=1
seandree@seandreemac TestConvertFromIntegral % ./TestConvertFromIntegral.sh
BEGIN EXECUTION
/Users/seandree/git/runtime/artifacts/tests/coreclr/OSX.arm64.Checked/Tests/Core_Root/corerun TestConvertFromIntegral.dll ''
Run test from System.Single, value -9.223372E+18 To System.UInt64with Op conv.u8 exception expected: False
Run test from System.Single, value -9.223372E+18 To System.UInt64with Op conv.ovf.u8 exception expected: True
Run test from System.Single, value -2.1474836E+09 To System.UInt64with Op conv.ovf.u8.un exception expected: True
Run test from System.Single, value 0 To System.UInt64with Op conv.ovf.u8.un exception expected: True
No exception in DynamicConvertFromSystem.SingleToSystem.UInt640Opconv.ovf.u8.un <- wrong
Test Simple value is 0, f1 is 0 <- wrong

seandree@seandreemac TestConvertFromIntegral % export COMPlus_JitDoValueNumber=0
seandree@seandreemac TestConvertFromIntegral % ./TestConvertFromIntegral.sh
BEGIN EXECUTION
/Users/seandree/git/runtime/artifacts/tests/coreclr/OSX.arm64.Checked/Tests/Core_Root/corerun TestConvertFromIntegral.dll ''
Run test from System.Single, value -9.223372E+18 To System.UInt64with Op conv.u8 exception expected: False
Run test from System.Single, value -9.223372E+18 To System.UInt64with Op conv.ovf.u8 exception expected: True
Run test from System.Single, value -2.1474836E+09 To System.UInt64with Op conv.ovf.u8.un exception expected: True
Run test from System.Single, value -9.223372E+18 To System.UInt64with Op conv.ovf.u8.un exception expected: True
Test Simple value is -9.223372E+18, f1 is -9.223372E+18

found during work on #56450.

It is not a minimum repro but if I replace GenerateTest body with something trivial it goes away, so I am not sure what happens there.

@sandreenko sandreenko added bug arch-arm64 area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI labels Jul 29, 2021
@sandreenko sandreenko added this to the 6.0.0 milestone Jul 29, 2021
@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged New issue has not been triaged by the area owner label Jul 29, 2021
@sandreenko sandreenko removed the untriaged New issue has not been triaged by the area owner label Jul 29, 2021
@sandreenko
Copy link
Contributor Author

@briansull could you please investigate this Arm64 VN bug? cc @dotnet/jit-contrib

@briansull
Copy link
Contributor

I will investigate

@briansull
Copy link
Contributor

briansull commented Jul 29, 2021

This doesn't appear to me to be a ValueNumbering bug.
We do make a CSE for all the references to long.MinValue and put this value into a callee saved register s8. (aka as d8)
I appears that the third call to GenerateTest corrupts this variable and changes it to 0.0

@briansull
Copy link
Contributor

briansull commented Jul 29, 2021

; Assembly listing for method CheckGenericSbyte.Program:TestConvertFromFloatToU8()
; Emitting BLENDED_CODE for generic ARM64 CPU - Windows
; optimized code
; fp based frame
; partially interruptible
; No PGO data
; invoked as altjit
; Final local variable assignments
;
;* V00 loc0         [V00    ] (  0,  0   )  struct ( 8) zero-ref   
;* V01 loc1         [V01    ] (  0,  0   )  struct ( 8) zero-ref   
;* V02 loc2         [V02    ] (  0,  0   )  struct ( 8) zero-ref   
;* V03 loc3         [V03    ] (  0,  0   )  struct ( 8) zero-ref   
;# V04 OutArgs      [V04    ] (  1,  1   )  lclBlk ( 0) [sp+00H]   "OutgoingArgSpace"
;  V05 tmp1         [V05,T03] (  3,  6   )     ref  ->   x0         class-hnd exact single-def "Single-def Box Helper"
;  V06 tmp2         [V06,T08] (  5,  5   )     int  ->  x19         single-def V00.m_value(offs=0x00) P-INDEP "field V00.m_value (fldOffset=0x0)"
;  V07 tmp3         [V07,T09] (  5,  5   )     int  ->  x20         single-def V00.m_flags(offs=0x04) P-INDEP "field V00.m_flags (fldOffset=0x4)"
;  V08 tmp4         [V08,T18] (  2,  2   )     int  ->   x1         single-def V01.m_value(offs=0x00) P-INDEP "field V01.m_value (fldOffset=0x0)"
;  V09 tmp5         [V09,T19] (  2,  2   )     int  ->   x0         single-def V01.m_flags(offs=0x04) P-INDEP "field V01.m_flags (fldOffset=0x4)"
;  V10 tmp6         [V10,T20] (  2,  2   )     int  ->   x0         single-def V02.m_value(offs=0x00) P-INDEP "field V02.m_value (fldOffset=0x0)"
;  V11 tmp7         [V11,T21] (  2,  2   )     int  ->   x2         single-def V02.m_flags(offs=0x04) P-INDEP "field V02.m_flags (fldOffset=0x4)"
;  V12 tmp8         [V12,T16] (  3,  3   )     int  ->  x21         single-def V03.m_value(offs=0x00) P-INDEP "field V03.m_value (fldOffset=0x0)"
;  V13 tmp9         [V13,T17] (  3,  3   )     int  ->  x23         single-def V03.m_flags(offs=0x04) P-INDEP "field V03.m_flags (fldOffset=0x4)"
;  V14 tmp10        [V14,T04] (  3,  6   )   byref  ->   x0         single-def "BlockOp address local"
;  V15 tmp11        [V15,T05] (  3,  6   )   byref  ->   x0         single-def "BlockOp address local"
;  V16 tmp12        [V16,T00] ( 12, 24   )  struct ( 8) [fp+18H]   do-not-enreg[SF] "by-value struct argument"
;  V17 tmp13        [V17,T01] ( 12, 24   )  struct ( 8) [fp+10H]   do-not-enreg[SF] "by-value struct argument"
;  V18 tmp14        [V18,T11] (  2,  4   )     int  ->   x2         "argument with side effect"
;  V19 tmp15        [V19,T12] (  2,  4   )     int  ->   x4         "argument with side effect"
;  V20 tmp16        [V20,T06] (  3,  6   )   byref  ->   x2         single-def "BlockOp address local"
;  V21 tmp17        [V21,T13] (  2,  4   )     int  ->   x2         "argument with side effect"
;  V22 tmp18        [V22,T07] (  3,  6   )   byref  ->   x2         single-def "BlockOp address local"
;  V23 tmp19        [V23,T14] (  2,  4   )     int  ->   x2         "argument with side effect"
;  V24 tmp20        [V24,T15] (  2,  4   )     int  ->   x2         "argument with side effect"
;* V25 cse0         [V25,T22] (  0,  0   )    long  ->  zero-ref    "CSE - aggressive"
;* V26 cse1         [V26,T23] (  0,  0   )    long  ->  zero-ref    "CSE - aggressive"
;  V27 cse2         [V27,T02] (  7,  7   )    long  ->  x22         "CSE - aggressive"
;  V28 cse3         [V28,T24] (  6,  6   )   float  ->   d8         "CSE - aggressive"
;  V29 cse4         [V29,T10] (  4,  4   )    long  ->  x21         "CSE - moderate"
;
; Lcl frame size = 16

G_M14852_IG01:              ;; offset=0000H
        A9BB7BFD          stp     fp, lr, [sp,#-80]!
        FD0013E8          str     d8, [sp,#32]
        A902D3F3          stp     x19, x20, [sp,#40]
        A903DBF5          stp     x21, x22, [sp,#56]
        F90027F7          str     x23, [sp,#72]
        910003FD          mov     fp, sp
						;; bbWeight=1    PerfScore 5.50
G_M14852_IG02:              ;; offset=0018H
        D2894100          movz    x0, #0x4a08
        F2A9F760          movk    x0, #0x4fbb LSL #16
        F2CFFF20          movk    x0, #0x7ff9 LSL #32
        5280E001          mov     w1, #0x700
        94000000          bl      CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE
        D283E400          movz    x0, #0x1f20
        F2A30000          movk    x0, #0x1800 LSL #16
        F2C03840          movk    x0, #450 LSL #32
        F9400000          ldr     x0, [x0]
        91002000          add     x0, x0, #8
        B9400013          ldr     w19, [x0]
        B9400414          ldr     w20, [x0,#4]
        D2842F15          movz    x21, #0x2178
        F2A30015          movk    x21, #0x1800 LSL #16
        F2C03855          movk    x21, #450 LSL #32
        F94002A0          ldr     x0, [x21]
        91002000          add     x0, x0, #8
        B9400001          ldr     w1, [x0]
        B9400400          ldr     w0, [x0,#4]
        B9001BB3          str     w19, [fp,#24]
        B9001FB4          str     w20, [fp,#28]
        B90013A1          str     w1, [fp,#16]
        B90017A0          str     w0, [fp,#20]
        D28FBB16          movz    x22, #0x7dd8
        F2A9FC36          movk    x22, #0x4fe1 LSL #16
        F2CFFF36          movk    x22, #0x7ff9 LSL #32
        AA1603E0          mov     x0, x22
        52800021          mov     w1, #1
        94000000          bl      CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE
        3940E6C2          ldrb    w2, [x22,#57]
        3940EAC4          ldrb    w4, [x22,#58]
        F9400BA1          ldr     x1, [fp,#16]
        F9400FA0          ldr     x0, [fp,#24]
        1C000748          ldr     s8, [@RWD00]                          ;; Setup cse3 with long.MinValue
        1E204100          fmov    s0, s8                                ;; Pass the cse containing long.MinValue as arg0
        D2800003          mov     x3, #0
        94000000          bl      CheckGenericSbyte.Program:GenerateTest(float,System.Reflection.Emit.OpCode,System.Reflection.Emit.OpCode,bool,long,bool)
        F940F6A2          ldr     x2, [x21,#488]
        91002042          add     x2, x2, #8
        B9400040          ldr     w0, [x2]
        B9400442          ldr     w2, [x2,#4]
        B9001BB3          str     w19, [fp,#24]
        B9001FB4          str     w20, [fp,#28]
        B90013A0          str     w0, [fp,#16]
        B90017A2          str     w2, [fp,#20]
        3940E2C2          ldrb    w2, [x22,#56]
        F9400FA0          ldr     x0, [fp,#24]
        F9400BA1          ldr     x1, [fp,#16]
        1E204100          fmov    s0, s8                               ;; Pass the cse containing long.MinValue as arg0
        D2800003          mov     x3, #0
        52800004          mov     w4, #0
        94000000          bl      CheckGenericSbyte.Program:GenerateTest(float,System.Reflection.Emit.OpCode,System.Reflection.Emit.OpCode,bool,long,bool)
        F94066A2          ldr     x2, [x21,#200]
        91002042          add     x2, x2, #8
        B9400055          ldr     w21, [x2]
        B9400457          ldr     w23, [x2,#4]
        B9001BB3          str     w19, [fp,#24]
        B9001FB4          str     w20, [fp,#28]
        B90013B5          str     w21, [fp,#16]
        B90017B7          str     w23, [fp,#20]
        3940E2C2          ldrb    w2, [x22,#56]
        F9400FA0          ldr     x0, [fp,#24]
        F9400BA1          ldr     x1, [fp,#16]
        1C0003A0          ldr     s0, [@RWD04]
        D2800003          mov     x3, #0
        52800004          mov     w4, #0
        94000000          bl      CheckGenericSbyte.Program:GenerateTest(float,System.Reflection.Emit.OpCode,System.Reflection.Emit.OpCode,bool,long,bool)
        B9001BB3          str     w19, [fp,#24]
        B9001FB4          str     w20, [fp,#28]
        B90013B5          str     w21, [fp,#16]
        B90017B7          str     w23, [fp,#20]
        3940E2C2          ldrb    w2, [x22,#56]
        F9400FA0          ldr     x0, [fp,#24]
        F9400BA1          ldr     x1, [fp,#16]
                                                                       ;; Somehow the value in s8 was changed to 0.0
        1E204100          fmov    s0, s8                               ;; Pass the cse containing long.MinValue as arg0
        D2800003          mov     x3, #0
        52800004          mov     w4, #0
        94000000          bl      CheckGenericSbyte.Program:GenerateTest(float,System.Reflection.Emit.OpCode,System.Reflection.Emit.OpCode,bool,long,bool)
        D29B1600          movz    x0, #0xd8b0
        F2A9F960          movk    x0, #0x4fcb LSL #16
        F2CFFF20          movk    x0, #0x7ff9 LSL #32
        94000000          bl      CORINFO_HELP_NEWSFAST
        BD000808          str     s8, [x0,#8]                          ;; Two more uses of the cse
        1E204100          fmov    s0, s8
        94000000          bl      CheckGenericSbyte.Program:TestSimple(float,System.Object)
						;; bbWeight=1    PerfScore 112.50
G_M14852_IG03:              ;; offset=016CH
        F94027F7          ldr     x23, [sp,#72]
        A943DBF5          ldp     x21, x22, [sp,#56]
        A942D3F3          ldp     x19, x20, [sp,#40]
        FD4013E8          ldr     d8, [sp,#32]
        A8C57BFD          ldp     fp, lr, [sp],#80
        D65F03C0          ret     lr
						;; bbWeight=1    PerfScore 8.00
RWD00  	dd	DF000000h		; -9.22337e+18
RWD04  	dd	CF000000h		; -2.14748e+09


; Total bytes of code 388, prolog size 24, PerfScore 164.80, instruction count 97, allocated bytes for code 388 (MethodHash=df87c5fb) for method CheckGenericSbyte.Program:TestConvertFromFloatToU8()
; ============================================================

@sandreenko
Copy link
Contributor Author

I appears that the third call to GenerateTest corrupts this variable and changes it to 0.0

Do you mean that Program:GenerateTest does not respect callee saved contract for d8? That would be a serious issue.

@briansull
Copy link
Contributor

I looked at Program:GenerateTest and it does use d8 (and it saves and restores d8)

I believe that there is data corruption taking place when Program:GenerateTest is executing,
which corrupts the value saved in the stack used for restoring d8 in Program:GenerateTest.

@briansull
Copy link
Contributor

I have included the Arm64 codegen for Windows AltJit, I don't see anything that is wrong with it.
Running on real hardware you could set a data breakpoint after the store of d8

FD0027E8 str d8, [sp,#72]

And see if someone is modifying [sp,#72]

; Assembly listing for method CheckGenericSbyte.Program:GenerateTest(float,System.Reflection.Emit.OpCode,System.Reflection.Emit.OpCode,bool,long,bool)
; Emitting BLENDED_CODE for generic ARM64 CPU - Windows
; optimized code
; fp based frame
; fully interruptible
; No PGO data
; 0 inlinees with PGO data; 13 single block inlinees; 0 inlinees without PGO data
; invoked as altjit
; Final local variable assignments
;
;  V00 arg0         [V00,T36] (  5,  5   )   float  ->   d8         ld-addr-op single-def
;  V01 arg1         [V01,T07] (  3,  3   )  struct ( 8) [fp+28H]   do-not-enreg[SF] single-def
;  V02 arg2         [V02    ] (  5,  5   )  struct ( 8) [fp+20H]   do-not-enreg[XSFB] addr-exposed ld-addr-op single-def
;  V03 arg3         [V03    ] (  6,  5   )    bool  ->  [fp+1CH]   do-not-enreg[XB] addr-exposed ld-addr-op single-def
;  V04 arg4         [V04,T08] (  3,  3   )    long  ->  x19         ld-addr-op single-def
;  V05 arg5         [V05,T09] (  3,  3   )    bool  ->   x4         single-def
;  V06 loc0         [V06,T32] (  2,  2   )    bool  ->  x20         single-def
;  V07 loc1         [V07,T31] (  2,  2   )     ref  ->  x21         class-hnd exact single-def
;  V08 loc2         [V08,T10] (  4,  4   )     ref  ->  x22         class-hnd single-def
;  V09 loc3         [V09,T26] (  5,  3   )     ref  ->  [fp+10H]   class-hnd EH-live single-def
;  V10 loc4         [V10,T27] (  3,  3   )     ref  ->  x24         class-hnd exact single-def
;  V11 loc5         [V11,T05] (  6,  6   )     ref  ->  x21         class-hnd single-def
;  V12 loc6         [V12,T33] (  2,  2   )    long  ->  x21         single-def
;  V13 OutArgs      [V13    ] (  1,  1   )  lclBlk (16) [sp+00H]   "OutgoingArgSpace"
;  V14 tmp1         [V14,T29] (  3,  3   )     int  ->   x0        
;  V15 tmp2         [V15,T00] ( 12, 24   )     ref  ->  x24         class-hnd exact single-def "dup spill"
;  V16 tmp3         [V16,T12] (  2,  4   )     ref  ->  x15         class-hnd single-def "Strict ordering of exceptions for Array store"
;  V17 tmp4         [V17,T13] (  2,  4   )     ref  ->  x15         class-hnd single-def "Strict ordering of exceptions for Array store"
;  V18 tmp5         [V18,T14] (  2,  4   )     ref  ->  x15         class-hnd single-def "Strict ordering of exceptions for Array store"
;  V19 tmp6         [V19,T15] (  2,  4   )     ref  ->  x15         class-hnd single-def "Strict ordering of exceptions for Array store"
;  V20 tmp7         [V20,T16] (  2,  4   )     ref  ->  x15         class-hnd single-def "Strict ordering of exceptions for Array store"
;  V21 tmp8         [V21,T01] (  9, 18   )     ref  ->  x24         class-hnd exact single-def "dup spill"
;  V22 tmp9         [V22,T17] (  2,  4   )     ref  ->  x15         class-hnd single-def "Strict ordering of exceptions for Array store"
;  V23 tmp10        [V23,T18] (  2,  4   )     ref  ->  x15         class-hnd single-def "Strict ordering of exceptions for Array store"
;  V24 tmp11        [V24,T19] (  2,  4   )     ref  ->  x15         class-hnd single-def "Strict ordering of exceptions for Array store"
;  V25 tmp12        [V25,T20] (  2,  4   )     ref  ->  x15         class-hnd single-def "Strict ordering of exceptions for Array store"
;  V26 tmp13        [V26,T06] (  3,  6   )     ref  ->  x24         class-hnd exact single-def "NewObj constructor temp"
;  V27 tmp14        [V27,T04] (  4,  7   )     ref  ->  x21         single-def "inline UNBOX clone1"
;* V28 tmp15        [V28    ] (  0,  0   )     ref  ->  zero-ref    class-hnd single-def "impSpillSpecialSideEff"
;  V29 tmp16        [V29,T21] (  2,  4   )     ref  ->   x0         class-hnd single-def "Inlining Arg"
;* V30 tmp17        [V30    ] (  0,  0   )   float  ->  zero-ref    "impAppendStmt"
;* V31 tmp18        [V31,T34] (  0,  0   )     ref  ->  zero-ref    class-hnd single-def "Inlining Arg"
;  V32 tmp19        [V32,T22] (  2,  4   )     ref  ->   x0         class-hnd single-def "Inlining Arg"
;* V33 tmp20        [V33,T35] (  0,  0   )     ref  ->  zero-ref    class-hnd single-def "Inlining Arg"
;* V34 tmp21        [V34    ] (  0,  0   )   float  ->  zero-ref    "impAppendStmt"
;  V35 tmp22        [V35,T23] (  2,  4   )     ref  ->   x1         single-def "argument with side effect"
;  V36 tmp23        [V36,T24] (  2,  4   )     ref  ->   x1         single-def "argument with side effect"
;  V37 tmp24        [V37,T25] (  2,  4   )     ref  ->   x4         single-def "argument with side effect"
;  V38 PSPSym       [V38    ] (  1,  1   )    long  ->  [fp+30H]   do-not-enreg[X] addr-exposed "PSPSym"
;  V39 cse0         [V39,T11] (  2,  2   )     ref  ->  x22         "CSE - moderate"
;  V40 cse1         [V40,T28] (  3,  3   )     ref  ->  x26         "CSE - moderate"
;  V41 cse2         [V41,T30] (  3,  3   )    long  ->  x22         "CSE - moderate"
;  V42 cse3         [V42,T02] ( 13, 11   )    long  ->  x25         "CSE - aggressive"
;  V43 cse4         [V43,T03] ( 10,  7   )    long  ->  x23         "CSE - aggressive"
;
; Lcl frame size = 56

G_M23294_IG01:              ;; offset=0000H
        D10243FF          sub     sp, sp, #144
        A9017BFD          stp     fp, lr, [sp,#16]
        FD0027E8          str     d8, [sp,#72]
        A90553F3          stp     x19, x20, [sp,#80]
        A9065BF5          stp     x21, x22, [sp,#96]
        A90763F7          stp     x23, x24, [sp,#112]
        A9086BF9          stp     x25, x26, [sp,#128]
        910043FD          add     fp, sp, #16
        910243E5          add     x5, sp, #144
        F9001BA5          str     x5, [fp,#48]	// [V38 PSPSym]
        F90017A0          str     x0, [fp,#40]	// [V01 arg1]
        F90013A1          str     x1, [fp,#32]	// [V02 arg2]
        B9001FA2          str     w2, [fp,#28]	// [V03 arg3]
        AA0303F3          mov     x19, x3
        1E204008          fmov    s8, s0
						;; bbWeight=1    PerfScore 12.50
G_M23294_IG02:              ;; offset=003CH
        B9401FA0          ldr     w0, [fp,#28]
        72001C1F          tst     w0, #255
        54000081          bne     G_M23294_IG03
        72001C9F          tst     w4, #255
        9A9F17E0          cset    x0, eq
        14000002          b       G_M23294_IG04
						;; bbWeight=1    PerfScore 5.50
G_M23294_IG03:              ;; offset=0054H
        2A1F03E0          mov     w0, wzr
						;; bbWeight=1    PerfScore 0.50
G_M23294_IG04:              ;; offset=0058H
        53001C14          uxtb    w20, w0
        D29E6600          movz    x0, #0xf330
        F2A9FEA0          movk    x0, #0x4ff5 LSL #16
        F2CFFF20          movk    x0, #0x7ff9 LSL #32
        D2800001          mov     x1, #0
        94000000          bl      CORINFO_HELP_NEWARR_1_OBJ
        AA0003F5          mov     x21, x0
        D2921D00          movz    x0, #0x90e8
        F2A9F940          movk    x0, #0x4fca LSL #16
        F2CFFF20          movk    x0, #0x7ff9 LSL #32
        94000000          bl      CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE
        AA0003F6          mov     x22, x0
        D28FCA17          movz    x23, #0x7e50
        F2A9FC17          movk    x23, #0x4fe0 LSL #16
        F2CFFF37          movk    x23, #0x7ff9 LSL #32
        AA1703E0          mov     x0, x23
        D2800141          mov     x1, #10
        94000000          bl      CORINFO_HELP_NEWARR_1_OBJ
        AA0003F8          mov     x24, x0
        9100430E          add     x14, x24, #16
        D2863B19          movz    x25, #0x31d8
        F2BBD919          movk    x25, #0xdec8 LSL #16
        F2C03F59          movk    x25, #506 LSL #32
        F940032F          ldr     x15, [x25]
        94000000          bl      CORINFO_HELP_ASSIGN_REF
        D29B1600          movz    x0, #0xd8b0
        F2A9F940          movk    x0, #0x4fca LSL #16
        F2CFFF20          movk    x0, #0x7ff9 LSL #32
        94000000          bl      CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE
        AA0003FA          mov     x26, x0
        52800041          mov     w1, #2
        94000000          bl      System.RuntimeType:GetCachedName(int):System.String:this
        AA0003EF          mov     x15, x0
        9100630E          add     x14, x24, #24
        94000000          bl      CORINFO_HELP_ASSIGN_REF
        9100830E          add     x14, x24, #32
        F940072F          ldr     x15, [x25,#8]
        94000000          bl      CORINFO_HELP_ASSIGN_REF
        94000000          bl      System.Globalization.NumberFormatInfo:get_CurrentInfo():System.Globalization.NumberFormatInfo
        AA0003E1          mov     x1, x0
        1E204100          fmov    s0, s8
        D2800000          mov     x0, #0
        94000000          bl      System.Number:FormatSingle(float,System.String,System.Globalization.NumberFormatInfo):System.String
        AA0003EF          mov     x15, x0
        9100A30E          add     x14, x24, #40
        94000000          bl      CORINFO_HELP_ASSIGN_REF
        9100C30E          add     x14, x24, #48
        F9400B2F          ldr     x15, [x25,#16]
        94000000          bl      CORINFO_HELP_ASSIGN_REF
        AA1603E0          mov     x0, x22
        52800041          mov     w1, #2
        94000000          bl      System.RuntimeType:GetCachedName(int):System.String:this
        AA0003EF          mov     x15, x0
        9100E30E          add     x14, x24, #56
        94000000          bl      CORINFO_HELP_ASSIGN_REF
        9101030E          add     x14, x24, #64
        F9400F2F          ldr     x15, [x25,#24]
        94000000          bl      CORINFO_HELP_ASSIGN_REF
        910083A0          add     x0, fp, #32	// [V02 arg2]
        94000000          bl      System.Reflection.Emit.OpCode:get_Name():System.String:this
        AA0003EF          mov     x15, x0
        9101230E          add     x14, x24, #72
        94000000          bl      CORINFO_HELP_ASSIGN_REF
        9101430E          add     x14, x24, #80
        F940132F          ldr     x15, [x25,#32]
        94000000          bl      CORINFO_HELP_ASSIGN_REF
        910073A0          add     x0, fp, #28	// [V03 arg3]
        94000000          bl      System.Boolean:ToString():System.String:this
        AA0003EF          mov     x15, x0
        9101630E          add     x14, x24, #88
        94000000          bl      CORINFO_HELP_ASSIGN_REF
        AA1803E0          mov     x0, x24
        94000000          bl      System.String:Concat(System.String[]):System.String
        94000000          bl      System.Console:WriteLine(System.String)
        AA1703E0          mov     x0, x23
        D28000E1          mov     x1, #7
        94000000          bl      CORINFO_HELP_NEWARR_1_OBJ
        AA0003F8          mov     x24, x0
        9100430E          add     x14, x24, #16
        F940172F          ldr     x15, [x25,#40]
        94000000          bl      CORINFO_HELP_ASSIGN_REF
        AA1A03E0          mov     x0, x26
        52800041          mov     w1, #2
        94000000          bl      System.RuntimeType:GetCachedName(int):System.String:this
        AA0003EF          mov     x15, x0
        9100630E          add     x14, x24, #24
        94000000          bl      CORINFO_HELP_ASSIGN_REF
        9100830E          add     x14, x24, #32
        F9401B2F          ldr     x15, [x25,#48]
        94000000          bl      CORINFO_HELP_ASSIGN_REF
        AA1603E0          mov     x0, x22
        52800041          mov     w1, #2
        94000000          bl      System.RuntimeType:GetCachedName(int):System.String:this
        AA0003EF          mov     x15, x0
        9100A30E          add     x14, x24, #40
        94000000          bl      CORINFO_HELP_ASSIGN_REF
        94000000          bl      System.Globalization.NumberFormatInfo:get_CurrentInfo():System.Globalization.NumberFormatInfo
        AA0003E1          mov     x1, x0
        1E204100          fmov    s0, s8
        D2800000          mov     x0, #0
        94000000          bl      System.Number:FormatSingle(float,System.String,System.Globalization.NumberFormatInfo):System.String
        AA0003EF          mov     x15, x0
        9100C30E          add     x14, x24, #48
        94000000          bl      CORINFO_HELP_ASSIGN_REF
        9100E30E          add     x14, x24, #56
        F9401F2F          ldr     x15, [x25,#56]
        94000000          bl      CORINFO_HELP_ASSIGN_REF
        910083A0          add     x0, fp, #32	// [V02 arg2]
        94000000          bl      System.Reflection.Emit.OpCode:get_Name():System.String:this
        AA0003EF          mov     x15, x0
        9101030E          add     x14, x24, #64
        94000000          bl      CORINFO_HELP_ASSIGN_REF
        AA1803E0          mov     x0, x24
        94000000          bl      System.String:Concat(System.String[]):System.String
        F9000BA0          str     x0, [fp,#16]	// [V09 loc3]
        D2815300          movz    x0, #0xa98
        F2A9FF00          movk    x0, #0x4ff8 LSL #16
        F2CFFF20          movk    x0, #0x7ff9 LSL #32
        94000000          bl      CORINFO_HELP_NEWSFAST
        AA0003F8          mov     x24, x0
        52800000          mov     w0, #0
        B90003E0          str     w0, [sp]	// [V13 OutArgs]
        52800020          mov     w0, #1
						;; bbWeight=1    PerfScore 101.00
G_M23294_IG05:              ;; offset=0244H
        B9000BE0          str     w0, [sp,#8]	// [V13 OutArgs+0x08]
        AA1803E0          mov     x0, x24
        F9400BA1          ldr     x1, [fp,#16]	// [V09 loc3]
        AA1603E4          mov     x4, x22
        AA1503E5          mov     x5, x21
        528002C2          mov     w2, #22
        52800023          mov     w3, #1
        D2800006          mov     x6, #0
        D2800007          mov     x7, #0
        94000000          bl      System.Reflection.Emit.DynamicMethod:Init(System.String,int,int,System.Type,System.Type[],System.Type,System.Reflection.Module,bool,bool):this
        AA1803E0          mov     x0, x24
        52800801          mov     w1, #64
        94000000          bl      System.Reflection.Emit.DynamicMethod:GetILGenerator(int):System.Reflection.Emit.ILGenerator:this
        AA0003F5          mov     x21, x0
        F94017A1          ldr     x1, [fp,#40]	// [V01 arg1]
        1E204100          fmov    s0, s8
        F94002A2          ldr     x2, [x21]
        F9402C42          ldr     x2, [x2,#88]
        F9400842          ldr     x2, [x2,#16]
        D63F0040          blr     x2
        AA1503E0          mov     x0, x21
        F94013A1          ldr     x1, [fp,#32]	// [V02 arg2]
        F94002A2          ldr     x2, [x21]
        F9402456          ldr     x22, [x2,#72]
        F9401AC2          ldr     x2, [x22,#48]
        D63F0040          blr     x2
        D283EB01          movz    x1, #0x1f58
        F2BBD901          movk    x1, #0xdec8 LSL #16
        F2C03F41          movk    x1, #506 LSL #32
        F9400021          ldr     x1, [x1]
        F9400421          ldr     x1, [x1,#8]
        AA1503E0          mov     x0, x21
        F9401AC2          ldr     x2, [x22,#48]
        D63F0040          blr     x2
						;; bbWeight=1    PerfScore 47.00
G_M23294_IG06:              ;; offset=02CCH
        D2878C00          movz    x0, #0x3c60
        F2A9F8A0          movk    x0, #0x4fc5 LSL #16
        F2CFFF20          movk    x0, #0x7ff9 LSL #32
        D2800001          mov     x1, #0
        94000000          bl      CORINFO_HELP_NEWARR_1_OBJ
        AA0003E4          mov     x4, x0
        AA1803E0          mov     x0, x24
        D2800001          mov     x1, #0
        52800002          mov     w2, #0
        D2800003          mov     x3, #0
        D2800005          mov     x5, #0
        D2818306          movz    x6, #0xc18
        F2A9FF06          movk    x6, #0x4ff8 LSL #16
        F2CFFF26          movk    x6, #0x7ff9 LSL #32
        F94000C6          ldr     x6, [x6]
        D63F00C0          blr     x6
        AA0003F5          mov     x21, x0
        F94002A1          ldr     x1, [x21]
        D2921D00          movz    x0, #0x90e8
        F2A9F940          movk    x0, #0x4fca LSL #16
        F2CFFF20          movk    x0, #0x7ff9 LSL #32
        EB00003F          cmp     x1, x0
        540000C0          beq     G_M23294_IG08
						;; bbWeight=1    PerfScore 18.00
G_M23294_IG07:              ;; offset=0328H
        AA1503E1          mov     x1, x21
        D2921D00          movz    x0, #0x90e8
        F2A9F940          movk    x0, #0x4fca LSL #16
        F2CFFF20          movk    x0, #0x7ff9 LSL #32
        94000000          bl      CORINFO_HELP_UNBOX
						;; bbWeight=0.50 PerfScore 1.50
G_M23294_IG08:              ;; offset=033CH
        F94006B5          ldr     x21, [x21,#8]
        B9401FA0          ldr     w0, [fp,#28]	// [V03 arg3]
        72001C1F          tst     w0, #255
        54000100          beq     G_M23294_IG09
        B85BC2E0          ldr     w0, [x23,#-68]
        11000400          add     w0, w0, #1
        B81BC2E0          str     w0, [x23,#-68]
        F9402320          ldr     x0, [x25,#64]
        F9400BA1          ldr     x1, [fp,#16]	// [V09 loc3]
        94000000          bl      System.String:Concat(System.String,System.String):System.String
        94000000          bl      System.Console:WriteLine(System.String)
						;; bbWeight=1    PerfScore 18.00
G_M23294_IG09:              ;; offset=0368H
        34000154          cbz     w20, G_M23294_IG10
        EB15027F          cmp     x19, x21
        54000100          beq     G_M23294_IG10
        B85BC2E0          ldr     w0, [x23,#-68]
        11000400          add     w0, w0, #1
        B81BC2E0          str     w0, [x23,#-68]
        F9402720          ldr     x0, [x25,#72]
        F9400BA1          ldr     x1, [fp,#16]	// [V09 loc3]
        94000000          bl      System.String:Concat(System.String,System.String):System.String
        94000000          bl      System.Console:WriteLine(System.String)
						;; bbWeight=1    PerfScore 14.00
G_M23294_IG10:              ;; offset=0390H
        A9486BF9          ldp     x25, x26, [sp,#128]
        A94763F7          ldp     x23, x24, [sp,#112]
        A9465BF5          ldp     x21, x22, [sp,#96]
        A94553F3          ldp     x19, x20, [sp,#80]
        FD4027E8          ldr     d8, [sp,#72]
        A9417BFD          ldp     fp, lr, [sp,#16]
        910243FF          add     sp, sp, #144
        D65F03C0          ret     lr
						;; bbWeight=1    PerfScore 8.50
G_M23294_IG11:              ;; offset=03B0H
        D101C3FF          sub     sp, sp, #112
        A9017BFD          stp     fp, lr, [sp,#16]
        FD0017E8          str     d8, [sp,#40]
        A90353F3          stp     x19, x20, [sp,#48]
        A9045BF5          stp     x21, x22, [sp,#64]
        A90563F7          stp     x23, x24, [sp,#80]
        A9066BF9          stp     x25, x26, [sp,#96]
        910203A3          add     x3, fp, #128
        F90013E3          str     x3, [sp,#32]
						;; bbWeight=0    PerfScore 0.00
G_M23294_IG12:              ;; offset=03D4H
        B9401FA0          ldr     w0, [fp,#28]	// [V03 arg3]
        72001C1F          tst     w0, #255
        540001C1          bne     G_M23294_IG13
        D28FCA17          movz    x23, #0x7e50
        F2A9FC17          movk    x23, #0x4fe0 LSL #16
        F2CFFF37          movk    x23, #0x7ff9 LSL #32
        B85BC2E0          ldr     w0, [x23,#-68]
        11000400          add     w0, w0, #1
        B81BC2E0          str     w0, [x23,#-68]
        D2863B19          movz    x25, #0x31d8
        F2BBD919          movk    x25, #0xdec8 LSL #16
        F2C03F59          movk    x25, #506 LSL #32
        F9402B20          ldr     x0, [x25,#80]
        F9400BA1          ldr     x1, [fp,#16]	// [V09 loc3]
        94000000          bl      System.String:Concat(System.String,System.String):System.String
        94000000          bl      System.Console:WriteLine(System.String)
						;; bbWeight=0    PerfScore 0.00
G_M23294_IG13:              ;; offset=0414H
        10FFFBE0          adr     x0, [G_M23294_IG10]
						;; bbWeight=0    PerfScore 0.00
G_M23294_IG14:              ;; offset=0418H
        A9466BF9          ldp     x25, x26, [sp,#96]
        A94563F7          ldp     x23, x24, [sp,#80]
        A9445BF5          ldp     x21, x22, [sp,#64]
        A94353F3          ldp     x19, x20, [sp,#48]
        FD4017E8          ldr     d8, [sp,#40]
        A9417BFD          ldp     fp, lr, [sp,#16]
        9101C3FF          add     sp, sp, #112
        D65F03C0          ret     lr
						;; bbWeight=0    PerfScore 0.00

; Total bytes of code 1080, prolog size 60, PerfScore 334.50, instruction count 270, allocated bytes for code 1080 (MethodHash=344ea501) for method CheckGenericSbyte.Program:GenerateTest(float,System.Reflection.Emit.OpCode,System.Reflection.Emit.OpCode,bool,long,bool)

@sandreenko
Copy link
Contributor Author

@briansull so your analysis was done using an altjit?

@briansull
Copy link
Contributor

briansull commented Jul 30, 2021

Yes, that is correct.

@briansull briansull changed the title Arm64 VN bug. Arm64 codegen bug. Jul 30, 2021
@sandreenko sandreenko added area-ExceptionHandling-coreclr and removed area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI labels Aug 4, 2021
@sandreenko
Copy link
Contributor Author

I have investigated it more and I believe there is a problem with non-volatile floating register restore after an exception that happens in C++ on arm64 Linux/OSX. I have discussed it with @davidwrighton and he suggested moving it to the runtime area for now.

So I suspect that if we throw an exception like this:

FCThrow(kOverflowException);

we don't restore non-volatile d8 after we get to the parent method that was using it.

I also was able to shrink the test and repro the issue without any reflection/IL generation involved as David asked but now it reproduces only on arm64 Mac, not on arm64 Linux, the source is here:
https://github.com/sandreenko/runtime/blob/4f1242c7e2ab665c3e9f02e693d2f34fabcdd33d/src/tests/JIT/IL_Conformance/Convert/TestConvertFromIntegral.cs

The expected output is:

seandree@seandreemac TestConvertFromIntegral % ./TestConvertFromIntegral.sh
BEGIN EXECUTION
/Users/seandree/git/runtime/artifacts/tests/coreclr/OSX.arm64.Checked/Tests/Core_Root/corerun TestConvertFromIntegral.dll ''
Value before, on entry -9.223372E+18
Value before, in try -9.223372E+18
Value after -9.223372E+18
Value before, on entry 0
Value before, in try 0
Value after 0
Value before, on entry 0
Value before, in try 0
Value after 0
Test Simple value is 0, f1 is 0
Process terminated. Assertion failed.
   at TestCasts.Program.TestSimple(Single f, Object f1) in TestConvertFromIntegral.dll:token 0x6000004+0x21
   at TestCasts.Program.TestConvertFromFloatToU8() in TestConvertFromIntegral.dll:token 0x6000003+0x1e
   at TestCasts.Program.Main(String[] args) in TestConvertFromIntegral.dll:token 0x6000005+0x0
./TestConvertFromIntegral.sh: line 353: 30998 Abort trap: 6           $LAUNCHER $ExePath "${CLRTestExecutionArguments[@]}"
Expected: 100
Actual: 134
END EXECUTION - FAILED

and if you want to repro it on arm64 Linux you should use the original test and shrink it after:
https://github.com/sandreenko/runtime/blob/262b1a452a068d915f6a780bf63aa4ded48fc588/src/tests/JIT/IL_Conformance/ConvertFromMain/TestConvertFromIntegral.cs

@janvorli could you please take a look as an exception expert?

@sandreenko sandreenko assigned janvorli and unassigned sandreenko Aug 4, 2021
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Aug 5, 2021
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Aug 8, 2021
davidwrighton pushed a commit that referenced this issue Aug 8, 2021
* Fix ARM64 floating point registers unwinding in PAL

We were not unwinding the non-volatile floating point registers at all
(not transferring them between the CONTEXT and ucontext_t before and
after the unw_step). That causes crashes on arm64 Unix in some of
the tests since JIT now generates code that uses e.g. the D8 register
and a runtime code that was throwing an exception was using it too.

* Fix non-OSX arm64, remove test csproj patch

* Fix Linux arm64

* Fix Linux arm64 - now really

Fixes #56522
@VincentBu
Copy link
Contributor

Failed again in runtime-coreclr jitstress 20210807.1

Failed test:

CoreCLR Linux arm Checked jitstress1 @ (Ubuntu.1804.Arm32.Open)Ubuntu.1804.Armarch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-arm32v7-bfcd90a-20200121150440

- JIT/IL_Conformance/Convert/TestConvertFromIntegral/TestConvertFromIntegral.sh

Error message:

Return code:      1
Raw output file:      /root/helix/work/workitem/uploads/Reports/JIT.IL_Conformance/Convert/TestConvertFromIntegral/TestConvertFromIntegral.output.txt
Raw output:
BEGIN EXECUTION
/root/helix/work/correlation/corerun TestConvertFromIntegral.dll ''
No exception in DynamicConvertFromSystem.SingleToSystem.UInt640Opconv.ovf.u8
No exception in DynamicConvertFromSystem.SingleToSystem.UInt640Opconv.ovf.u8.un
The number of failed tests: 2
Expected: 100
Actual: 101
END EXECUTION - FAILED
Test Harness Exitcode is : 1
To run the test:

set CORE_ROOT=/root/helix/work/correlation
/root/helix/work/workitem/JIT/IL_Conformance/Convert/TestConvertFromIntegral/TestConvertFromIntegral.sh
Expected: True
Actual:   False


Stack trace
   at JIT_IL_Conformance._Convert_TestConvertFromIntegral_TestConvertFromIntegral_._Convert_TestConvertFromIntegral_TestConvertFromIntegral_sh() in JIT.IL_Conformance.XUnitWrapper.dll:token 0x6000004+0x295

@JulieLeeMSFT
Copy link
Member

CC @janvorli @davidwrighton

@ghost ghost locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants