aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/loongarch
diff options
context:
space:
mode:
authorLulu Cheng <chenglulu@loongson.cn>2022-06-27 16:26:25 +0800
committerLulu Cheng <chenglulu@loongson.cn>2022-06-29 14:43:37 +0800
commit43653547e7c8da2cd861bceb4a3e4bd338787ced (patch)
tree5ceae88828d4f0a36774914bad8785dab44cf64f /gcc/config/loongarch
parentb93ae1a01bbad59ee77b7c84f4743a730138ba87 (diff)
downloadgcc-43653547e7c8da2cd861bceb4a3e4bd338787ced.zip
gcc-43653547e7c8da2cd861bceb4a3e4bd338787ced.tar.gz
gcc-43653547e7c8da2cd861bceb4a3e4bd338787ced.tar.bz2
LoongArch: Remove undefined behavior from code [PR 106097]
C++2017 and previous standard description: The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-filled. If E1 has an unsigned type, the value of the result is E1×2E2, reduced modulo one more than the maximum value representable inthe result type. Otherwise, if E1 has a signed type and non-negative value, and E1×2E2 is representablein the corresponding unsigned type of the result type, then that value, converted to the result type, is the resulting value; otherwise, the behavior is undefined. The value of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a non-negative value, the value of the result is the integral part of the quotient of E1/2E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined. gcc/ChangeLog: PR target/106097 * config/loongarch/loongarch.cc (loongarch_build_integer): Remove undefined behavior from code.
Diffstat (limited to 'gcc/config/loongarch')
-rw-r--r--gcc/config/loongarch/loongarch.cc11
1 files changed, 6 insertions, 5 deletions
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index c8502b0..48d9ccd 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -160,7 +160,7 @@ enum loongarch_load_imm_method
struct loongarch_integer_op
{
enum rtx_code code;
- unsigned HOST_WIDE_INT value;
+ HOST_WIDE_INT value;
enum loongarch_load_imm_method method;
};
@@ -1468,7 +1468,7 @@ loongarch_build_integer (struct loongarch_integer_op *codes,
unsigned int cost = 0;
/* Get the lower 32 bits of the value. */
- HOST_WIDE_INT low_part = TARGET_64BIT ? value << 32 >> 32 : value;
+ HOST_WIDE_INT low_part = (int32_t)value;
if (IMM12_OPERAND (low_part) || IMM12_OPERAND_UNSIGNED (low_part))
{
@@ -1502,6 +1502,7 @@ loongarch_build_integer (struct loongarch_integer_op *codes,
bool lu52i[2] = {(value & LU52I_B) == 0, (value & LU52I_B) == LU52I_B};
int sign31 = (value & (1UL << 31)) >> 31;
+ int sign51 = (value & (1UL << 51)) >> 51;
/* Determine whether the upper 32 bits are sign-extended from the lower
32 bits. If it is, the instructions to load the high order can be
ommitted. */
@@ -1512,12 +1513,12 @@ loongarch_build_integer (struct loongarch_integer_op *codes,
else if (lu32i[sign31])
{
codes[cost].method = METHOD_LU52I;
- codes[cost].value = (value >> 52) << 52;
+ codes[cost].value = value & LU52I_B;
return cost + 1;
}
codes[cost].method = METHOD_LU32I;
- codes[cost].value = ((value << 12) >> 44) << 32;
+ codes[cost].value = (value & LU32I_B) | (sign51 ? LU52I_B : 0);
cost++;
/* Determine whether the 52-61 bits are sign-extended from the low order,
@@ -1525,7 +1526,7 @@ loongarch_build_integer (struct loongarch_integer_op *codes,
if (!lu52i[(value & (1ULL << 51)) >> 51])
{
codes[cost].method = METHOD_LU52I;
- codes[cost].value = (value >> 52) << 52;
+ codes[cost].value = value & LU52I_B;
cost++;
}
}