Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

[Arm64] Pr jit acquire release simple cases#12087

Merged
CarolEidt merged 5 commits intodotnet:masterfrom
sdmaclea:PR-JIT-AcquireRelease-SimpleCases
Jun 8, 2017
Merged

[Arm64] Pr jit acquire release simple cases#12087
CarolEidt merged 5 commits intodotnet:masterfrom
sdmaclea:PR-JIT-AcquireRelease-SimpleCases

Conversation

@sdmaclea
Copy link
Copy Markdown

@sdmaclea sdmaclea commented Jun 5, 2017

No description provided.

@sdmaclea
Copy link
Copy Markdown
Author

sdmaclea commented Jun 5, 2017

@dotnet/arm64-contrib @dotnet/jit-contrib

if (code & 0x00800000) // Is this a sign-extending opcode? (i.e. ldrsw, ldrsh, ldrsb)
bool exclusive = ((code & 0x35000000) == 0);

if ((code & 0x00800000) && !exclusive) // Is this a sign-extending opcode? (i.e. ldrsw, ldrsh, ldrsb)
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The original code was not fully decoding whether this was a sign extending load.

Acquire/Release are in the exclusive group which does not support sign extending forms. So this is needed to correctly generate some of the store release forms..

The decode here is still incomplete, but it is sufficient for our current set of generated instructions. I might expect similar issues when we try to support ARM 8.1 atomics...

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

OK

// issue a full memory barrier a before volatile StInd
instGen_MemoryBarrier();
bool useStoreRelease = (dataReg >= REG_INT_FIRST) && (dataReg <= REG_ZR) && !addr->isContained() &&
((attr == EA_1BYTE) || !(tree->gtFlags & GTF_IND_UNALIGNED));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Isn't there already a method that validates that we have a General purpose register that we can use for this ?
(dataReg >= REG_INT_FIRST) && (dataReg <= REG_ZR)

We don't want to bake in the fact that REG_ZR has the largest enum value for a general purpose register in this code.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It also should not be possible to have the case of an "unaligned" 1 byte load/store.
A check could be added when we decide to set that flag.

Copy link
Copy Markdown
Author

@sdmaclea sdmaclea Jun 5, 2017

Choose a reason for hiding this comment

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

Looks like genIsValidIntReg(regNumber reg) is a direct replacement. I'll use that unless you strongly prefer not float.

It also should not be possible to have the case of an "unaligned" 1 byte load/store.
A check could be added when we decide to set that flag.

My original code added an assert unaligned not set on byte size code which triggered on some of the directed volatile prefix tests.

Since Unaligned is a IL prefix, I think we do not remove the prefix in import. I expect some of the directed volatile prefix tests set the unaligned flag on byte sized load/store. We can add code to clear the flag during import for byte sized ops. I do not think the prefix on a byte load/store is explicitly illegal IL, so ignoring it would be the best course of action IMO.

Either way I'll remove the special case here.

instGen_MemoryBarrier(INS_BARRIER_LD);
GenTree* addr = tree->Addr();
bool useLoadAcquire = (targetReg >= REG_INT_FIRST) && (targetReg <= REG_ZR) && !addr->isContained() &&
varTypeIsUnsigned(targetType) &&
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I think that the register check can be changed to a check that targetType is not a floating point type.

@sdmaclea
Copy link
Copy Markdown
Author

sdmaclea commented Jun 5, 2017

@briansull This should address your comments.

}
}

if (prefixFlags & PREFIX_UNALIGNED)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I don't understand the code that follow this, so I would just leave this line alone.

But you also might want to correct the broken indention here...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This code just sets the GTF_IND_UNALIGNED if it is not using a helper.

Not sure what indentation is broken. clang-format was happy with it. Perhaps you missed the discontinuityin the patch line numbers?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Yeah, The diff does have a big discontinuity in the line numbers. I have never seen that before.
Makes it hard to code review.

op1->gtFlags |= GTF_IND_VOLATILE;
}
if (prefixFlags & PREFIX_UNALIGNED)
if ((prefixFlags & PREFIX_UNALIGNED) && !varTypeIsByte(lclTyp))
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This change is fine, as we just want to set things up so that we don't set GTF_IND_UNALIGNED when we have a byte sized indirection

@@ -13594,7 +13594,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
op1->gtFlags |= GTF_ORDER_SIDEEFF; // Prevent this from being reordered
op1->gtFlags |= GTF_IND_VOLATILE;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It seems unnecessary to me to set these two flags when we see a UNALIGNED prefix, but that isn't part of your change.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Those are set when we see a VOLATILE prefix.

@sdmaclea
Copy link
Copy Markdown
Author

sdmaclea commented Jun 6, 2017

@dotnet-bot test Ubuntu arm Cross Release Build

@sdmaclea
Copy link
Copy Markdown
Author

sdmaclea commented Jun 8, 2017

Please merge

@CarolEidt CarolEidt merged commit 1a6c1d1 into dotnet:master Jun 8, 2017
@sdmaclea sdmaclea deleted the PR-JIT-AcquireRelease-SimpleCases branch August 1, 2017 17:58
@jashook
Copy link
Copy Markdown

jashook commented Aug 15, 2017

@sdmaclea the assert you added here is firing. It seems to me like it may be too restrictive. Is the assert: assert((attr != EA_1BYTE) || !(tree->gtFlags & GTF_IND_UNALIGNED)); meant for the volatile case or in general?

@sdmaclea
Copy link
Copy Markdown
Author

@jashook it was meant for the general case. The GTF_IND_UNALIGNED flag is not supposed to be set on EA_1BYTE objects because they can by definition never be unaligned.

If the assertion is removed the volatile code will have to be changed. the correct fix would be to not set the Unaligned flag for these objects.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants