diff options
author | Jakub Jelinek <jakub@redhat.com> | 2024-10-29 09:06:25 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2024-10-29 09:06:25 +0100 |
commit | 972f653cad2aedcfa901614566506c1c2e668766 (patch) | |
tree | 49c17bb7190fbf3777de58d816c46d4665c2f9d9 /gcc/c/c-fold.cc | |
parent | 87fa88222ff0c7f8b2ca3a480f41fc4e826cdf32 (diff) | |
download | gcc-972f653cad2aedcfa901614566506c1c2e668766.zip gcc-972f653cad2aedcfa901614566506c1c2e668766.tar.gz gcc-972f653cad2aedcfa901614566506c1c2e668766.tar.bz2 |
c: Add __builtin_stdc_rotate_{left,right} builtins [PR117030]
I believe the new C2Y <stdbit.h> type-generic functions
stdc_rotate_{left,right} have the same problems the other stdc_*
type-generic functions had. If we want to support arbitrary
unsigned _BitInt(N), don't want to use statement expressions
(so that one can actually use them in static variable initializers),
don't want to evaluate the arguments multiple times and don't want
to expand the arguments multiple times during preprocessing to avoid the
old tgmath preprocessing bloat, we need a built-in for those.
The following patch adds those. And as we need to support rotations by 0
and tree-ssa-forwprop.cc is only able to pattern recognize with BIT_AND_EXPR
for that case (i.e. for power of two widths), the patch just constructs
LROTATE_EXPR/RROTATE_EXPR right away. Negative second arguments are
considered UB, while positive ones are modulo precision.
2024-10-29 Jakub Jelinek <jakub@redhat.com>
PR c/117030
gcc/
* doc/extend.texi (__builtin_stdc_rotate_left,
__builtin_stdc_rotate_right): Document.
gcc/c-family/
* c-common.cc (c_common_reswords): Add __builtin_stdc_rotate_left
and __builtin_stdc_rotate_right.
* c-ubsan.cc (ubsan_instrument_shift): For {L,R}ROTATE_EXPR
just check if op1 is negative.
gcc/c/
* c-parser.cc: Include asan.h and c-family/c-ubsan.h.
(c_parser_postfix_expression): Handle __builtin_stdc_rotate_left
and __builtin_stdc_rotate_right.
* c-fold.cc (c_fully_fold_internal): Handle LROTATE_EXPR and
RROTATE_EXPR.
gcc/testsuite/
* gcc.dg/builtin-stdc-rotate-1.c: New test.
* gcc.dg/builtin-stdc-rotate-2.c: New test.
* gcc.dg/ubsan/builtin-stdc-rotate-1.c: New test.
* gcc.dg/ubsan/builtin-stdc-rotate-2.c: New test.
Diffstat (limited to 'gcc/c/c-fold.cc')
-rw-r--r-- | gcc/c/c-fold.cc | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/gcc/c/c-fold.cc b/gcc/c/c-fold.cc index 06085f5..deb6896 100644 --- a/gcc/c/c-fold.cc +++ b/gcc/c/c-fold.cc @@ -328,6 +328,8 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, case EXACT_DIV_EXPR: case LSHIFT_EXPR: case RSHIFT_EXPR: + case LROTATE_EXPR: + case RROTATE_EXPR: case BIT_IOR_EXPR: case BIT_XOR_EXPR: case BIT_AND_EXPR: @@ -389,7 +391,10 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, && tree_int_cst_sgn (op0) < 0) warning_at (loc, OPT_Wshift_negative_value, "left shift of negative value"); - if ((code == LSHIFT_EXPR || code == RSHIFT_EXPR) + if ((code == LSHIFT_EXPR + || code == RSHIFT_EXPR + || code == LROTATE_EXPR + || code == RROTATE_EXPR) && TREE_CODE (orig_op1) != INTEGER_CST && TREE_CODE (op1) == INTEGER_CST && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE |