Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64 - #101927

Merged
VSadov merged 2 commits into
dotnet:mainfrom
VSadov:fix101896
May 7, 2024
Merged

Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64#101927
VSadov merged 2 commits into
dotnet:mainfrom
VSadov:fix101896

Conversation

@VSadov

@VSadovVSadov commented May 6, 2024

Copy link
Copy Markdown
Member

Fixes: #101896

With #101647 we started using LR as a general purpose register when doing indirect calls and that broke our logic on NativeAOT that detects whether a thread is in an epilog on linux-arm64

Using LR as a GPR is not illegal, just something that we did not do before, so once we see LR (or FP) loaded with some value, the epilog detection logic assumes that we are in an epilog.

Long-term (and assuming that some platforms will never learn how to unwind in epilogs), I think we should encode the epilog ranges. In GC info, I suppose. It will not be trivial as there could be more than one epilog in a method, so encoding them all and then searching through them to answer IsUnwindable question could be a bit tricky. However, it will be a more portable approach.

For now we can have a simpler fix - we do not have to use LR for indirect call targets, so let's not use it.
It seems like REG_INDIRECT_CALL_TARGET_REG is a better fit for this.

@ghostghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 6, 2024
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

@VSadov
VSadov requested a review from jakobbotschMay 6, 2024 17:30
#ifdef TARGET_ARM
// For arm32 we've allocated an internal register to load the target into.
// Loading into lr takes 4 bytes (instead of potentially 2 with another register).
// Loading into IP takes 4 bytes (instead of potentially 2 with another register).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a register called this on arm32?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Yes (IP/r12 I think), but i think it cannot be loaded in 2byte instr

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah, I wasn't aware of that alias. R12 would be problematic to use anyway because we use it as an argument register in a bunch of a cases.

@jakobbotschjakobbotsch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks! I was not aware that we cannot use LR as a GPR. Is that just a coreclr constraint or a more general property for arm64?

For arm32, we definitely use LR as a scratch register in more cases (REG_SCRATCH is defined as REG_LR). Is that problematic?

@VSadov

VSadov commented May 6, 2024

Copy link
Copy Markdown
MemberAuthor

Thanks! I was not aware that we cannot use LR as a GPR

That is not illegal. It is just was not done before and at the time when the epilog detection heuristic was introduced, we assumed it will not be needed in the future. We had a small discussion about that.

For arm32, we definitely use LR as a scratch register in more cases.

Not sure how that is handled. Either Arm32 can unwind in epilog (unlikely), or has more complex heuristic that looks for actual epilog patterns.
On arm64 we could get away with just looking for LR/FP loads vs. something that is never in an epilog (calls, branches...).

I've logged a bug to replace this practice with something more robust - like storing the epilog ranges in GC info.
#101932

@VSadov

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-nativeaot-outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@VSadov

Copy link
Copy Markdown
MemberAuthor

All tests are green, including NativeAOT outer loop.

I will add a commit with a comment about current dependency on LR not being a GPR.

@VSadov
VSadov merged commit e1c6717 into dotnet:mainMay 7, 2024
@VSadov
VSadov deleted the fix101896 branch May 7, 2024 06:20
@VSadov

Copy link
Copy Markdown
MemberAuthor

Thanks!!!

michaelgsharp pushed a commit to michaelgsharp/runtime that referenced this pull request May 9, 2024
…101927)
* Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64
* Added a comment about NativeAOT dependency at the place wehre we exclude LR from availableIntRegs
Ruihan-Yin pushed a commit to Ruihan-Yin/runtime that referenced this pull request May 30, 2024
…101927)
* Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64
* Added a comment about NativeAOT dependency at the place wehre we exclude LR from availableIntRegs
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 6, 2024
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR 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.

[NativeAOT/linux-arm64] AF: codeManager->IsUnwindable(pvAddress) || runtime->IsConservativeStackReportingEnabled()

2 participants

@VSadov@jakobbotsch
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64 - #101927

