Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7956 Discussions

SHIFT LEFT BY 64 does not result in ZERO

Murari
Employee
1,587 Views

 

#include <iostream>

int main()
{
unsigned long long kk = 64, Mask, i;

//When you use constant to shift left by 64 it always result in Zero but then you use it using variable it //result 1. In debug mode this is 1 all the time but in release mode value outside the loop comes zero //whereas value inside loop become 0. It seems compiler issue

Mask = (0x1ull << 0x40ll);
printf("Out-1 %d\n", Mask);

Mask = (0x1ull << kk);
printf("Out-2 %d\n", Mask);

for (int i = 1; i < 256; i++) {
Mask = 0x1ull << kk;
printf("Loop %d = %d\n", i, Mask);
}
std::cout << "Hello World!\n";
}

0 Kudos
12 Replies
GouthamK_Intel
Moderator
1,566 Views

Hi Murari,

Thanks for reaching out to us!

Could you please provide your system environment details?

OS Version

Compiler details and Version


Thanks & Regards

Goutham


0 Kudos
Murari
Employee
1,552 Views

Hi Goutham, are you from compiler team?  

I thought it can be reproduced on all system (in 64 bit mode) but so far I have tested it on my laptop which is Kaby Lake U and I have also tested it on SKX and ICX system. In debug mode this issue is more reproducible than release mode. Sometime in release mode it only happens when this code is inside loop.

Interesting thing is that shift left with constant value works but when you do same using variable than it does not work. 

 

0 Kudos
Murari
Employee
1,551 Views

Sorry here are more detail

OS - Windows 10.

Win Server 2019

 

Used latest compiler 19.x

0 Kudos
Viet_H_Intel
Moderator
1,557 Views

This looks like an overflow issue. You can only shift by 63.

Thanks,


0 Kudos
Viet_H_Intel
Moderator
1,542 Views

Hi,

Did you see any warning from the compiler? What are the results you get with cl?

Thanks,


0 Kudos
Murari
Employee
1,536 Views

I see only one warning in the very first line where I am using constant value of 64 to shift left . Although it works all the time .

What is cl? I am using visual studio.

Severity Code Description Project File Line Suppression State
Warning C4293 '<<': shift count negative or too big, undefined behavior ConsoleApplication1 c:\users\administrator\source\repos\consoleapplication1\consoleapplication1\consoleapplication1.cpp 13

 

 

0 Kudos
Viet_H_Intel
Moderator
1,533 Views

cl is Microsoft Compiler. From the warning you provided:

1) The warning came from Microsoft compiler not Intel compiler.

2) You have an overflow, undefined behavior.


If you wanted to shift by 64, you should have code as:

unsigned long long kk = 63, Mask, i;

Mask = (0x1ull << 0x3fll);




0 Kudos
MWind2
New Contributor III
1,512 Views

I tried this on VC and had to use 

unsigned long long ull0 = 1;
unsigned long long ull1 = (ull0 << 0x3f) << 1;

but I wonder why not use

ull0 = 1;
ull1 = ull0 ^ ull0;

 

0 Kudos
Murari
Employee
1,504 Views

It looks like for 64 bit number you can only shift up to 63 times similarly for 32 bit number you can shift up to 31 bit otherwise result will be undefined.  

0 Kudos
nemequ
New Contributor I
1,489 Views

Yep; in C17 the relevant part of the standard is § 6.5.7 ¶ 3:


The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.


C++17 also has a similar passage in § 8.8:


The operands shall be of integral or unscoped enumeration type and integral promotions are performed. The type of the result is that of the promoted left operand. The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.

FWIW, I believe UBSan will warn about this.

0 Kudos
Viet_H_Intel
Moderator
1,476 Views

Hi Murari,

Can we close this thread?

Thanks,


0 Kudos
Murari
Employee
1,474 Views

Yes,

 

Thanks for your support.

0 Kudos
Reply