https://gcc.gnu.org/g:11b09c5f9babc07d72ae3e07cbdeb11286c881b4
commit 11b09c5f9babc07d72ae3e07cbdeb11286c881b4 Author: Thomas Koenig <tkoe...@gcc.gnu.org> Date: Sun Aug 4 20:14:34 2024 +0200 Add bit_size, btest and bgt plus friends. Diff: --- gcc/fortran/check.cc | 66 ++++++++++++++++++++++-------- gcc/fortran/intrinsic.cc | 2 +- gcc/fortran/simplify.cc | 47 +++++++++++++++++---- gcc/testsuite/gfortran.dg/unsigned_8.f90 | 70 ++++++++++++++++++++++++++++++++ 4 files changed, 160 insertions(+), 25 deletions(-) diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc index 5cfae6182c3b..1a8f601ce838 100644 --- a/gcc/fortran/check.cc +++ b/gcc/fortran/check.cc @@ -2015,11 +2015,36 @@ gfc_check_bge_bgt_ble_blt (gfc_expr *i, gfc_expr *j) && !gfc_boz2int (j, i->ts.kind)) return false; - if (!type_check (i, 0, BT_INTEGER)) - return false; + if (flag_unsigned) + { + /* If i is BOZ and j is UNSIGNED, convert i to type of j. */ + if (i->ts.type == BT_BOZ && j->ts.type == BT_UNSIGNED + && !gfc_boz2uint (i, j->ts.kind)) + return false; - if (!type_check (j, 1, BT_INTEGER)) - return false; + /* If j is BOZ and i is UNSIGNED, convert j to type of i. */ + if (j->ts.type == BT_BOZ && i->ts.type == BT_UNSIGNED + && !gfc_boz2uint (j, i->ts.kind)) + return false; + + if (gfc_invalid_unsigned_ops (i,j)) + return false; + + if (!type_check2 (i, 0, BT_INTEGER, BT_UNSIGNED)) + return false; + + if (!type_check2 (j, 1, BT_INTEGER, BT_UNSIGNED)) + return false; + + } + else + { + if (!type_check (i, 0, BT_INTEGER)) + return false; + + if (!type_check (j, 1, BT_INTEGER)) + return false; + } return true; } @@ -2028,8 +2053,16 @@ gfc_check_bge_bgt_ble_blt (gfc_expr *i, gfc_expr *j) bool gfc_check_bitfcn (gfc_expr *i, gfc_expr *pos) { - if (!type_check (i, 0, BT_INTEGER)) - return false; + if (flag_unsigned) + { + if (!type_check2 (i, 0, BT_INTEGER, BT_UNSIGNED)) + return false; + } + else + { + if (!type_check (i, 0, BT_INTEGER)) + return false; + } if (!type_check (pos, 1, BT_INTEGER)) return false; @@ -3154,18 +3187,18 @@ gfc_check_iand_ieor_ior (gfc_expr *i, gfc_expr *j) && !gfc_boz2int (j, i->ts.kind)) return false; - /* If i is BOZ and j is UNSIGNED, convert i to type of j. */ - if (i->ts.type == BT_BOZ && j->ts.type == BT_UNSIGNED - && !gfc_boz2uint (i, j->ts.kind)) - return false; - - /* If j is BOZ and i is UNSIGNED, convert j to type of i. */ - if (j->ts.type == BT_BOZ && i->ts.type == BT_UNSIGNED - && !gfc_boz2uint (j, i->ts.kind)) - return false; - if (flag_unsigned) { + /* If i is BOZ and j is UNSIGNED, convert i to type of j. */ + if (i->ts.type == BT_BOZ && j->ts.type == BT_UNSIGNED + && !gfc_boz2uint (i, j->ts.kind)) + return false; + + /* If j is BOZ and i is UNSIGNED, convert j to type of i. */ + if (j->ts.type == BT_BOZ && i->ts.type == BT_UNSIGNED + && !gfc_boz2uint (j, i->ts.kind)) + return false; + if (gfc_invalid_unsigned_ops (i,j)) return false; @@ -3177,7 +3210,6 @@ gfc_check_iand_ieor_ior (gfc_expr *i, gfc_expr *j) } else { - if (!type_check (i, 0, BT_INTEGER)) return false; diff --git a/gcc/fortran/intrinsic.cc b/gcc/fortran/intrinsic.cc index 8dcdff9540a5..da4e9828dc8d 100644 --- a/gcc/fortran/intrinsic.cc +++ b/gcc/fortran/intrinsic.cc @@ -1661,7 +1661,7 @@ add_functions (void) make_generic ("bgt", GFC_ISYM_BGT, GFC_STD_F2008); add_sym_1 ("bit_size", GFC_ISYM_BIT_SIZE, CLASS_INQUIRY, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95, - gfc_check_i, gfc_simplify_bit_size, NULL, + gfc_check_iu, gfc_simplify_bit_size, NULL, i, BT_INTEGER, di, REQUIRED); make_generic ("bit_size", GFC_ISYM_BIT_SIZE, GFC_STD_F95); diff --git a/gcc/fortran/simplify.cc b/gcc/fortran/simplify.cc index e00ebb6e4d19..1818dc5956cc 100644 --- a/gcc/fortran/simplify.cc +++ b/gcc/fortran/simplify.cc @@ -1658,8 +1658,14 @@ gfc_expr * gfc_simplify_bit_size (gfc_expr *e) { int i = gfc_validate_kind (e->ts.type, e->ts.kind, false); - return gfc_get_int_expr (e->ts.kind, &e->where, - gfc_integer_kinds[i].bit_size); + int bit_size; + + if (flag_unsigned && e->ts.type == BT_UNSIGNED) + bit_size = gfc_unsigned_kinds[i].bit_size; + else + bit_size = gfc_integer_kinds[i].bit_size; + + return gfc_get_int_expr (e->ts.kind, &e->where, bit_size); } @@ -1709,47 +1715,74 @@ compare_bitwise (gfc_expr *i, gfc_expr *j) gfc_expr * gfc_simplify_bge (gfc_expr *i, gfc_expr *j) { + bool result; + if (i->expr_type != EXPR_CONSTANT || j->expr_type != EXPR_CONSTANT) return NULL; + if (flag_unsigned && i->ts.type == BT_UNSIGNED) + result = mpz_cmp (i->value.integer, j->value.integer) >= 0; + else + result = compare_bitwise (i, j) >= 0; + return gfc_get_logical_expr (gfc_default_logical_kind, &i->where, - compare_bitwise (i, j) >= 0); + result); } gfc_expr * gfc_simplify_bgt (gfc_expr *i, gfc_expr *j) { + bool result; + if (i->expr_type != EXPR_CONSTANT || j->expr_type != EXPR_CONSTANT) return NULL; + if (flag_unsigned && i->ts.type == BT_UNSIGNED) + result = mpz_cmp (i->value.integer, j->value.integer) > 0; + else + result = compare_bitwise (i, j) > 0; + return gfc_get_logical_expr (gfc_default_logical_kind, &i->where, - compare_bitwise (i, j) > 0); + result); } gfc_expr * gfc_simplify_ble (gfc_expr *i, gfc_expr *j) { + bool result; + if (i->expr_type != EXPR_CONSTANT || j->expr_type != EXPR_CONSTANT) return NULL; + if (flag_unsigned && i->ts.type == BT_UNSIGNED) + result = mpz_cmp (i->value.integer, j->value.integer) <= 0; + else + result = compare_bitwise (i, j) <= 0; + return gfc_get_logical_expr (gfc_default_logical_kind, &i->where, - compare_bitwise (i, j) <= 0); + result); } gfc_expr * gfc_simplify_blt (gfc_expr *i, gfc_expr *j) { + bool result; + if (i->expr_type != EXPR_CONSTANT || j->expr_type != EXPR_CONSTANT) return NULL; + if (flag_unsigned && i->ts.type == BT_UNSIGNED) + result = mpz_cmp (i->value.integer, j->value.integer) < 0; + else + result = compare_bitwise (i, j) < 0; + return gfc_get_logical_expr (gfc_default_logical_kind, &i->where, - compare_bitwise (i, j) < 0); + result); } - gfc_expr * gfc_simplify_ceiling (gfc_expr *e, gfc_expr *k) { diff --git a/gcc/testsuite/gfortran.dg/unsigned_8.f90 b/gcc/testsuite/gfortran.dg/unsigned_8.f90 new file mode 100644 index 000000000000..f23056ab3bb9 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/unsigned_8.f90 @@ -0,0 +1,70 @@ +! { dg-do run } +! { dg-options "-funsigned" } +! Test bit_size, btest and bgt plus friends. +program main + implicit none + unsigned :: u + integer :: i, j + unsigned :: ui, uj + logical:: test_i, test_u + if (bit_size(u) /= 32) error stop 1 + if (.not. btest(32,5)) error stop 2 + if (btest(32,4)) error stop 3 + u = 32u + if (btest(u,4)) error stop 4 + do i=1,3 + ui = uint(i) + do j=1,3 + uj = uint(j) + test_i = blt(i,j) + test_u = blt(ui,uj) + if (test_i .neqv. test_u) error stop 5 + test_i = ble(i,j) + test_u = ble(ui,uj) + if (test_i .neqv. test_u) error stop 6 + test_i = bge(i,j) + test_u = bge(ui,uj) + if (test_i .neqv. test_u) error stop 7 + test_i = bgt(i,j) + test_u = bgt(ui,uj) + if (test_i .neqv. test_u) error stop 8 + end do + end do + if (blt (1, 1) .neqv. blt (1u, 1u)) error stop 8 + if (ble (1, 1) .neqv. ble (1u, 1u)) error stop 9 + if (bge (1, 1) .neqv. bge (1u, 1u)) error stop 10 + if (bgt (1, 1) .neqv. bgt (1u, 1u)) error stop 11 + if (blt (1, 2) .neqv. blt (1u, 2u)) error stop 12 + if (ble (1, 2) .neqv. ble (1u, 2u)) error stop 13 + if (bge (1, 2) .neqv. bge (1u, 2u)) error stop 14 + if (bgt (1, 2) .neqv. bgt (1u, 2u)) error stop 15 + if (blt (1, 3) .neqv. blt (1u, 3u)) error stop 16 + if (ble (1, 3) .neqv. ble (1u, 3u)) error stop 17 + if (bge (1, 3) .neqv. bge (1u, 3u)) error stop 18 + if (bgt (1, 3) .neqv. bgt (1u, 3u)) error stop 19 + if (blt (2, 1) .neqv. blt (2u, 1u)) error stop 20 + if (ble (2, 1) .neqv. ble (2u, 1u)) error stop 21 + if (bge (2, 1) .neqv. bge (2u, 1u)) error stop 22 + if (bgt (2, 1) .neqv. bgt (2u, 1u)) error stop 23 + if (blt (2, 2) .neqv. blt (2u, 2u)) error stop 24 + if (ble (2, 2) .neqv. ble (2u, 2u)) error stop 25 + if (bge (2, 2) .neqv. bge (2u, 2u)) error stop 26 + if (bgt (2, 2) .neqv. bgt (2u, 2u)) error stop 27 + if (blt (2, 3) .neqv. blt (2u, 3u)) error stop 28 + if (ble (2, 3) .neqv. ble (2u, 3u)) error stop 29 + if (bge (2, 3) .neqv. bge (2u, 3u)) error stop 30 + if (bgt (2, 3) .neqv. bgt (2u, 3u)) error stop 31 + if (blt (3, 1) .neqv. blt (3u, 1u)) error stop 32 + if (ble (3, 1) .neqv. ble (3u, 1u)) error stop 33 + if (bge (3, 1) .neqv. bge (3u, 1u)) error stop 34 + if (bgt (3, 1) .neqv. bgt (3u, 1u)) error stop 35 + if (blt (3, 2) .neqv. blt (3u, 2u)) error stop 36 + if (ble (3, 2) .neqv. ble (3u, 2u)) error stop 37 + if (bge (3, 2) .neqv. bge (3u, 2u)) error stop 38 + if (bgt (3, 2) .neqv. bgt (3u, 2u)) error stop 39 + if (blt (3, 3) .neqv. blt (3u, 3u)) error stop 40 + if (ble (3, 3) .neqv. ble (3u, 3u)) error stop 41 + if (bge (3, 3) .neqv. bge (3u, 3u)) error stop 42 + if (bgt (3, 3) .neqv. bgt (3u, 3u)) error stop 43 + +end