Merged
VSadov merged 2 commits into
dotnet:mainfrom
VSadov:fix101896
May 7, 2024
Merged

Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64#101927
VSadov merged 2 commits into
dotnet:mainfrom
VSadov:fix101896

Conversation

@VSadov

@VSadovVSadov commented May 6, 2024

Copy link
Copy Markdown
Member

Fixes: #101896

With #101647 we started using LR as a general purpose register when doing indirect calls and that broke our logic on NativeAOT that detects whether a thread is in an epilog on linux-arm64

Using LR as a GPR is not illegal, just something that we did not do before, so once we see LR (or FP) loaded with some value, the epilog detection logic assumes that we are in an epilog.

Long-term (and assuming that some platforms will never learn how to unwind in epilogs), I think we should encode the epilog ranges. In GC info, I suppose. It will not be trivial as there could be more than one epilog in a method, so encoding them all and then searching through them to answer IsUnwindable question could be a bit tricky. However, it will be a more portable approach.

For now we can have a simpler fix - we do not have to use LR for indirect call targets, so let's not use it.
It seems like REG_INDIRECT_CALL_TARGET_REG is a better fit for this.

@ghostghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 6, 2024
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

@VSadov
VSadov requested a review from jakobbotschMay 6, 2024 17:30
#ifdef TARGET_ARM
// For arm32 we've allocated an internal register to load the target into.
// Loading into lr takes 4 bytes (instead of potentially 2 with another register).
// Loading into IP takes 4 bytes (instead of potentially 2 with another register).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a register called this on arm32?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Yes (IP/r12 I think), but i think it cannot be loaded in 2byte instr

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah, I wasn't aware of that alias. R12 would be problematic to use anyway because we use it as an argument register in a bunch of a cases.

@jakobbotschjakobbotsch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks! I was not aware that we cannot use LR as a GPR. Is that just a coreclr constraint or a more general property for arm64?

For arm32, we definitely use LR as a scratch register in more cases (REG_SCRATCH is defined as REG_LR). Is that problematic?

@VSadov

VSadov commented May 6, 2024

Copy link
Copy Markdown
MemberAuthor

Thanks! I was not aware that we cannot use LR as a GPR

That is not illegal. It is just was not done before and at the time when the epilog detection heuristic was introduced, we assumed it will not be needed in the future. We had a small discussion about that.

For arm32, we definitely use LR as a scratch register in more cases.

Not sure how that is handled. Either Arm32 can unwind in epilog (unlikely), or has more complex heuristic that looks for actual epilog patterns.
On arm64 we could get away with just looking for LR/FP loads vs. something that is never in an epilog (calls, branches...).

I've logged a bug to replace this practice with something more robust - like storing the epilog ranges in GC info.
#101932

@VSadov

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-nativeaot-outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@VSadov

Copy link
Copy Markdown
MemberAuthor

All tests are green, including NativeAOT outer loop.

I will add a commit with a comment about current dependency on LR not being a GPR.

@VSadov
VSadov merged commit e1c6717 into dotnet:mainMay 7, 2024
@VSadov
VSadov deleted the fix101896 branch May 7, 2024 06:20
@VSadov

Copy link
Copy Markdown
MemberAuthor

Thanks!!!

michaelgsharp pushed a commit to michaelgsharp/runtime that referenced this pull request May 9, 2024
…101927)
* Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64
* Added a comment about NativeAOT dependency at the place wehre we exclude LR from availableIntRegs
Ruihan-Yin pushed a commit to Ruihan-Yin/runtime that referenced this pull request May 30, 2024
…101927)
* Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64
* Added a comment about NativeAOT dependency at the place wehre we exclude LR from availableIntRegs
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 6, 2024
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR 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.

[NativeAOT/linux-arm64] AF: codeManager->IsUnwindable(pvAddress) || runtime->IsConservativeStackReportingEnabled()

2 participants

@VSadov@jakobbotsch
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64 - #101927

