[Arm64] Pr jit acquire release simple cases#12087
Conversation
|
@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) |
There was a problem hiding this comment.
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...
src/jit/codegenarm64.cpp
Outdated
| // 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)); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
src/jit/codegenarmarch.cpp
Outdated
| instGen_MemoryBarrier(INS_BARRIER_LD); | ||
| GenTree* addr = tree->Addr(); | ||
| bool useLoadAcquire = (targetReg >= REG_INT_FIRST) && (targetReg <= REG_ZR) && !addr->isContained() && | ||
| varTypeIsUnsigned(targetType) && |
There was a problem hiding this comment.
I think that the register check can be changed to a check that targetType is not a floating point type.
|
@briansull This should address your comments. |
| } | ||
| } | ||
|
|
||
| if (prefixFlags & PREFIX_UNALIGNED) |
There was a problem hiding this comment.
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...
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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)) |
There was a problem hiding this comment.
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; | |||
There was a problem hiding this comment.
It seems unnecessary to me to set these two flags when we see a UNALIGNED prefix, but that isn't part of your change.
There was a problem hiding this comment.
Those are set when we see a VOLATILE prefix.
|
@dotnet-bot test Ubuntu arm Cross Release Build |
|
Please merge |
|
@sdmaclea the assert you added here is firing. It seems to me like it may be too restrictive. Is the assert: |
|
@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. |
No description provided.