[m-rev.] for review: make unchecked shifts by uint amounts builtin, step 1

Julien Fischer jfischer at opturion.com
Thu Apr 30 17:26:49 AEST 2020


On Thu, 30 Apr 2020, Zoltan Somogyi wrote:

> On Thu, 30 Apr 2020 17:06:27 +1000 (AEST), Julien Fischer <jfischer at opturion.com> wrote:
>>> compiler/erl_call_gen.m:
>>>     Don't treat unchecked shifts by uint amounts as builtins, since I (zs)
>>>     don't know how this should be done in Erlang.
>>
>> I wouldn't worry too much about the Erlang backend; it's currently lacking
>> a lot of support for non-int integer types anyway.
>
> I agree, though I didn't think this diff to erl_call_gen.m exhibited any such worry :-)
>
>>> diff --git a/compiler/llds_out_data.m b/compiler/llds_out_data.m
>>> index 92ba641fe..d0148ae2c 100644
>>> --- a/compiler/llds_out_data.m
>>> +++ b/compiler/llds_out_data.m
>>> @@ -1178,16 +1178,22 @@ output_rval(Info, Rval, !IO) :-
>>>              output_rval_as_type(Info, SubRvalB, lt_int(int_type_int), !IO),
>>>              io.write_string(")", !IO)
>>>          ;
>>> -            % The second operand of the shift operatators always has type
>>> -            % `int'.
>>> -            ( Op = unchecked_left_shift(IntType), OpStr = "<<"
>>> -            ; Op = unchecked_right_shift(IntType), OpStr = ">>"
>>> +            % The second operand of the shift operators always has type
>>> +            % `int' in C, but Mercury also allows it to be uint.
>>
>> The second operand of a shift in C can have any integral type.
>
> I suspected as much, but my copy of K&R is packed away, and I couldn't find
> any confirmation of this online among the avalanche of search results that
> all focused on explaining the difference between int and uint in the LEFT
> operands of shift operators, but never discussed the issue in the RIGHT
> operands.

The most relevant online search is something like "C11 draft standard".
(The final drafts of the ISO standards for most recent versions of C are
all online; for nearly all purposes they're identical to the published
ones.)

The C standard spends most of its time discussing the first operand of
the shift operators as well.

>> (Obviously,
>> for the behaviour to be defined the second operand must have a value that
>> is non-negative and within the bit size of the first operand.)  Or do
>> you mean that we always generate shift expressions so that their second
>> operand has type int?
>
> That's what the code I have now. I guess I could undo all the code additions
> that look like this:
>
>>> +            ( Op = unchecked_left_shift(IntType, ShiftType), OpStr = "<<"
>>> +            ; Op = unchecked_right_shift(IntType, ShiftType), OpStr = ">>"
>>>              ),
>>>              io.write_string("(", !IO),
>>>              output_rval_as_type(Info, SubRvalA, lt_int(IntType), !IO),
>>>              io.write_string(" ", !IO),
>>>              io.write_string(OpStr, !IO),
>>>              io.write_string(" ", !IO),
>>> +            (
>>> +                ShiftType = shift_by_int
>>> +            ;
>>> +                ShiftType = shift_by_uint,
>>> +                io.write_string("(int) ", !IO)
>>> +            ),
>>>              output_rval_as_type(Info, SubRvalB, lt_int(int_type_int), !IO),
>>>              io.write_string(")", !IO)
>
> as unnecessary, but then shifts are so rare that it does not really matter.

I'm not particularly fussed about it, that's why I didn't request you
change it.

Julien.


More information about the reviews mailing list