Merged
VSadov merged 2 commits into
dotnet:mainfrom
VSadov:fix101896
May 7, 2024
Merged

Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64#101927
VSadov merged 2 commits into
dotnet:mainfrom
VSadov:fix101896

Conversation

@VSadov

@VSadovVSadov commented May 6, 2024

Copy link
Copy Markdown
Member

Fixes: #101896

With #101647 we started using LR as a general purpose register when doing indirect calls and that broke our logic on NativeAOT that detects whether a thread is in an epilog on linux-arm64

Using LR as a GPR is not illegal, just something that we did not do before, so once we see LR (or FP) loaded with some value, the epilog detection logic assumes that we are in an epilog.

Long-term (and assuming that some platforms will never learn how to unwind in epilogs), I think we should encode the epilog ranges. In GC info, I suppose. It will not be trivial as there could be more than one epilog in a method, so encoding them all and then searching through them to answer IsUnwindable question could be a bit tricky. However, it will be a more portable approach.

For now we can have a simpler fix - we do not have to use LR for indirect call targets, so let's not use it.
It seems like REG_INDIRECT_CALL_TARGET_REG is a better fit for this.

@ghostghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 6, 2024
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

@VSadov
VSadov requested a review from jakobbotschMay 6, 2024 17:30
#ifdef TARGET_ARM
// For arm32 we've allocated an internal register to load the target into.
// Loading into lr takes 4 bytes (instead of potentially 2 with another register).
// Loading into IP takes 4 bytes (instead of potentially 2 with another register).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a register called this on arm32?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Yes (IP/r12 I think), but i think it cannot be loaded in 2byte instr

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah, I wasn't aware of that alias. R12 would be problematic to use anyway because we use it as an argument register in a bunch of a cases.

@jakobbotschjakobbotsch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks! I was not aware that we cannot use LR as a GPR. Is that just a coreclr constraint or a more general property for arm64?

For arm32, we definitely use LR as a scratch register in more cases (REG_SCRATCH is defined as REG_LR). Is that problematic?

@VSadov

VSadov commented May 6, 2024

Copy link
Copy Markdown
MemberAuthor

Thanks! I was not aware that we cannot use LR as a GPR

That is not illegal. It is just was not done before and at the time when the epilog detection heuristic was introduced, we assumed it will not be needed in the future. We had a small discussion about that.

For arm32, we definitely use LR as a scratch register in more cases.

Not sure how that is handled. Either Arm32 can unwind in epilog (unlikely), or has more complex heuristic that looks for actual epilog patterns.
On arm64 we could get away with just looking for LR/FP loads vs. something that is never in an epilog (calls, branches...).

I've logged a bug to replace this practice with something more robust - like storing the epilog ranges in GC info.
#101932

@VSadov

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-nativeaot-outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@VSadov

Copy link
Copy Markdown
MemberAuthor

All tests are green, including NativeAOT outer loop.

I will add a commit with a comment about current dependency on LR not being a GPR.

@VSadov
VSadov merged commit e1c6717 into dotnet:mainMay 7, 2024
@VSadov
VSadov deleted the fix101896 branch May 7, 2024 06:20
@VSadov

Copy link
Copy Markdown
MemberAuthor

Thanks!!!

michaelgsharp pushed a commit to michaelgsharp/runtime that referenced this pull request May 9, 2024
…101927)
* Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64
* Added a comment about NativeAOT dependency at the place wehre we exclude LR from availableIntRegs
Ruihan-Yin pushed a commit to Ruihan-Yin/runtime that referenced this pull request May 30, 2024
…101927)
* Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64
* Added a comment about NativeAOT dependency at the place wehre we exclude LR from availableIntRegs
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 6, 2024
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR 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.

[NativeAOT/linux-arm64] AF: codeManager->IsUnwindable(pvAddress) || runtime->IsConservativeStackReportingEnabled()

2 participants

@VSadov@jakobbotsch
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64 - #101927

