aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2024-03-27 19:38:06 +0100
committerJakub Jelinek <jakub@redhat.com>2024-03-27 19:39:18 +0100
commit4b0443361a82ef89d519c9ae6d4d3bec74376e8f (patch)
tree06bff8c7c340d074628fbf9550c2d52b07450642 /gcc/c-family
parentf85d3362cdb4bab611508dd9a38d9015c02ff7ca (diff)
downloadgcc-4b0443361a82ef89d519c9ae6d4d3bec74376e8f.zip
gcc-4b0443361a82ef89d519c9ae6d4d3bec74376e8f.tar.gz
gcc-4b0443361a82ef89d519c9ae6d4d3bec74376e8f.tar.bz2
c-family: Cast __atomic_load_*/__atomic_exchange_* result to _BitInt rather then VCE it [PR114469]
As written in the PR, torture/bitint-64.c test fails with -O2 -flto and the reason is that on _BitInt arches where the padding bits are undefined, the padding bits in the _Atomic vars are also undefined, but when __atomic_load or __atomic_exchange on a _BitInt _Atomic variable with some padding bits is lowered into __atomic_load_{1,2,4,8,16} or __atomic_exchange_*, the mode precision unsigned result is VIEW_CONVERT_EXPR converted to _BitInt and because of the VCE nothing actually sign/zero extends it as needed for later uses - the var is no longer addressable and expansion assumes such automatic vars are properly extended. The following patch fixes that by using NOP_EXPR on it (the VIEW_CONVERT_EXPR after it will then be optimized away during gimplification, didn't want to repeat it in the code as else result = build1 (VIEW_CONVERT_EXPR, ...); twice. 2024-03-27 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/114469 * c-common.cc (resolve_overloaded_builtin): For _BitInt result on !extended targets convert result to the _BitInt type before using VIEW_CONVERT_EXPR.
Diffstat (limited to 'gcc/c-family')
-rw-r--r--gcc/c-family/c-common.cc14
1 files changed, 13 insertions, 1 deletions
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 48844b1..6fa8243 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -8461,7 +8461,19 @@ resolve_overloaded_builtin (location_t loc, tree function,
if (new_return)
{
/* Cast function result from I{1,2,4,8,16} to the required type. */
- result = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (new_return), result);
+ if (TREE_CODE (TREE_TYPE (new_return)) == BITINT_TYPE)
+ {
+ struct bitint_info info;
+ unsigned prec = TYPE_PRECISION (TREE_TYPE (new_return));
+ targetm.c.bitint_type_info (prec, &info);
+ if (!info.extended)
+ /* For _BitInt which has the padding bits undefined
+ convert to the _BitInt type rather than VCE to force
+ zero or sign extension. */
+ result = build1 (NOP_EXPR, TREE_TYPE (new_return), result);
+ }
+ result
+ = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (new_return), result);
result = build2 (MODIFY_EXPR, TREE_TYPE (new_return), new_return,
result);
TREE_SIDE_EFFECTS (result) = 1;