diff options
author | Harald Anlauf <anlauf@gmx.de> | 2019-06-14 18:41:20 +0000 |
---|---|---|
committer | Harald Anlauf <anlauf@gcc.gnu.org> | 2019-06-14 18:41:20 +0000 |
commit | d0442491d506497f9c7e8bfa6f0e9edb16d21306 (patch) | |
tree | c3615319bcfcff103f8bbc0cd88ef23de4955beb /gcc/fortran/trans-intrinsic.c | |
parent | a8566e938ca4c6d5c8a631397e15216d0d6a720f (diff) | |
download | gcc-d0442491d506497f9c7e8bfa6f0e9edb16d21306.zip gcc-d0442491d506497f9c7e8bfa6f0e9edb16d21306.tar.gz gcc-d0442491d506497f9c7e8bfa6f0e9edb16d21306.tar.bz2 |
re PR fortran/90577 (FAIL: gfortran.dg/lrshift_1.f90 with -O(2|3) and -flto)
2019-06-14 Harald Anlauf <anlauf@gmx.de>
PR fortran/90577
PR fortran/90578
* trans-intrinsic.c (gfc_conv_intrinsic_shift): Properly
distinguish logical/arithmetic shifts.
* intrinsic.texi: Update documentation for SHIFTR/SHIFTL/SHIFTA
(Fortran 2008) and LSHIFT/RSHIFT (GNU extensions).
PR fortran/90577
PR fortran/90578
* gfortran.dg/lrshift_1.f90: Adjust testcase.
* gfortran.dg/shiftalr_3.f90: New testcase.
From-SVN: r272309
Diffstat (limited to 'gcc/fortran/trans-intrinsic.c')
-rw-r--r-- | gcc/fortran/trans-intrinsic.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index f6edd68..cc041f9 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -6346,6 +6346,7 @@ gfc_conv_intrinsic_shift (gfc_se * se, gfc_expr * expr, bool right_shift, bool arithmetic) { tree args[2], type, num_bits, cond; + tree bigshift; gfc_conv_intrinsic_function_args (se, expr, args, 2); @@ -6365,6 +6366,18 @@ gfc_conv_intrinsic_shift (gfc_se * se, gfc_expr * expr, bool right_shift, if (!arithmetic) se->expr = fold_convert (type, se->expr); + if (!arithmetic) + bigshift = build_int_cst (type, 0); + else + { + tree nonneg = fold_build2_loc (input_location, GE_EXPR, + logical_type_node, args[0], + build_int_cst (TREE_TYPE (args[0]), 0)); + bigshift = fold_build3_loc (input_location, COND_EXPR, type, nonneg, + build_int_cst (type, 0), + build_int_cst (type, -1)); + } + /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas gcc requires a shift width < BIT_SIZE(I), so we have to catch this special case. */ @@ -6373,7 +6386,7 @@ gfc_conv_intrinsic_shift (gfc_se * se, gfc_expr * expr, bool right_shift, args[1], num_bits); se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond, - build_int_cst (type, 0), se->expr); + bigshift, se->expr); } /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i)) |