Merged
VSadov merged 2 commits into
dotnet:mainfrom
VSadov:fix101896
May 7, 2024
Merged

Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64#101927
VSadov merged 2 commits into
dotnet:mainfrom
VSadov:fix101896

Conversation

@VSadov

@VSadovVSadov commented May 6, 2024

Copy link
Copy Markdown
Member

Fixes: #101896

With #101647 we started using LR as a general purpose register when doing indirect calls and that broke our logic on NativeAOT that detects whether a thread is in an epilog on linux-arm64

Using LR as a GPR is not illegal, just something that we did not do before, so once we see LR (or FP) loaded with some value, the epilog detection logic assumes that we are in an epilog.

Long-term (and assuming that some platforms will never learn how to unwind in epilogs), I think we should encode the epilog ranges. In GC info, I suppose. It will not be trivial as there could be more than one epilog in a method, so encoding them all and then searching through them to answer IsUnwindable question could be a bit tricky. However, it will be a more portable approach.

For now we can have a simpler fix - we do not have to use LR for indirect call targets, so let's not use it.
It seems like REG_INDIRECT_CALL_TARGET_REG is a better fit for this.

@ghostghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 6, 2024
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

@VSadov
VSadov requested a review from jakobbotschMay 6, 2024 17:30
#ifdef TARGET_ARM
// For arm32 we've allocated an internal register to load the target into.
// Loading into lr takes 4 bytes (instead of potentially 2 with another register).
// Loading into IP takes 4 bytes (instead of potentially 2 with another register).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a register called this on arm32?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Yes (IP/r12 I think), but i think it cannot be loaded in 2byte instr

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah, I wasn't aware of that alias. R12 would be problematic to use anyway because we use it as an argument register in a bunch of a cases.

@jakobbotschjakobbotsch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks! I was not aware that we cannot use LR as a GPR. Is that just a coreclr constraint or a more general property for arm64?

For arm32, we definitely use LR as a scratch register in more cases (REG_SCRATCH is defined as REG_LR). Is that problematic?

@VSadov

VSadov commented May 6, 2024

Copy link
Copy Markdown
MemberAuthor

Thanks! I was not aware that we cannot use LR as a GPR

That is not illegal. It is just was not done before and at the time when the epilog detection heuristic was introduced, we assumed it will not be needed in the future. We had a small discussion about that.

For arm32, we definitely use LR as a scratch register in more cases.

Not sure how that is handled. Either Arm32 can unwind in epilog (unlikely), or has more complex heuristic that looks for actual epilog patterns.
On arm64 we could get away with just looking for LR/FP loads vs. something that is never in an epilog (calls, branches...).

I've logged a bug to replace this practice with something more robust - like storing the epilog ranges in GC info.
#101932

@VSadov

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-nativeaot-outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@VSadov

Copy link
Copy Markdown
MemberAuthor

All tests are green, including NativeAOT outer loop.

I will add a commit with a comment about current dependency on LR not being a GPR.

@VSadov
VSadov merged commit e1c6717 into dotnet:mainMay 7, 2024
@VSadov
VSadov deleted the fix101896 branch May 7, 2024 06:20
@VSadov

Copy link
Copy Markdown
MemberAuthor

Thanks!!!

michaelgsharp pushed a commit to michaelgsharp/runtime that referenced this pull request May 9, 2024
…101927)
* Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64
* Added a comment about NativeAOT dependency at the place wehre we exclude LR from availableIntRegs
Ruihan-Yin pushed a commit to Ruihan-Yin/runtime that referenced this pull request May 30, 2024
…101927)
* Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64
* Added a comment about NativeAOT dependency at the place wehre we exclude LR from availableIntRegs
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 6, 2024
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR 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.

[NativeAOT/linux-arm64] AF: codeManager->IsUnwindable(pvAddress) || runtime->IsConservativeStackReportingEnabled()

2 participants

@VSadov@jakobbotsch
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64 - #101927

