-
Notifications
You must be signed in to change notification settings - Fork 5k
default(T)
produces non-optimized code in contrast to new T()
on (generic) value types when the instance is not used
#51825
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
Comments
I guess it's related to the Your two examples gives IL output like New:
Default (notice the
Actually, if you explicitly store that
[JitGeneric(typeof(One))]
public int Local<T>() where T : struct, IValue
{
T local = default;
return local.Value;
} So it's probably not the runtime's issue but the compiler's. Also it would be easier to make the compiler not to emit the |
Yep, it is the [ 0] 0 (0x000) ldloca.s 0
[ 1] 2 (0x002) dup
STMT00000 (IL 0x000... ???)
[000003] -A---------- * ASG byref
[000002] D------N---- +--* LCL_VAR byref V03 tmp1
[000001] ------------ \--* ADDR byref
[000000] -------N---- \--* LCL_VAR struct<S, 1> V01 loc0
[ 2] 3 (0x003) initobj 02000003
STMT00001 (IL ???... ???)
[000008] IA---------- * ASG struct (init)
[000007] -------N---- +--* BLK struct<1>
[000005] ------------ | \--* LCL_VAR byref V03 tmp1
[000006] ------------ \--* CNS_INT int 0
[ 1] 9 (0x009) call 0A000008
STMT00002 (IL ???... ???)
[000009] I-C-G------- * CALL int S.Value (exactContextHnd=0x00000000D1FFAB1E)
[000004] ------------ this in rcx \--* LCL_VAR byref V03 tmp1 While for the case when we have a local as the source: [ 0] 0 (0x000) ldloca.s 0
[ 1] 2 (0x002) initobj 02000003
STMT00000 (IL 0x000... ???)
[000003] IA---------- * ASG struct (init)
[000000] D------N---- +--* LCL_VAR struct<S, 1> V01 loc0
[000002] ------------ \--* CNS_INT int 0
[ 0] 8 (0x008) ldloca.s 0
[ 1] 10 (0x00a) call 0A000008
STMT00001 (IL 0x008... ???)
[000006] I-C-G------- * CALL int S.Value (exactContextHnd=0x00000000D1FFAB1E)
[000005] ------------ this in rcx \--* ADDR byref
[000004] -------N---- \--* LCL_VAR struct<S, 1> V01 loc0 The difference in how My thinking on the direction of the fix is along the lines of importing |
I guess it's one of those issues where Forward-Sub could help us again 🙂 to substitute that local so the peephole optimization could fold GT_BLK |
Address of local should not be considered "too complex to clone". Seems like the dup logic should be willing to use the same heuristic that |
Description
The runtime is not optimizing the instantiation of a struct (by
default
) when it's actually not used at all (due to optimizations of the code that make the instance not required).The following minimal snippet:
Produces this JIT asm:
The expected code generation of
C.Default[[One, _]]()
was the same asC.New[[One, _]]()
.Configuration
Run on SharpLab (Core CLR v5.0.421.11614 on x86) on release mode.
Regression?
Don't know. Sorry.
Other information
No idea how to fix it. Sorry.
Though you currently can use
new T()
instead ofdefault(T)
to get the optimized code as a workaround.By the way, I noticed the generated code is optimized if the type is actually returned to the caller.
For example:
Produces:
Or when it's used as a parameter to another function (even if the function is actually inlined):
Produces:
Or if the instance is mutated:
Produces:
So, I think the problem only happens when an instance is created but not returned, passed as parameter nor mutated.
category:cq
theme:generics
skill-level:intermediate
cost:medium
impact:small
The text was updated successfully, but these errors were encountered: