[Bug fortran/90578] Wrong code with LSHIFT and optimization

2019-06-18 Thread anlauf at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90578

--- Comment #11 from anlauf at gcc dot gnu.org ---
Author: anlauf
Date: Tue Jun 18 20:21:47 2019
New Revision: 272437

URL: https://gcc.gnu.org/viewcvs?rev=272437=gcc=rev
Log:
2019-06-18  Harald Anlauf  

Backport from mainline
2019-06-14  Harald Anlauf  

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.

Added:
branches/gcc-9-branch/gcc/testsuite/gfortran.dg/shiftalr_3.f90
Modified:
branches/gcc-9-branch/gcc/fortran/ChangeLog
branches/gcc-9-branch/gcc/fortran/intrinsic.texi
branches/gcc-9-branch/gcc/fortran/trans-intrinsic.c
branches/gcc-9-branch/gcc/testsuite/ChangeLog
branches/gcc-9-branch/gcc/testsuite/gfortran.dg/lrshift_1.f90

[Bug fortran/90578] Wrong code with LSHIFT and optimization

2019-06-14 Thread anlauf at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90578

anlauf at gcc dot gnu.org changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |FIXED

--- Comment #10 from anlauf at gcc dot gnu.org ---
Testcase fixed to no longer invoke undefined behavior.

Documentation fixed, as well as arithmetic shifts which SHIFT=BIT_SIZE(arg1).

No runtime test for invalid SHIFT values.  Please open a separate PR if you
think this is important.

[Bug fortran/90578] Wrong code with LSHIFT and optimization

2019-06-14 Thread anlauf at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90578

--- Comment #9 from anlauf at gcc dot gnu.org ---
Author: anlauf
Date: Fri Jun 14 18:41:20 2019
New Revision: 272309

URL: https://gcc.gnu.org/viewcvs?rev=272309=gcc=rev
Log:
2019-06-14  Harald Anlauf  

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.

Added:
trunk/gcc/testsuite/gfortran.dg/shiftalr_3.f90
Modified:
trunk/gcc/fortran/ChangeLog
trunk/gcc/fortran/intrinsic.texi
trunk/gcc/fortran/trans-intrinsic.c
trunk/gcc/testsuite/ChangeLog
trunk/gcc/testsuite/gfortran.dg/lrshift_1.f90

[Bug fortran/90578] Wrong code with LSHIFT and optimization

2019-06-13 Thread anlauf at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90578

--- Comment #8 from anlauf at gcc dot gnu.org ---
Patch at https://gcc.gnu.org/ml/fortran/2019-06/msg00077.html

[Bug fortran/90578] Wrong code with LSHIFT and optimization

2019-06-01 Thread dominiq at lps dot ens.fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90578

--- Comment #7 from Dominique d'Humieres  ---
> Can you please explain what you expect?

As usual, the impossible;-)

More seriously:

(1) the test suite should not invoke undefined behavior, i.e., the test
gfortran.dg/lrshift_1.f90 should be fixed.

(2) The gfortran manual should be improved:

(a) In the entries SHIFTA, SHIFTL, and SHIFTR, 
"If the absolute value of SHIFT is greater than BIT_SIZE(I), the value is
undefined"
should be replaced with 
"SHIFT shall be nonnegative and less than or equal to BIT_SIZE (I)".
IMO the former wording suggest that SHIFT can be negative.

(b) LSHIFT and RSHIFT are extensions and should behave as in other compilers,
e.g., fort.

If the common behavior is that negative values of SHIFT are rejected, the
manual should be changed as in (a).

(3) It would nice to have a run-time check.

[Bug fortran/90578] Wrong code with LSHIFT and optimization

2019-05-30 Thread anlauf at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90578

