From 57f514d09d3b879e238f37980456634e8286691c Mon Sep 17 00:00:00 2001 From: kaizhangNV <149626564+kaizhangNV@users.noreply.github.com> Date: Tue, 26 Mar 2024 11:05:00 -0700 Subject: Fix the sign-extending issue in right shift (#3820) Fix issue (#3637). In constant folding of a right shift operation,slang always uses signed interger as the operand no matter the input source code is signed or unsigned, this could causes sign-extending issue if the input source is unsigned integer with highest bit set to 1. Fix the issue by checking the original type of the input and use the unsigned type if the input is unsigned. --- tests/bugs/gh-3637.slang | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tests/bugs/gh-3637.slang (limited to 'tests') diff --git a/tests/bugs/gh-3637.slang b/tests/bugs/gh-3637.slang new file mode 100644 index 000000000..81aa58c73 --- /dev/null +++ b/tests/bugs/gh-3637.slang @@ -0,0 +1,26 @@ +//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-cuda -compute -output-using-type +//TEST(compute, vulkan):COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-vk -compute -output-using-type +//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-cpu -compute -output-using-type + +// CHECK: 9223372036854775808 +// CHECK: 1 +// CHECK: 18446744073709551615 + +// This tests exhibits a bug in constant folding in which the right shift +// operator unconditionally performs sign-extension. + +//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0], stride=8):out,name=outputBuffer +RWStructuredBuffer outputBuffer; + +[numthreads(1, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + const uint64_t topBitSet = 0x8000000000000000ull; + const uint64_t bottomBitSet = topBitSet >> 63; + const uint64_t allBitsSet = int64_t(topBitSet) >> 63; // expect sign-extending which will set all bits. + const uint64_t noBitsSet = topBitSet >> 64; // This exhibits undefined behaviour, as the compiler shifts right by at least the number of bits in the first operand + outputBuffer[0] = topBitSet; + outputBuffer[1] = bottomBitSet; + outputBuffer[2] = allBitsSet; + outputBuffer[3] = noBitsSet; +} -- cgit v1.2.3