Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

[BUG] Burst compiler bug when converting uint constants to ulong?

Discussion in 'Data Oriented Technology Stack' started by x_unity897, Nov 16, 2018.

  1. x_unity897

    x_unity897

    Joined:
    Oct 2, 2018
    Posts:
    5
    We were trying to enable burst compiler for our job systems and found incorrect behavior when enabling burst compile for some jobs. After hours of debugging, I have finally narrowed it down to a single uint to ulong assignment that's not working correctly. Below is the code snippet that can reproduce the problem:

    Code (CSharp):
    1.  
    2.     public struct Data : IComponentData
    3.     {
    4.         public ulong Value;
    5.     }
    6.     public class TestBurstComponentSystem : JobComponentSystem
    7.     {
    8.         [BurstCompile]
    9.         private struct Job : IJobProcessComponentData<Data>
    10.         {
    11.             public void Execute(ref Data data)
    12.             {
    13.                 data.Value = uint.MaxValue;
    14.             }
    15.         }
    16.  
    17.         protected override JobHandle OnUpdate(JobHandle inputDeps)
    18.         {
    19.             return new Job().Schedule(this, inputDeps);
    20.         }
    21.     }
    22.  
    uint.MaxValue is 4294967295 and ulong has a larger range than uint so you would expect the value to be 4294967295 after the assignment in "data.Value = uint.MaxValue". However, when burst is enabled, the result ulong value will be 18446744073709551615.

    I have created a demo project you can check to reproduce this:
    https://github.com/xfxyjwf/burstbug

    It has one scene in Scens/SampleScene with one text label showing the result of the assignment. When burst is enabled, the value shown in the center of the screen is 18446744073709551615 and as soon as you disable burst jobs in the "Jobs -> Use Burst Jobs" menu it will change back to the correct value 4294967295.

    Some more info from the burst inspector:

    The compiled IL instructions of the Job.Execute method:
    Code (csharp):
    1.  
    2. IL_0001: ldarg.1
    3. IL_0002: ldc.i4.m1
    4. IL_0003: conv.u8 args(IL_0002)
    5. IL_0004: stfld System.UInt64 TestBurstBug/Data::Value args(IL_0001, IL_0003)
    6. IL_0009: ret
    7.  
    It pushes -1 as a 32-bit value onto the stack and then do an unsigned extension to convert it to a 64-bit value. That should produce 4294967295.

    The converted LLVM IR (unoptimized), however, stores -1 directly into the field:
    Code (csharp):
    1.  
    2. BL.0000:                                          ; preds = %BL.entry
    3.   %0 = getelementptr %"TestBurstBug/Data.79", %"TestBurstBug/Data.79"* %data, i32 0, i32 0
    4.   store i64 -1, i64* %0
    5.   ret void
    6. }
    7.  
    It seems to me the burst compiler is handling the conv.u8 instruction incorrectly.

    This issue makes burst compiler unusable for us because every constant value in the range [2^31, 2^32) will be converted incorrectly (e.g., (longValue & 0x00000000FFFFFFFFL) doesn't work when burst is enabled).

    Please help and let me know if it's a project configuration issue on our end.
     
  2. xoofx

    xoofx

    Unity Technologies

    Joined:
    Nov 5, 2016
    Posts:
    186
    Our apologize for this issue, this should be fixed in an upcoming 0.2.4-preview.38 available later today
     
  3. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,031
    Oh... new ecs release? :)
     
  4. xoofx

    xoofx

    Unity Technologies

    Joined:
    Nov 5, 2016
    Posts:
    186
    For ECS, I can't tell, but you can update burst separately. You can reference explicitly burst package to your project to override the one used by ECS
     
  5. x_unity897

    x_unity897

    Joined:
    Oct 2, 2018
    Posts:
    5
    Thanks for the reply! I couldn't find 0.2.4-preview.38 though. Is it already released?
     
  6. xoofx

    xoofx

    Unity Technologies

    Joined:
    Nov 5, 2016
    Posts:
    186
    You need to use the staging registry by modifying your manifest.json and using "registry": "https://staging-packages.unity.com",
     
  7. x_unity897

    x_unity897

    Joined:
    Oct 2, 2018
    Posts:
    5
    Confirmed that 0.2.4-preview.38 fixed the bug we were seeing. Thanks so much for the help!