From 8390c7212facecf4cad72a8ec7c74ff54cdf8d8d Mon Sep 17 00:00:00 2001 From: Mike Danes Date: Sat, 4 Feb 2017 12:14:54 +0200 Subject: [PATCH] Fix incorrect cast in gtFoldExprConst The fact that an operation is unsigned affects the operation itself but that doesn't mean that the result of the operation is also unsigned. Constants are stored as ssize_t and the node type is TYP_INT so the result has to be sign extended, not zero extended. Otherwise code that uses the return of IconValue() without first narrowing it to int will behave incorrectly. Such code does exists, even gtFoldExprConst does this when folding shift operations: uint a = uint.MaxValue; uint b = 0; int r = (int)checked(a + b); Console.WriteLine((r >> 2).ToString("X")); The above code prints 3FFFFFFF instead of the expected FFFFFFFF. This also makes gtFoldExprConst consistent with ValueNumStore::EvalFuncForConstantArgs which evaluates TYP_INT nodes as int and then casts to ssize_t. Commit migrated from https://github.com/dotnet/coreclr/commit/176e2c7964846bf5dea22557f0828475deac05e1 --- src/coreclr/src/jit/gentree.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index 7af500f..539df23 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/src/jit/gentree.cpp @@ -13410,15 +13410,10 @@ GenTreePtr Compiler::gtFoldExprConst(GenTreePtr tree) #endif #ifdef _TARGET_64BIT_ - // we need to properly re-sign-extend or truncate as needed. - if (tree->gtFlags & GTF_UNSIGNED) - { - i1 = UINT32(i1); - } - else - { - i1 = INT32(i1); - } + // Some operations are performed as 64 bit instead of 32 bit so the upper 32 bits + // need to be discarded. Since constant values are stored as ssize_t and the node + // has TYP_INT the result needs to be sign extended rather than zero extended. + i1 = INT32(i1); #endif // _TARGET_64BIT_ /* Also all conditional folding jumps here since the node hanging from -- 2.7.4