--- Comment #6 from anlauf at gcc dot gnu.org ---
(In reply to Dominique d'Humieres from comment #5)
> Compiling
> 
> print *, lshift(1,-1)
> end
> 
> gives the following error
> 
> lshift.f90:1:16:
> 
> 1 | print *, lshift(1,-1)
>   |1
> Error: Second argument of LSHIFT is negative at (1)
> 
> While
> 
> print *, ishft(2,-1)
> end
> 
> gives
> 
>1

Can you please explain what you expect?

Keep the current implementation, where negative shifts are disallowed for
lshift/rshift?  Then fix the documentation, explaining that negative shifts
have undefined behavior.  Related testcases in the testsuite need to be fixed.

Or allow negative shifts, as in ishft?

[Bug fortran/90578] Wrong code with LSHIFT and optimization

2019-05-30 Thread dominiq at lps dot ens.fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90578

--- Comment #5 from Dominique d'Humieres  ---
Compiling

print *, lshift(1,-1)
end

gives the following error

lshift.f90:1:16:

1 | print *, lshift(1,-1)
  |1
Error: Second argument of LSHIFT is negative at (1)

While

print *, ishft(2,-1)
end

gives

   1

[Bug fortran/90578] Wrong code with LSHIFT and optimization

2019-05-29 Thread anlauf at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90578

anlauf at gcc dot gnu.org changed:

   What|Removed |Added

 CC||anlauf at gcc dot gnu.org

--- Comment #4 from anlauf at gcc dot gnu.org ---
(In reply to rguent...@suse.de from comment #3)
> On Thu, 23 May 2019, dominiq at lps dot ens.fr wrote:
> > I don't see any mention of "left-shift by negative value is undefined".
> 
> But it doesn't define what happens either ;)  Thus it is "undefined" :P
> 
> So, if the GNU extension would document it as "A LSHIFT by a 
> negative value is treated as a RSHIFT" then the frontend has
> to emit y < 0 ? x >> y : x << y since what I am saying is that
> the middle-end follows the C standard here and treats negative
> shift amounts as undefined.

The gfortran documentation of LSHIFT (and RSHIFT) mentions:

"This function has been superseded by the ISHFT intrinsic, which is standard in
Fortran 95 and later."

The natural solution would be to implement LSHIFT/RSHIFT in terms of ISHFT,
which does handle positive and negative shifts.

I might have a look at it.

[Bug fortran/90578] Wrong code with LSHIFT and optimization

2019-05-23 Thread rguenther at suse dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90578

--- Comment #3 from rguenther at suse dot de  ---
On Thu, 23 May 2019, dominiq at lps dot ens.fr wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90578
> 
> Dominique d'Humieres  changed:
> 
>What|Removed |Added
> 
>  Status|RESOLVED|NEW
>  Resolution|INVALID |---
> 
> --- Comment #2 from Dominique d'Humieres  ---
> LSHIFT is a GNU extension defined as
> 
> LSHIFT returns a value corresponding to I with all of the bits shifted left by
> SHIFT places. If the absolute value of SHIFT is greater than BIT_SIZE(I), the
> value is undefined. Bits shifted out from the left end are lost; zeros are
> shifted in from the opposite end.
> 
> I don't see any mention of "left-shift by negative value is undefined".

But it doesn't define what happens either ;)  Thus it is "undefined" :P

So, if the GNU extension would document it as "A LSHIFT by a 
negative value is treated as a RSHIFT" then the frontend has
to emit y < 0 ? x >> y : x << y since what I am saying is that
the middle-end follows the C standard here and treats negative
shift amounts as undefined.

[Bug fortran/90578] Wrong code with LSHIFT and optimization

2019-05-23 Thread dominiq at lps dot ens.fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90578

Dominique d'Humieres  changed:

   What|Removed |Added

 Status|RESOLVED|NEW
 Resolution|INVALID |---

--- Comment #2 from Dominique d'Humieres  ---
LSHIFT is a GNU extension defined as

LSHIFT returns a value corresponding to I with all of the bits shifted left by
SHIFT places. If the absolute value of SHIFT is greater than BIT_SIZE(I), the
value is undefined. Bits shifted out from the left end are lost; zeros are
shifted in from the opposite end.

I don't see any mention of "left-shift by negative value is undefined".

If it is the case for the gfortran implementation, this should be documented.

[Bug fortran/90578] Wrong code with LSHIFT and optimization

2019-05-23 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90578

Richard Biener  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||rguenth at gcc dot gnu.org
 Resolution|--- |INVALID

--- Comment #1 from Richard Biener  ---
left-shift by negative value is undefined.  arithmetic left-shift _of_ a
negative value is undefined as well.

I see lshift translates to a logical shift so the 2nd issue is moot.  But we
have in .gimple:

_1 = (unsigned int) D.3899;
_2 = _1 << -30;

note that constant folding treats _1 << -30 as _1 >> 30 but at -O0 we
ask the CPU to perform this shift via

sall%cl, %edx

which simply truncates -30 by & 255.

[Bug fortran/90578] Wrong code with LSHIFT and optimization

2019-05-22 Thread dominiq at lps dot ens.fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90578

Dominique d'Humieres  changed:

   What|Removed |Added

   Keywords||wrong-code
 Status|UNCONFIRMED |NEW
   Last reconfirmed||2019-05-22
   See Also||https://gcc.gnu.org/bugzill
   ||a/show_bug.cgi?id=90577
 Ever confirmed|0   |1