Merged
VSadov merged 2 commits into
dotnet:mainfrom
VSadov:fix101896
May 7, 2024
Merged

Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64#101927
VSadov merged 2 commits into
dotnet:mainfrom
VSadov:fix101896

Conversation

@VSadov

@VSadovVSadov commented May 6, 2024

Copy link
Copy Markdown
Member

Fixes: #101896

With #101647 we started using LR as a general purpose register when doing indirect calls and that broke our logic on NativeAOT that detects whether a thread is in an epilog on linux-arm64

Using LR as a GPR is not illegal, just something that we did not do before, so once we see LR (or FP) loaded with some value, the epilog detection logic assumes that we are in an epilog.

Long-term (and assuming that some platforms will never learn how to unwind in epilogs), I think we should encode the epilog ranges. In GC info, I suppose. It will not be trivial as there could be more than one epilog in a method, so encoding them all and then searching through them to answer IsUnwindable question could be a bit tricky. However, it will be a more portable approach.

For now we can have a simpler fix - we do not have to use LR for indirect call targets, so let's not use it.
It seems like REG_INDIRECT_CALL_TARGET_REG is a better fit for this.

@ghostghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 6, 2024
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

@VSadov
VSadov requested a review from jakobbotschMay 6, 2024 17:30
#ifdef TARGET_ARM
// For arm32 we've allocated an internal register to load the target into.
// Loading into lr takes 4 bytes (instead of potentially 2 with another register).
// Loading into IP takes 4 bytes (instead of potentially 2 with another register).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a register called this on arm32?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Yes (IP/r12 I think), but i think it cannot be loaded in 2byte instr

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah, I wasn't aware of that alias. R12 would be problematic to use anyway because we use it as an argument register in a bunch of a cases.

@jakobbotschjakobbotsch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks! I was not aware that we cannot use LR as a GPR. Is that just a coreclr constraint or a more general property for arm64?

For arm32, we definitely use LR as a scratch register in more cases (REG_SCRATCH is defined as REG_LR). Is that problematic?

@VSadov

VSadov commented May 6, 2024

Copy link
Copy Markdown
MemberAuthor

Thanks! I was not aware that we cannot use LR as a GPR

That is not illegal. It is just was not done before and at the time when the epilog detection heuristic was introduced, we assumed it will not be needed in the future. We had a small discussion about that.

For arm32, we definitely use LR as a scratch register in more cases.

Not sure how that is handled. Either Arm32 can unwind in epilog (unlikely), or has more complex heuristic that looks for actual epilog patterns.
On arm64 we could get away with just looking for LR/FP loads vs. something that is never in an epilog (calls, branches...).

I've logged a bug to replace this practice with something more robust - like storing the epilog ranges in GC info.
#101932

@VSadov

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-nativeaot-outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@VSadov

Copy link
Copy Markdown
MemberAuthor

All tests are green, including NativeAOT outer loop.

I will add a commit with a comment about current dependency on LR not being a GPR.

@VSadov
VSadov merged commit e1c6717 into dotnet:mainMay 7, 2024
@VSadov
VSadov deleted the fix101896 branch May 7, 2024 06:20
@VSadov

Copy link
Copy Markdown
MemberAuthor

Thanks!!!

michaelgsharp pushed a commit to michaelgsharp/runtime that referenced this pull request May 9, 2024
…101927)
* Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64
* Added a comment about NativeAOT dependency at the place wehre we exclude LR from availableIntRegs
Ruihan-Yin pushed a commit to Ruihan-Yin/runtime that referenced this pull request May 30, 2024
…101927)
* Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64
* Added a comment about NativeAOT dependency at the place wehre we exclude LR from availableIntRegs
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 6, 2024
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR 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.

[NativeAOT/linux-arm64] AF: codeManager->IsUnwindable(pvAddress) || runtime->IsConservativeStackReportingEnabled()

2 participants

@VSadov@jakobbotsch
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64 - #101927

Merged
VSadov merged 2 commits into
dotnet:mainfrom
VSadov:fix101896
May 7, 2024
Merged

Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64#101927
VSadov merged 2 commits into
dotnet:mainfrom
VSadov:fix101896

Conversation

@VSadov

@VSadovVSadov commented May 6, 2024

Copy link
Copy Markdown
Member

Fixes: #101896

With #101647 we started using LR as a general purpose register when doing indirect calls and that broke our logic on NativeAOT that detects whether a thread is in an epilog on linux-arm64

Using LR as a GPR is not illegal, just something that we did not do before, so once we see LR (or FP) loaded with some value, the epilog detection logic assumes that we are in an epilog.

Long-term (and assuming that some platforms will never learn how to unwind in epilogs), I think we should encode the epilog ranges. In GC info, I suppose. It will not be trivial as there could be more than one epilog in a method, so encoding them all and then searching through them to answer IsUnwindable question could be a bit tricky. However, it will be a more portable approach.

For now we can have a simpler fix - we do not have to use LR for indirect call targets, so let's not use it.
It seems like REG_INDIRECT_CALL_TARGET_REG is a better fit for this.

@ghostghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 6, 2024
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

@VSadov
VSadov requested a review from jakobbotschMay 6, 2024 17:30
#ifdef TARGET_ARM
// For arm32 we've allocated an internal register to load the target into.
// Loading into lr takes 4 bytes (instead of potentially 2 with another register).
// Loading into IP takes 4 bytes (instead of potentially 2 with another register).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a register called this on arm32?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Yes (IP/r12 I think), but i think it cannot be loaded in 2byte instr

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah, I wasn't aware of that alias. R12 would be problematic to use anyway because we use it as an argument register in a bunch of a cases.

@jakobbotschjakobbotsch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks! I was not aware that we cannot use LR as a GPR. Is that just a coreclr constraint or a more general property for arm64?

For arm32, we definitely use LR as a scratch register in more cases (REG_SCRATCH is defined as REG_LR). Is that problematic?

@VSadov

VSadov commented May 6, 2024

Copy link
Copy Markdown
MemberAuthor

Thanks! I was not aware that we cannot use LR as a GPR

That is not illegal. It is just was not done before and at the time when the epilog detection heuristic was introduced, we assumed it will not be needed in the future. We had a small discussion about that.

For arm32, we definitely use LR as a scratch register in more cases.

Not sure how that is handled. Either Arm32 can unwind in epilog (unlikely), or has more complex heuristic that looks for actual epilog patterns.
On arm64 we could get away with just looking for LR/FP loads vs. something that is never in an epilog (calls, branches...).

I've logged a bug to replace this practice with something more robust - like storing the epilog ranges in GC info.
#101932

@VSadov

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-nativeaot-outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@VSadov

Copy link
Copy Markdown
MemberAuthor

All tests are green, including NativeAOT outer loop.

I will add a commit with a comment about current dependency on LR not being a GPR.

@VSadov
VSadov merged commit e1c6717 into dotnet:mainMay 7, 2024
@VSadov
VSadov deleted the fix101896 branch May 7, 2024 06:20
@VSadov

Copy link
Copy Markdown
MemberAuthor

Thanks!!!

michaelgsharp pushed a commit to michaelgsharp/runtime that referenced this pull request May 9, 2024
…101927)
* Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64
* Added a comment about NativeAOT dependency at the place wehre we exclude LR from availableIntRegs
Ruihan-Yin pushed a commit to Ruihan-Yin/runtime that referenced this pull request May 30, 2024
…101927)
* Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64
* Added a comment about NativeAOT dependency at the place wehre we exclude LR from availableIntRegs
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 6, 2024
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR 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.

[NativeAOT/linux-arm64] AF: codeManager->IsUnwindable(pvAddress) || runtime->IsConservativeStackReportingEnabled()

2 participants

@VSadov@jakobbotsch
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64 - #101927

Merged
VSadov merged 2 commits into
dotnet:mainfrom
VSadov:fix101896
May 7, 2024
Merged

Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64#101927
VSadov merged 2 commits into
dotnet:mainfrom
VSadov:fix101896

Conversation

@VSadov

@VSadovVSadov commented May 6, 2024

Copy link
Copy Markdown
Member

Fixes: #101896

With #101647 we started using LR as a general purpose register when doing indirect calls and that broke our logic on NativeAOT that detects whether a thread is in an epilog on linux-arm64

Using LR as a GPR is not illegal, just something that we did not do before, so once we see LR (or FP) loaded with some value, the epilog detection logic assumes that we are in an epilog.

Long-term (and assuming that some platforms will never learn how to unwind in epilogs), I think we should encode the epilog ranges. In GC info, I suppose. It will not be trivial as there could be more than one epilog in a method, so encoding them all and then searching through them to answer IsUnwindable question could be a bit tricky. However, it will be a more portable approach.

For now we can have a simpler fix - we do not have to use LR for indirect call targets, so let's not use it.
It seems like REG_INDIRECT_CALL_TARGET_REG is a better fit for this.

@ghostghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 6, 2024
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

@VSadov
VSadov requested a review from jakobbotschMay 6, 2024 17:30
#ifdef TARGET_ARM
// For arm32 we've allocated an internal register to load the target into.
// Loading into lr takes 4 bytes (instead of potentially 2 with another register).
// Loading into IP takes 4 bytes (instead of potentially 2 with another register).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a register called this on arm32?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Yes (IP/r12 I think), but i think it cannot be loaded in 2byte instr

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah, I wasn't aware of that alias. R12 would be problematic to use anyway because we use it as an argument register in a bunch of a cases.

@jakobbotschjakobbotsch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks! I was not aware that we cannot use LR as a GPR. Is that just a coreclr constraint or a more general property for arm64?

For arm32, we definitely use LR as a scratch register in more cases (REG_SCRATCH is defined as REG_LR). Is that problematic?

@VSadov

VSadov commented May 6, 2024

Copy link
Copy Markdown
MemberAuthor

Thanks! I was not aware that we cannot use LR as a GPR

That is not illegal. It is just was not done before and at the time when the epilog detection heuristic was introduced, we assumed it will not be needed in the future. We had a small discussion about that.

For arm32, we definitely use LR as a scratch register in more cases.

Not sure how that is handled. Either Arm32 can unwind in epilog (unlikely), or has more complex heuristic that looks for actual epilog patterns.
On arm64 we could get away with just looking for LR/FP loads vs. something that is never in an epilog (calls, branches...).

I've logged a bug to replace this practice with something more robust - like storing the epilog ranges in GC info.
#101932

@VSadov

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-nativeaot-outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@VSadov

Copy link
Copy Markdown
MemberAuthor

All tests are green, including NativeAOT outer loop.

I will add a commit with a comment about current dependency on LR not being a GPR.

@VSadov
VSadov merged commit e1c6717 into dotnet:mainMay 7, 2024
@VSadov
VSadov deleted the fix101896 branch May 7, 2024 06:20
@VSadov

Copy link
Copy Markdown
MemberAuthor

Thanks!!!

michaelgsharp pushed a commit to michaelgsharp/runtime that referenced this pull request May 9, 2024
…101927)
* Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64
* Added a comment about NativeAOT dependency at the place wehre we exclude LR from availableIntRegs
Ruihan-Yin pushed a commit to Ruihan-Yin/runtime that referenced this pull request May 30, 2024
…101927)
* Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64
* Added a comment about NativeAOT dependency at the place wehre we exclude LR from availableIntRegs
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 6, 2024
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR 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.

[NativeAOT/linux-arm64] AF: codeManager->IsUnwindable(pvAddress) || runtime->IsConservativeStackReportingEnabled()

2 participants

@VSadov@jakobbotsch
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64 - #101927

Merged
VSadov merged 2 commits into
dotnet:mainfrom
VSadov:fix101896
May 7, 2024
Merged

Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64#101927
VSadov merged 2 commits into
dotnet:mainfrom
VSadov:fix101896

Conversation

@VSadov

@VSadovVSadov commented May 6, 2024

Copy link
Copy Markdown
Member

Fixes: #101896

With #101647 we started using LR as a general purpose register when doing indirect calls and that broke our logic on NativeAOT that detects whether a thread is in an epilog on linux-arm64

Using LR as a GPR is not illegal, just something that we did not do before, so once we see LR (or FP) loaded with some value, the epilog detection logic assumes that we are in an epilog.

Long-term (and assuming that some platforms will never learn how to unwind in epilogs), I think we should encode the epilog ranges. In GC info, I suppose. It will not be trivial as there could be more than one epilog in a method, so encoding them all and then searching through them to answer IsUnwindable question could be a bit tricky. However, it will be a more portable approach.

For now we can have a simpler fix - we do not have to use LR for indirect call targets, so let's not use it.
It seems like REG_INDIRECT_CALL_TARGET_REG is a better fit for this.

@ghostghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 6, 2024
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

@VSadov
VSadov requested a review from jakobbotschMay 6, 2024 17:30
#ifdef TARGET_ARM
// For arm32 we've allocated an internal register to load the target into.
// Loading into lr takes 4 bytes (instead of potentially 2 with another register).
// Loading into IP takes 4 bytes (instead of potentially 2 with another register).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a register called this on arm32?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Yes (IP/r12 I think), but i think it cannot be loaded in 2byte instr

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah, I wasn't aware of that alias. R12 would be problematic to use anyway because we use it as an argument register in a bunch of a cases.

@jakobbotschjakobbotsch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks! I was not aware that we cannot use LR as a GPR. Is that just a coreclr constraint or a more general property for arm64?

For arm32, we definitely use LR as a scratch register in more cases (REG_SCRATCH is defined as REG_LR). Is that problematic?

@VSadov

VSadov commented May 6, 2024

Copy link
Copy Markdown
MemberAuthor

Thanks! I was not aware that we cannot use LR as a GPR

That is not illegal. It is just was not done before and at the time when the epilog detection heuristic was introduced, we assumed it will not be needed in the future. We had a small discussion about that.

For arm32, we definitely use LR as a scratch register in more cases.

Not sure how that is handled. Either Arm32 can unwind in epilog (unlikely), or has more complex heuristic that looks for actual epilog patterns.
On arm64 we could get away with just looking for LR/FP loads vs. something that is never in an epilog (calls, branches...).

I've logged a bug to replace this practice with something more robust - like storing the epilog ranges in GC info.
#101932

@VSadov

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-nativeaot-outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@VSadov

Copy link
Copy Markdown
MemberAuthor

All tests are green, including NativeAOT outer loop.

I will add a commit with a comment about current dependency on LR not being a GPR.

@VSadov
VSadov merged commit e1c6717 into dotnet:mainMay 7, 2024
@VSadov
VSadov deleted the fix101896 branch May 7, 2024 06:20
@VSadov

Copy link
Copy Markdown
MemberAuthor

Thanks!!!

michaelgsharp pushed a commit to michaelgsharp/runtime that referenced this pull request May 9, 2024
…101927)
* Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64
* Added a comment about NativeAOT dependency at the place wehre we exclude LR from availableIntRegs
Ruihan-Yin pushed a commit to Ruihan-Yin/runtime that referenced this pull request May 30, 2024
…101927)
* Use REG_INDIRECT_CALL_TARGET_REG for indirect calls on arm64
* Added a comment about NativeAOT dependency at the place wehre we exclude LR from availableIntRegs
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 6, 2024
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR 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.

[NativeAOT/linux-arm64] AF: codeManager->IsUnwindable(pvAddress) || runtime->IsConservativeStackReportingEnabled()

2 participants

@VSadov@jakobbotsch