<div dir="ltr"><div>Hi Eliot,<div>What we must do is correctly infer the type that we generate.</div></div><div>Computing the type of (1 << anything) as int is correct if that is what we generate.</div><div><br></div><div>If it indeed overflows, then we must cast to VM word sqInt at code generation and indeed infer</div><div>(((sqInt) 1) << anything) as sqInt.</div><div>But this is invoking UB and potentially many -O compiler problems if left operand is negative.</div><div>So I think that we do generate this foolish (but recommended) expression:</div><div>((sqInt)(((usqInt) x) << anything))</div><div>and must we infer that type to sqInt. Maybe we have another path for constants...<br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le sam. 22 févr. 2020 à 05:34, Eliot Miranda <<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> <div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">Hi Nicolas, Hi Clément, Hi Pierre, Hi All,<div><br></div><div>    I'm working again on ARMv8 having got confused and with help clear headed again.  So I'm getting the real system to run (it displays the full desktop before crashing).  One issue is the IMO mis-typing of #<<.</div><div><br></div><div>The expression in question is</div><div><span style="white-space:pre-wrap">  </span>1 << (cogit coInterpreter highBit: cogit methodZone zoneEnd)</div><div>which is used to determine a type for mask:</div><div><div><span style="white-space:pre-wrap">  </span>mask := 1 << (cogit coInterpreter highBit: cogit methodZone zoneEnd) - dataCacheMinLineLength.</div></div><div><br></div><div><br></div><div>In Smalltalk this evaluates to something large, and in the real VM it should evaluate to 1 << 39.  However, because in CCodeGenerator>>returnTypeForSend:in:ifNil: we explicitly assume C semantics here:</div><div><br></div><div><div><span style="white-space:pre-wrap">    </span>^kernelReturnTypes</div><div><span style="white-space:pre-wrap">               </span>at: sel</div><div><span style="white-space:pre-wrap">          </span>ifAbsent:</div><div><span style="white-space:pre-wrap">                        </span>[sel</div><div><span style="white-space:pre-wrap">                             </span>caseOf: {</div><div><span style="white-space:pre-wrap">                                ...</span></div><div><span style="white-space:pre-wrap">                              </span>"C99 Sec Bitwise shift operators ... 3 Semantics ...</div><div><span style="white-space:pre-wrap">                                </span> The integer promotions are performed on each of the operands.</div><div><span style="white-space:pre-wrap">                           </span> The type of the result is that of the promoted left operand..."</div><div><span style="white-space:pre-wrap">                           </span>[#>>]<span style="white-space:pre-wrap">     </span>-><span style="white-space:pre-wrap">   </span>[sendNode receiver typeFrom: self in: aTMethod].</div><div><span style="white-space:pre-wrap">                         </span>[#<<]<span style="white-space:pre-wrap">     </span>-><span style="white-space:pre-wrap">   </span>[sendNode receiver typeFrom: self in: aTMethod].</div><div><br></div><div>we compute the ty<font face="arial, sans-serif">pe of <span style="color:rgb(0,0,0)">1 <<</span><font color="#000000"><span> anything to be #int, and hence the type of mask to be int, and hence mask is both truncated to 32-bits and later extended to 64-bits by virtue of being passed as an argument to a #sqInt parameter. So instead of generating the mask </span></font></font>16r7FFFFFFFC0 we generate the mask 16rFFFFFFFFFFFFFFC0.  Clearly nonsense.</div><div><br></div><div>It seems to me that we have the wrong philosophy.  In CCodeGenerator>>returnTypeForSend:in:ifNil: we should be computing types that cause the generated C to mimic as closely as possible what happens in Smalltalk, *not* typing according to the C99 standard, which creates unintended incompatibilities between the simulated Slang and the generated Slang.</div><div><br></div><div>Surely what we should be doing for << is seeing if the right operand is a constant and if so typing according to that, but in general typing << as #sqInt or #usqInt, depending on the type of the left operand.  This is what Smalltalk does; left-shifting a signed value preserves the sign; left shifting a non-negative value always yields a non-negative value.  Yes, eventually we will truncate to the word size, but the word size is sqInt, not int, and we are familiar with the truncation issue.</div><div><br></div><div>The mistyping of << as int is unexpected and extremely inconvenient.  We force the Slang programmer to type all variables receiving the result of a << explicitly.</div><div><br></div><div>Do you agree or does my way lead to chaos?</div><div><br></div><div dir="ltr"><div dir="ltr"><div><span style="border-collapse:separate"><div><font face="arial, sans-serif">_,,,^..^,,,_</font><br></div><div style="font-size:small">best, Eliot</div></span></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div>
</blockquote></div>