Skip to content

Commit f4dc588

Browse files
authored
Fix interpreter double and 64 bit constant processing (#116115)
There is a bug in extracting 64 bit and double constants on both the interpreter compiler and execution sides. The problem was that the lower 32 bits were extracted as signed 32 bit int and then casted to signed 64 bit int and or-ed to the other 32 bits shifted up. The problem is that when the lower 32 bits were signed, the sign got extended to the upper 32 bits and the combined result was incorrect. This fixes 24 codegen bringup tests with the interpreter that were previously failing with "Assert.Equal() Failure: Values differ".
1 parent ddf67a7 commit f4dc588

File tree

2 files changed

+3
-3
lines changed

2 files changed

+3
-3
lines changed

src/coreclr/interpreter/intops.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ inline int32_t getI4LittleEndian(const uint8_t* ptr)
9898

9999
inline int64_t getI8LittleEndian(const uint8_t* ptr)
100100
{
101-
return (int64_t)getI4LittleEndian(ptr) | ((int64_t)getI4LittleEndian(ptr + 4)) << 32;
101+
return (int64_t)getU4LittleEndian(ptr) | ((int64_t)getI4LittleEndian(ptr + 4)) << 32;
102102
}
103103

104104
inline float getR4LittleEndian(const uint8_t* ptr)

src/coreclr/vm/interpexec.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,15 +143,15 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr
143143
ip += 2;
144144
break;
145145
case INTOP_LDC_I8:
146-
LOCAL_VAR(ip[1], int64_t) = (int64_t)ip[2] + ((int64_t)ip[3] << 32);
146+
LOCAL_VAR(ip[1], int64_t) = (int64_t)(uint32_t)ip[2] + ((int64_t)ip[3] << 32);
147147
ip += 4;
148148
break;
149149
case INTOP_LDC_R4:
150150
LOCAL_VAR(ip[1], int32_t) = ip[2];
151151
ip += 3;
152152
break;
153153
case INTOP_LDC_R8:
154-
LOCAL_VAR(ip[1], int64_t) = (int64_t)ip[2] + ((int64_t)ip[3] << 32);
154+
LOCAL_VAR(ip[1], int64_t) = (int64_t)(uint32_t)ip[2] + ((int64_t)ip[3] << 32);
155155
ip += 4;
156156
break;
157157
case INTOP_LDPTR:

0 commit comments

Comments
 (0)