Skip to content

JIT: Propagate multi-reg-index for upper-vector-restore ref positions #88380

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

Merged

Conversation

jakobbotsch
Copy link
Member

LinearScan::resolveRegisters will write the register back to the IR node for an upper-vector-restore RP, so without this propagation we would overwrite the register assignment for an unrelated field.

For example, for IR like

N001 (  9,  6) [000090] m------N---                   t90 =    LCL_VAR   struct<JIT.HardwareIntrinsics.Arm._AdvSimd.SimpleTernaryOpTest__AbsoluteDifferenceWideningUpperAndAdd_Vector128_UInt32+TestStruct, 48>(P) V00 loc0
                                                                simd16 field V00._fld1 (fldOffset=0x0) -> V14 tmp10         (last use)
                                                                simd16 field V00._fld2 (fldOffset=0x10) -> V15 tmp11         (last use)
                                                                simd16 field V00._fld3 (fldOffset=0x20) -> V16 tmp12         (last use) $540
                                                            ┌──▌  t90    struct
N002 ( 10,  7) [000091] -----------                           RETURN    struct $VN.Void

we could build ref positions such as

[000091] 449.#639 U14  UVRs   UVRes    NA   │    │    │    │    │    │    │    │    │    │    │    │    │V16a│    │    │    │
         449.#640 d0   Fixd   Keep     d0   │    │    │    │    │    │    │    │    │    │    │    │    │V16a│    │    │    │
         449.#641 V14  Use *  ReLod    d0   │    │    │    │    │    │    │    │    │    │    │V14a│    │V16a│    │    │    │
                              Keep     d0   │    │    │    │    │    │    │    │    │    │    │V14i│    │V16a│    │    │    │
         449.#642 U15  UVRs   UVRes    NA   │    │    │    │    │    │    │    │    │    │    │    │    │V16a│    │    │    │
         449.#643 d1   Fixd   Keep     d1   │    │    │    │    │    │    │    │    │    │    │    │    │V16a│    │    │    │
         449.#644 V15  Use *  ReLod    d1   │    │    │    │    │    │    │    │    │    │    │    │V15a│V16a│    │    │    │
                              Keep     d1   │    │    │    │    │    │    │    │    │    │    │    │V15i│V16a│    │    │    │
         449.#645 d2   Fixd   Keep     d2   │    │    │    │    │    │    │    │    │    │    │    │    │V16a│    │    │    │
         449.#646 V16  Use *  Keep     d2   │    │    │    │    │    │    │    │    │    │    │    │    │V16i│    │    │    │

When writing back register assignments the upper-vector-restore at 449.#642 ended up overwriting the assignment for the first field on [000090], resulting in

N447 (  9,  6) [000090] m------N--z                   t90 =    LCL_VAR   struct<JIT.HardwareIntrinsics.Arm._AdvSimd.SimpleTernaryOpTest__AbsoluteDifferenceWideningUpperAndAdd_Vector128_UInt32+TestStruct, 48>(P) V00 loc0          NA
                                                                simd16 field V00._fld1 (fldOffset=0x0) -> V14 tmp10         (last use)
                                                                simd16 field V00._fld2 (fldOffset=0x10) -> V15 tmp11         (last use)
                                                                simd16 field V00._fld3 (fldOffset=0x20) -> V16 tmp12         d2 (last use) REG NA,d1,d2 $540
                                                            ┌──▌  t90    struct
N449 ( 10,  7) [000091] -----------                           RETURN    struct REG NA $VN.Void

(note the REG NA instead of REG d0).

`LinearScan::resolveRegisters` will write the register back to the IR
node for an upper-vector-restore RP, so without this propagation we
would overwrite the register assignment for an unrelated field.

For example, for IR like
```scala
N001 (  9,  6) [000090] m------N---                   t90 =    LCL_VAR   struct<JIT.HardwareIntrinsics.Arm._AdvSimd.SimpleTernaryOpTest__AbsoluteDifferenceWideningUpperAndAdd_Vector128_UInt32+TestStruct, 48>(P) V00 loc0
                                                            ▌    simd16 field V00._fld1 (fldOffset=0x0) -> V14 tmp10         (last use)
                                                            ▌    simd16 field V00._fld2 (fldOffset=0x10) -> V15 tmp11         (last use)
                                                            ▌    simd16 field V00._fld3 (fldOffset=0x20) -> V16 tmp12         (last use) $540
                                                            ┌──▌  t90    struct
N002 ( 10,  7) [000091] -----------                         ▌  RETURN    struct $VN.Void
```
we could build ref positions such as

```
[000091] 449.dotnet#639 U14  UVRs   UVRes    NA   │    │    │    │    │    │    │    │    │    │    │    │    │V16a│    │    │    │
         449.dotnet#640 d0   Fixd   Keep     d0   │    │    │    │    │    │    │    │    │    │    │    │    │V16a│    │    │    │
         449.dotnet#641 V14  Use *  ReLod    d0   │    │    │    │    │    │    │    │    │    │    │V14a│    │V16a│    │    │    │
                              Keep     d0   │    │    │    │    │    │    │    │    │    │    │V14i│    │V16a│    │    │    │
         449.dotnet#642 U15  UVRs   UVRes    NA   │    │    │    │    │    │    │    │    │    │    │    │    │V16a│    │    │    │
         449.dotnet#643 d1   Fixd   Keep     d1   │    │    │    │    │    │    │    │    │    │    │    │    │V16a│    │    │    │
         449.dotnet#644 V15  Use *  ReLod    d1   │    │    │    │    │    │    │    │    │    │    │    │V15a│V16a│    │    │    │
                              Keep     d1   │    │    │    │    │    │    │    │    │    │    │    │V15i│V16a│    │    │    │
         449.dotnet#645 d2   Fixd   Keep     d2   │    │    │    │    │    │    │    │    │    │    │    │    │V16a│    │    │    │
         449.dotnet#646 V16  Use *  Keep     d2   │    │    │    │    │    │    │    │    │    │    │    │    │V16i│    │    │    │
```

When writing back register assignments the upper-vector-restore at dotnet#642
ended up overwriting the assignment for the first field on [000090],
resulting in

```scala
N447 (  9,  6) [000090] m------N--z                   t90 =    LCL_VAR   struct<JIT.HardwareIntrinsics.Arm._AdvSimd.SimpleTernaryOpTest__AbsoluteDifferenceWideningUpperAndAdd_Vector128_UInt32+TestStruct, 48>(P) V00 loc0          NA
                                                            ▌    simd16 field V00._fld1 (fldOffset=0x0) -> V14 tmp10         (last use)
                                                            ▌    simd16 field V00._fld2 (fldOffset=0x10) -> V15 tmp11         (last use)
                                                            ▌    simd16 field V00._fld3 (fldOffset=0x20) -> V16 tmp12         d2 (last use) REG NA,d1,d2 $540
                                                            ┌──▌  t90    struct
N449 ( 10,  7) [000091] -----------                         ▌  RETURN    struct REG NA $VN.Void
```
(note the REG NA instead of REG d0).
@ghost ghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Jul 4, 2023
@ghost ghost assigned jakobbotsch Jul 4, 2023
@ghost
Copy link

ghost commented Jul 4, 2023

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Issue Details

LinearScan::resolveRegisters will write the register back to the IR node for an upper-vector-restore RP, so without this propagation we would overwrite the register assignment for an unrelated field.

For example, for IR like

N001 (  9,  6) [000090] m------N---                   t90 =    LCL_VAR   struct<JIT.HardwareIntrinsics.Arm._AdvSimd.SimpleTernaryOpTest__AbsoluteDifferenceWideningUpperAndAdd_Vector128_UInt32+TestStruct, 48>(P) V00 loc0
                                                                simd16 field V00._fld1 (fldOffset=0x0) -> V14 tmp10         (last use)
                                                                simd16 field V00._fld2 (fldOffset=0x10) -> V15 tmp11         (last use)
                                                                simd16 field V00._fld3 (fldOffset=0x20) -> V16 tmp12         (last use) $540
                                                            ┌──▌  t90    struct
N002 ( 10,  7) [000091] -----------                           RETURN    struct $VN.Void

we could build ref positions such as

[000091] 449.#639 U14  UVRs   UVRes    NA   │    │    │    │    │    │    │    │    │    │    │    │    │V16a│    │    │    │
         449.#640 d0   Fixd   Keep     d0   │    │    │    │    │    │    │    │    │    │    │    │    │V16a│    │    │    │
         449.#641 V14  Use *  ReLod    d0   │    │    │    │    │    │    │    │    │    │    │V14a│    │V16a│    │    │    │
                              Keep     d0   │    │    │    │    │    │    │    │    │    │    │V14i│    │V16a│    │    │    │
         449.#642 U15  UVRs   UVRes    NA   │    │    │    │    │    │    │    │    │    │    │    │    │V16a│    │    │    │
         449.#643 d1   Fixd   Keep     d1   │    │    │    │    │    │    │    │    │    │    │    │    │V16a│    │    │    │
         449.#644 V15  Use *  ReLod    d1   │    │    │    │    │    │    │    │    │    │    │    │V15a│V16a│    │    │    │
                              Keep     d1   │    │    │    │    │    │    │    │    │    │    │    │V15i│V16a│    │    │    │
         449.#645 d2   Fixd   Keep     d2   │    │    │    │    │    │    │    │    │    │    │    │    │V16a│    │    │    │
         449.#646 V16  Use *  Keep     d2   │    │    │    │    │    │    │    │    │    │    │    │    │V16i│    │    │    │

When writing back register assignments the upper-vector-restore at 449.#642 ended up overwriting the assignment for the first field on [000090], resulting in

N447 (  9,  6) [000090] m------N--z                   t90 =    LCL_VAR   struct<JIT.HardwareIntrinsics.Arm._AdvSimd.SimpleTernaryOpTest__AbsoluteDifferenceWideningUpperAndAdd_Vector128_UInt32+TestStruct, 48>(P) V00 loc0          NA
                                                                simd16 field V00._fld1 (fldOffset=0x0) -> V14 tmp10         (last use)
                                                                simd16 field V00._fld2 (fldOffset=0x10) -> V15 tmp11         (last use)
                                                                simd16 field V00._fld3 (fldOffset=0x20) -> V16 tmp12         d2 (last use) REG NA,d1,d2 $540
                                                            ┌──▌  t90    struct
N449 ( 10,  7) [000091] -----------                           RETURN    struct REG NA $VN.Void

(note the REG NA instead of REG d0).

Author: jakobbotsch
Assignees: jakobbotsch
Labels:

area-CodeGen-coreclr

Milestone: -

@jakobbotsch
Copy link
Member Author

/azp run runtime-coreclr jitstress, runtime-coreclr libraries-jitstress, runtime-coreclr jitstressregs

@azure-pipelines
Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@jakobbotsch
Copy link
Member Author

/azp run runtime-coreclr superpmi-diffs

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jakobbotsch jakobbotsch marked this pull request as ready for review July 5, 2023 13:50
@jakobbotsch
Copy link
Member Author

cc @dotnet/jit-contrib PTAL @kunalspathak

No diffs. Fixes a problem I hit in #84122 with JitStressRegs=2.

@jakobbotsch jakobbotsch requested a review from kunalspathak July 5, 2023 13:51
Copy link
Member

@kunalspathak kunalspathak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kunalspathak
Copy link
Member

I am assuming the jitstress failures are unrelated?

@jakobbotsch
Copy link
Member Author

I am assuming the jitstress failures are unrelated?

Yep, they are known according to build analysis.

@jakobbotsch jakobbotsch merged commit d52b303 into dotnet:main Jul 5, 2023
@jakobbotsch jakobbotsch deleted the lsra-multireg-upper-vector-restore branch July 5, 2023 15:16
@ghost ghost locked as resolved and limited conversation to collaborators Aug 4, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants