Skip to content

Conversation

@minad
Copy link
Member

@minad minad commented Apr 4, 2019

any reasonably intelligent compiler will optimize the loop away

ping @nijtmans @sjaeckel

@minad
Copy link
Member Author

minad commented Apr 4, 2019

Same for mp_get_long. But this is open for discussion. The compilers I am using optimize such things. And for more stupid compilers this will just result in one additional untaken branch. It is hardly worth the extra code.

@nijtmans
Copy link
Collaborator

nijtmans commented Apr 4, 2019

Well, I think the Travis build will show why this specialization was necessary ;-)

@minad
Copy link
Member Author

minad commented Apr 4, 2019

Ok, I am curious. I didn't test it. Is there an overflow issue or something?

@nijtmans
Copy link
Collaborator

nijtmans commented Apr 4, 2019

Hint: the "<<" operator cannot shift more than the size of the data-type.

@minad
Copy link
Member Author

minad commented Apr 4, 2019

Can it happen that DIGIT_SIZE > 8*sizeof(long)? Isn't shifting by the size of the datatype well defined?
Or is only shifting by size-1 well defined?

I think I just compiled the unspecialized version and my compiler did not warn. But maybe I used a different digit size. I will check.

@minad minad changed the title remove mp_set_long specialization Discussion: remove mp_set_long specialization Apr 4, 2019
@nijtmans
Copy link
Collaborator

nijtmans commented Apr 4, 2019

Can it happen that DIGIT_SIZE > 8*sizeof(long)? Isn't shifting by the size of the datatype well defined?
Or is only shifting by size-1 well defined?

It can happen that sizeof(long)==4 and DIGIT_SIZE == 60. So, the answer is Yes, unfortunately.

@nijtmans
Copy link
Collaborator

nijtmans commented Apr 4, 2019

bn_mp_set_long.c: In function ‘mp_set_long’:
bn_mp_set_long.c:15:1: warning: right shift count >= width of type [enabled by default]
MP_SET_XLONG(mp_set_long, unsigned long)
^
ar: creating libtommath.a
The command "./testme.sh ${BUILDOPTIONS}" exited with 128.

@minad
Copy link
Member Author

minad commented Apr 4, 2019

@nijtmans Ok to merge then? With the shifting fix the generated code is equivalent to the specialized code.

@minad minad requested a review from nijtmans April 4, 2019 13:04
minad added 2 commits April 4, 2019 15:11
any reasonably intelligent compiler will optimize the loop away
@minad minad force-pushed the simplify-set-long branch from 5234d44 to 7c5e889 Compare April 4, 2019 13:11
Copy link
Collaborator

@nijtmans nijtmans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm OK with this change.

@czurnieden
Copy link
Contributor

As far as I remember : we need to make everything explicit here at LTM, including operator precedence, which means parentheses around 8 * sizeof (b). Also: no magick numbers, use CHAR_BIT instead. Please think of all the innocent DPSs which need to squeeze much more bits into each byte! ;-)

@minad
Copy link
Member Author

minad commented Apr 4, 2019

@sjaeckel ready to merge :)

while (b != 0u) { \
a->dp[x++] = ((mp_digit)b & MP_MASK); \
b >>= DIGIT_BIT; \
if (CHAR_BIT * sizeof (b) <= DIGIT_BIT) { break; } \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just writing this comment while you pushed the change...

my question is if it is really CHAR_BIT as suggested by @czurnieden or if 8 is correct...

I think of platforms like some DSP's where CHAR_BIT is 16 or 32

I guess the 8 must stay, but I'm not 100% sure yet and I've to leave...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, probably. Since sizeof always counts bytes??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we have sizeof*CHAR_BIT at other places too. Then we would have to remove all of those and replace with 8.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to stackoverflow, sizeof is always bytes. https://stackoverflow.com/questions/11868211/does-sizeof-return-the-number-of-bytes-or-the-number-of-octets-of-a-type-in-c

Therefore the usage of CHAR_BIT is wrong at many places in tommath. I can fix this in a separate PR if you wish.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah and bytes are implementation defined. Hehe. This is shit.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sjaeckel Please merge as is and we resolve the CHAR_BIT question in a separate PR. If we want to resolve it...

Copy link
Contributor

@czurnieden czurnieden Apr 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah and bytes are implementation defined. Hehe. This is shit.

Oh, yes! *deep sigh*

To quote the standard (ISO/IEC 9899:2011 (E). I'm still too stingy to get the new one)

3.6
1 byte
addressable unit of data storage large enough to hold any member of the basic character set of the execution environment
2 NOTE 1 It is possible to express the address of each individual byte of an object uniquely.
3 NOTE 2 A byte is composed of a contiguous sequence of bits, the number of which is implementation-defined. The least significant bit is called the low-order bit; the most significant bit is called the high-order bit.
(emphasis mine)

But also

6.5.3.4 The sizeof and _Alignof operators

2 The sizeof operator yields the size (in bytes) of its operand, […]
4 When sizeof is applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1.

So you can get the size of a byte with all standard compliant compilers where it is in CHAR_BIT. But what is with all of the non-standard compliant compilers? They are not supported, you said? Well, we really need a list of supported ones somewhere in a place where we can point at it if somebody wants to blame us for the problems one of the many crappy c-compilers out there gave them.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok at least CHAR_BIT=BYTES_BIT. Then it is correct as it is now :)

minad and others added 2 commits April 4, 2019 17:21
(size_t)XXX". The (size_t) cast doesn't add anything here.
@nijtmans
Copy link
Collaborator

nijtmans commented Apr 4, 2019

Well, I see the construct "sizeof(yyy) * (size_t) CHAR_BIT" in a lot of places. To me the (size_t) cast doesn't add anything here: since sizeof() already returns a size_t, what's wrong with multiplying that to an "int", giving a size_t result? As I read the C-spec, usages of CHAR_BIT is correct here. It could be 8, 16 or whatever.

@minad
Copy link
Member Author

minad commented Apr 4, 2019

@nijtmans While I don't have anything against you or other collaborators editing my PRs, I would prefer if you keep create a separate PR for the separate issue you observed. Nevertheless, I also didn't like these unnecessary size_t casts and would like to see them gone 👍

@minad
Copy link
Member Author

minad commented Apr 4, 2019

@nijtmans Since I am messing with your code, I guess it is ok ;) I am just trying to ease it a bit for @sjaeckel such that he can quickly merge things step by step.

@nijtmans
Copy link
Collaborator

nijtmans commented Apr 4, 2019

So, it looks like we are in full agreement here! ;-)

@nijtmans
Copy link
Collaborator

nijtmans commented Apr 4, 2019

Since this PR already has 5 commits, I think @sjaeckel will want us to do this commit again anyway, to keep a clean history in GIT. Well, then we can split it, now we know how it should look like. But if @sjaeckel accepts it as-is that would be easier for us. For me 5 commits like this is acceptable.

minad added 2 commits April 4, 2019 22:36
Still not activated by default since demo.c has many issues.
Furthermore there are issues in the system headers due to Wsystem-headers.
@minad
Copy link
Member Author

minad commented Apr 4, 2019

@nijtmans I suggest to split this into two cleaned-up PRs. One for the mp_set_long specialization and the second one fixing the casts etc. Do you agree?

@nijtmans
Copy link
Collaborator

nijtmans commented Apr 4, 2019

I agree with splitting this into 2 PR's. Thanks for the -Wconversion and -Wsign-conversion fixes. It looks like I was too rigid in the (size_t) removals ;-)

@minad
Copy link
Member Author

minad commented Apr 4, 2019

Shall I do the split?

@nijtmans
Copy link
Collaborator

nijtmans commented Apr 4, 2019

Yes, go ahead! I'll put my approval there!

@minad
Copy link
Member Author

minad commented Apr 4, 2019

Closing in favour of #199 and #200

@minad minad closed this Apr 4, 2019
@sjaeckel sjaeckel deleted the simplify-set-long branch April 5, 2019 07:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants