[x86] Make copies of odd-size structs
authorCarol Eidt <carol.eidt@microsoft.com>
Fri, 4 Jan 2019 22:32:34 +0000 (14:32 -0800)
committerCarol Eidt <carol.eidt@microsoft.com>
Fri, 4 Jan 2019 23:21:23 +0000 (15:21 -0800)
PR #21304 inadvertently disabled this code for x86.
This led to AV failures on desktop, but the same code silently loads
the larger size on coreclr without AV'ing.
Add an assert that we don't see this kind of node in x86 codegen.

src/jit/codegenxarch.cpp
src/jit/morph.cpp

index cf9055c..fdd3fab 100644 (file)
@@ -5303,6 +5303,12 @@ void CodeGen::genCallInstruction(GenTreeCall* call)
                 {
                     GenTreeObj* obj      = source->AsObj();
                     unsigned    argBytes = roundUp(obj->gtBlkSize, TARGET_POINTER_SIZE);
+#ifdef _TARGET_X86_
+                    // If we have an OBJ, we must have created a copy if the original arg was not a
+                    // local and was not a multiple of TARGET_POINTER_SIZE.
+                    // Note that on x64/ux this will be handled by unrolling in genStructPutArgUnroll.
+                    assert((argBytes == obj->gtBlkSize) || obj->Addr()->IsLocalAddrExpr());
+#endif // _TARGET_X86_
                     assert((curArgTabEntry->numSlots * TARGET_POINTER_SIZE) == argBytes);
                 }
 #endif // FEATURE_PUT_STRUCT_ARG_STK
index 09c6fc7..f1fe1b3 100644 (file)
@@ -3831,7 +3831,6 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call)
             unsigned  roundupSize    = (unsigned)roundUp(originalSize, TARGET_POINTER_SIZE);
             var_types structBaseType = argEntry->argType;
 
-#ifndef _TARGET_X86_
             // First, handle the case where the argument is passed by reference.
             if (argEntry->passedByRef)
             {
@@ -3844,6 +3843,9 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call)
             else
             {
                 // This is passed by value.
+                CLANG_FORMAT_COMMENT_ANCHOR;
+
+#ifndef _TARGET_X86_
                 // Check to see if we can transform this into load of a primitive type.
                 // 'size' must be the number of pointer sized items
                 assert(size == roundupSize / TARGET_POINTER_SIZE);
@@ -4053,6 +4055,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call)
 
                     size = 1;
                 }
+#endif // !_TARGET_X86_
 
 #ifndef UNIX_AMD64_ABI
                 // We still have a struct unless we converted the GT_OBJ into a GT_IND above...
@@ -4087,7 +4090,6 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call)
                 }
 #endif // !UNIX_AMD64_ABI
             }
-#endif // !_TARGET_X86_
         }
 
         if (argEntry->isPassedInRegisters())