public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* warning: right shift count >= width of type
@ 2004-11-29 16:30 Dave Korn
  2004-11-29 16:33 ` Nathan Sidwell
                   ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Dave Korn @ 2004-11-29 16:30 UTC (permalink / raw)
  To: gcc



  Afternoon all.  Here's something that's piqued my curiosity; it's probably
owing to some language-lawyerly issue, but it isn't obvious to me.  This is
on gcc-3.3.3, (cygwin variant, but that's probably not relevant):

-------------------------<snip!>-------------------------
dk@mace /test/shift-test> cat foo.c

unsigned int bar (unsigned int baz)
{
unsigned int quux;

        quux = baz >> 32;
        return quux;
}

dk@mace /test/shift-test> gcc -S foo.c -O2 -o foo.s
foo.c: In function `bar':
foo.c:7: warning: right shift count >= width of type
dk@mace /test/shift-test> cat foo.s
        .file   "foo.c"
        .text
        .p2align 4,,15
.globl _bar
        .def    _bar;   .scl    2;      .type   32;     .endef
_bar:
        pushl   %ebp
        movl    %esp, %ebp
        movl    8(%ebp), %eax
        movb    $32, %cl
        shrl    %cl, %eax
        popl    %ebp
        ret
dk@mace /test/shift-test>
-------------------------<snip!>-------------------------

  Why isn't the shift operation optimised away and replaced with const_int
0?


    cheers, 
      DaveK
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: warning: right shift count >= width of type
  2004-11-29 16:30 warning: right shift count >= width of type Dave Korn
@ 2004-11-29 16:33 ` Nathan Sidwell
  2004-11-29 17:01 ` Andrew Haley
  2004-11-29 17:12 ` Dale Johannesen
  2 siblings, 0 replies; 19+ messages in thread
From: Nathan Sidwell @ 2004-11-29 16:33 UTC (permalink / raw)
  To: Dave Korn; +Cc: gcc

Dave Korn wrote:
> 
>   Afternoon all.  Here's something that's piqued my curiosity; it's probably
> owing to some language-lawyerly issue, but it isn't obvious to me.  This is
> on gcc-3.3.3, (cygwin variant, but that's probably not relevant):
> 
> -------------------------<snip!>-------------------------
> dk@mace /test/shift-test> cat foo.c
> 
> unsigned int bar (unsigned int baz)
> {
> unsigned int quux;
> 
>         quux = baz >> 32;
>         return quux;
> }
> 
> dk@mace /test/shift-test> gcc -S foo.c -O2 -o foo.s
> foo.c: In function `bar':
> foo.c:7: warning: right shift count >= width of type
> dk@mace /test/shift-test> cat foo.s

>   Why isn't the shift operation optimised away and replaced with const_int
> 0?

It's _undefined_.  Didn't you make some comment about what undefined
meant last week :)

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

^ permalink raw reply	[flat|nested] 19+ messages in thread

* warning: right shift count >= width of type
  2004-11-29 16:30 warning: right shift count >= width of type Dave Korn
  2004-11-29 16:33 ` Nathan Sidwell
@ 2004-11-29 17:01 ` Andrew Haley
  2004-11-29 17:12 ` Dale Johannesen
  2 siblings, 0 replies; 19+ messages in thread
From: Andrew Haley @ 2004-11-29 17:01 UTC (permalink / raw)
  To: Dave Korn; +Cc: gcc

Dave Korn writes:
  > 
 >   Why isn't the shift operation optimised away and replaced with const_int
 > 0?

Why should it be?

Okay Dave, you guessed it: go see Section 6.5.7, para. 3.  :-)

Andrew.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: warning: right shift count >= width of type
  2004-11-29 16:30 warning: right shift count >= width of type Dave Korn
  2004-11-29 16:33 ` Nathan Sidwell
  2004-11-29 17:01 ` Andrew Haley
@ 2004-11-29 17:12 ` Dale Johannesen
  2004-11-29 17:14   ` Dave Korn
  2 siblings, 1 reply; 19+ messages in thread
From: Dale Johannesen @ 2004-11-29 17:12 UTC (permalink / raw)
  To: Dave Korn; +Cc: gcc, Dale Johannesen

On Nov 29, 2004, at 8:18 AM, Dave Korn wrote:
>   Afternoon all.  Here's something that's piqued my curiosity; it's 
> probably
> owing to some language-lawyerly issue, but it isn't obvious to me.  
> This is
> on gcc-3.3.3, (cygwin variant, but that's probably not relevant):
>
> -------------------------<snip!>-------------------------
> dk@mace /test/shift-test> cat foo.c
>
> unsigned int bar (unsigned int baz)
> {
> unsigned int quux;
>
>         quux = baz >> 32;
>         return quux;
> }
>   Why isn't the shift operation optimised away and replaced with 
> const_int
> 0?

Because that's not what it means.  Shifts by >= word size are undefined 
behavior
and will give different results depending on optimization level and on 
whether
the shift count is constant or variable.  Don't do that.  (If you think 
it ought to be 0,
reflect that most popular CPUs have only 5 bit shift counts, and 
consider what the
code for x >> y would have to look like.)

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: warning: right shift count >= width of type
  2004-11-29 17:12 ` Dale Johannesen
@ 2004-11-29 17:14   ` Dave Korn
  2004-11-29 17:26     ` Andrew Haley
  2004-11-29 17:38     ` Chris Jefferson
  0 siblings, 2 replies; 19+ messages in thread
From: Dave Korn @ 2004-11-29 17:14 UTC (permalink / raw)
  To: 'Dale Johannesen'
  Cc: gcc, 'Andrew Haley', 'Nathan Sidwell'

> -----Original Message-----
> From: Dale Johannesen 
> Sent: 29 November 2004 16:31

> On Nov 29, 2004, at 8:18 AM, Dave Korn wrote:
> >   Afternoon all.  Here's something that's piqued my curiosity; it's 
> > probably
> > owing to some language-lawyerly issue, but it isn't obvious to me.  
> > This is
> > on gcc-3.3.3, (cygwin variant, but that's probably not relevant):
> >
> > -------------------------<snip!>-------------------------
> > dk@mace /test/shift-test> cat foo.c
> >
> > unsigned int bar (unsigned int baz)
> > {
> > unsigned int quux;
> >
> >         quux = baz >> 32;
> >         return quux;
> > }
> >   Why isn't the shift operation optimised away and replaced with 
> > const_int
> > 0?
> 
> Because that's not what it means.  Shifts by >= word size are 
> undefined 
> behavior
> and will give different results depending on optimization 
> level and on 
> whether
> the shift count is constant or variable.  Don't do that.  (If 
> you think 
> it ought to be 0,
> reflect that most popular CPUs have only 5 bit shift counts, and 
> consider what the
> code for x >> y would have to look like.)


  Absolutely so; my curiosity was piqued when I noticed that my
cross-compiler was generating illegal assembler code with an out-of-range
operand value that the assembler couldn't fit into the relevant opcode
bitfield.

  So my question is really "Given that it's undefined, which means that
whatever the compiler does is correct, and given that there's already code
in there to detect the situation and issue a warning, which probably means
that it would be very easy at such a point to replace the offending RTL with
(const_int 0), is there any specific reason why not to?"  And it looks like
the answer is that there's no reason not to, but nobody has wanted to make
it work that way; it's historical accident rather than any kind of policy or
language issue.

  I imagine that this is one of those areas where "undefined behaviour" is
the standard's way of saying "Well, some compilers in the past got it right
and some got it wrong and since the standard is largely about codifying the
de-facto behaviour of existing C compilers we'll leave this one alone", but
it's surely only an issue of bugward-compatibility: mathematically, there's
really no problem with right-shifting more than the width of the integer,
all that happens is that _all_ the bits drop out the right-hand side and
you're left with nothing.  ISTM reasonable that the result of a right-shift
by 32 bits could be assumed to be the same thing you get if you right-shift
by 1 bit 32 times....


    cheers, 
      DaveK
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: warning: right shift count >= width of type
  2004-11-29 17:14   ` Dave Korn
@ 2004-11-29 17:26     ` Andrew Haley
  2004-11-29 18:29       ` Peter Barada
  2004-11-29 18:52       ` Dave Korn
  2004-11-29 17:38     ` Chris Jefferson
  1 sibling, 2 replies; 19+ messages in thread
From: Andrew Haley @ 2004-11-29 17:26 UTC (permalink / raw)
  To: Dave Korn; +Cc: 'Dale Johannesen', gcc, 'Nathan Sidwell'

Dave Korn writes:
 > > -----Original Message-----
 > > From: Dale Johannesen 
 > > Sent: 29 November 2004 16:31
 > 
 > > On Nov 29, 2004, at 8:18 AM, Dave Korn wrote:
 > > >   Afternoon all.  Here's something that's piqued my curiosity; it's 
 > > > probably
 > > > owing to some language-lawyerly issue, but it isn't obvious to me.  
 > > > This is
 > > > on gcc-3.3.3, (cygwin variant, but that's probably not relevant):
 > > >
 > > > -------------------------<snip!>-------------------------
 > > > dk@mace /test/shift-test> cat foo.c
 > > >
 > > > unsigned int bar (unsigned int baz)
 > > > {
 > > > unsigned int quux;
 > > >
 > > >         quux = baz >> 32;
 > > >         return quux;
 > > > }
 > > >   Why isn't the shift operation optimised away and replaced with 
 > > > const_int
 > > > 0?
 > > 
 > > Because that's not what it means.  Shifts by >= word size are 
 > > undefined 
 > > behavior
 > > and will give different results depending on optimization 
 > > level and on 
 > > whether
 > > the shift count is constant or variable.  Don't do that.  (If 
 > > you think 
 > > it ought to be 0,
 > > reflect that most popular CPUs have only 5 bit shift counts, and 
 > > consider what the
 > > code for x >> y would have to look like.)
 > 
 > 
 >   Absolutely so; my curiosity was piqued when I noticed that my
 > cross-compiler was generating illegal assembler code with an out-of-range
 > operand value that the assembler couldn't fit into the relevant opcode
 > bitfield.
 > 
 >   So my question is really "Given that it's undefined, which means that
 > whatever the compiler does is correct, and given that there's already code
 > in there to detect the situation and issue a warning, which probably means
 > that it would be very easy at such a point to replace the offending RTL with
 > (const_int 0), is there any specific reason why not to?"

I think the idea is that 

  a << n  /* n == 32 */

and 

  a << 32

should do the same thing.  This seems IMO more helpful than
optimizing away the shift.

 >   I imagine that this is one of those areas where "undefined
 > behaviour" is the standard's way of saying "Well, some compilers in
 > the past got it right and some got it wrong and since the standard
 > is largely about codifying the de-facto behaviour of existing C
 > compilers we'll leave this one alone",

No, not at all.  The x86 processors interpret this as 

  a << (n % 32)

 > but it's surely only an issue of bugward-compatibility:
 > mathematically, there's really no problem with right-shifting more
 > than the width of the integer, all that happens is that _all_ the
 > bits drop out the right-hand side and you're left with nothing.

That's not what all hardware actually does with shift instructions.

 > ISTM reasonable that the result of a right-shift by 32 bits could
 > be assumed to be the same thing you get if you right-shift by 1 bit
 > 32 times....

The chip designers don't agree.

Andrew.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: warning: right shift count >= width of type
  2004-11-29 17:14   ` Dave Korn
  2004-11-29 17:26     ` Andrew Haley
@ 2004-11-29 17:38     ` Chris Jefferson
  2004-11-29 18:46       ` Dave Korn
  1 sibling, 1 reply; 19+ messages in thread
From: Chris Jefferson @ 2004-11-29 17:38 UTC (permalink / raw)
  To: Dave Korn
  Cc: 'Dale Johannesen', gcc, 'Andrew Haley',
	'Nathan Sidwell'

Dave Korn wrote:

>>-----Original Message-----
>>From: Dale Johannesen 
>>Sent: 29 November 2004 16:31
>>    
>>
>
>  
>
>>On Nov 29, 2004, at 8:18 AM, Dave Korn wrote:
>>    
>>
>>>  Afternoon all.  Here's something that's piqued my curiosity; it's 
>>>probably
>>>owing to some language-lawyerly issue, but it isn't obvious to me.  
>>>This is
>>>on gcc-3.3.3, (cygwin variant, but that's probably not relevant):
>>>
>>>-------------------------<snip!>-------------------------
>>>dk@mace /test/shift-test> cat foo.c
>>>
>>>unsigned int bar (unsigned int baz)
>>>{
>>>unsigned int quux;
>>>
>>>        quux = baz >> 32;
>>>        return quux;
>>>}
>>>  Why isn't the shift operation optimised away and replaced with 
>>>const_int
>>>0?
>>>      
>>>
>>Because that's not what it means.  Shifts by >= word size are 
>>undefined 
>>behavior
>>and will give different results depending on optimization 
>>level and on 
>>whether
>>the shift count is constant or variable.  Don't do that.  (If 
>>you think 
>>it ought to be 0,
>>reflect that most popular CPUs have only 5 bit shift counts, and 
>>consider what the
>>code for x >> y would have to look like.)
>>    
>>
>
>
>  Absolutely so; my curiosity was piqued when I noticed that my
>cross-compiler was generating illegal assembler code with an out-of-range
>operand value that the assembler couldn't fit into the relevant opcode
>bitfield.
>
>  So my question is really "Given that it's undefined, which means that
>whatever the compiler does is correct, and given that there's already code
>in there to detect the situation and issue a warning, which probably means
>that it would be very easy at such a point to replace the offending RTL with
>(const_int 0), is there any specific reason why not to?" 
>
One reason (of course) not to would be if you are bit-shifting by a 
variable. Adding a check at runtime to see if the value of this variable 
is <32 and if not setting the variable to zero would be frowned upon by 
many people, particuarily because the kind of people who undertake 
bitshifting are doing it for performance-related reasons...

Chris

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: warning: right shift count >= width of type
  2004-11-29 17:26     ` Andrew Haley
@ 2004-11-29 18:29       ` Peter Barada
  2004-11-29 18:53         ` Dave Korn
  2004-11-29 18:52       ` Dave Korn
  1 sibling, 1 reply; 19+ messages in thread
From: Peter Barada @ 2004-11-29 18:29 UTC (permalink / raw)
  To: aph; +Cc: dk, dalej, gcc, nathan


> > but it's surely only an issue of bugward-compatibility:
> > mathematically, there's really no problem with right-shifting more
> > than the width of the integer, all that happens is that _all_ the
> > bits drop out the right-hand side and you're left with nothing.
>
>That's not what all hardware actually does with shift instructions.
>
> > ISTM reasonable that the result of a right-shift by 32 bits could
> > be assumed to be the same thing you get if you right-shift by 1 bit
> > 32 times....
>
>The chip designers don't agree.

They *definitely* don't agree.  Most shift hardware is designed as a
barrel shifter which is a large combinational logic block that takes the
n-bits of the shift count and using them determine what each bit of
the result is supposed to be.  This allows a shift that takes only one
clock, wheter the shift is arithmetic or logical, right or left, and a
shift count from 0 up to the number of bits in the register-1.

Any shift count outside of that range is considered "undefined".

n 1-bit shifts is equivient to 1 n-bit shift only if n is less than
the size of the register in bits, at least for a hardware
implementation described above.

-- 
Peter Barada
peter@the-baradas.com

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: warning: right shift count >= width of type
  2004-11-29 17:38     ` Chris Jefferson
@ 2004-11-29 18:46       ` Dave Korn
  2004-11-29 19:19         ` Chris Jefferson
  0 siblings, 1 reply; 19+ messages in thread
From: Dave Korn @ 2004-11-29 18:46 UTC (permalink / raw)
  To: 'Chris Jefferson'
  Cc: 'Dale Johannesen', gcc, 'Andrew Haley',
	'Nathan Sidwell'

> -----Original Message-----
> From: Chris Jefferson 
> Sent: 29 November 2004 17:13

> >  So my question is really "Given that it's undefined, which 
> means that
> >whatever the compiler does is correct, and given that 
> there's already code
> >in there to detect the situation and issue a warning, which 
> probably means
> >that it would be very easy at such a point to replace the 
> offending RTL with
> >(const_int 0), is there any specific reason why not to?" 
> >
> One reason (of course) not to would be if you are bit-shifting by a 
> variable. Adding a check at runtime to see if the value of 
> this variable 
> is <32 and if not setting the variable to zero would be 
> frowned upon by 
> many people, particuarily because the kind of people who undertake 
> bitshifting are doing it for performance-related reasons...
> 
> Chris

  What on earth made you suppose I would for one instant suggest anything so
ridiculous?  I was talking about static compile-time checking.

    cheers, 
      DaveK
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: warning: right shift count >= width of type
  2004-11-29 17:26     ` Andrew Haley
  2004-11-29 18:29       ` Peter Barada
@ 2004-11-29 18:52       ` Dave Korn
  2004-11-29 19:09         ` Andrew Haley
  1 sibling, 1 reply; 19+ messages in thread
From: Dave Korn @ 2004-11-29 18:52 UTC (permalink / raw)
  To: 'Andrew Haley'
  Cc: 'Dale Johannesen', gcc, 'Nathan Sidwell'

> -----Original Message-----
> From: gcc-owner On Behalf Of Andrew Haley
> Sent: 29 November 2004 17:11

> Dave Korn writes:

>  >   So my question is really "Given that it's undefined, 
> which means that
>  > whatever the compiler does is correct, and given that 
> there's already code
>  > in there to detect the situation and issue a warning, 
> which probably means
>  > that it would be very easy at such a point to replace the 
> offending RTL with
>  > (const_int 0), is there any specific reason why not to?"
> 
> I think the idea is that 
> 
>   a << n  /* n == 32 */
> 
> and 
> 
>   a << 32
> 
> should do the same thing.  This seems IMO more helpful than
> optimizing away the shift.

  Ah, well I can see that as a desirable goal (although who ever said
undefined behaviour had to produce the same results consistently across
different methods of invoking said undefined behaviour?) I suppose.  

> No, not at all.  The x86 processors interpret this as 
> 
>   a << (n % 32)
> 
>  > but it's surely only an issue of bugward-compatibility:
>  > mathematically, there's really no problem with right-shifting more
>  > than the width of the integer, all that happens is that _all_ the
>  > bits drop out the right-hand side and you're left with nothing.
> 
> That's not what all hardware actually does with shift instructions.
> 
>  > ISTM reasonable that the result of a right-shift by 32 bits could
>  > be assumed to be the same thing you get if you right-shift by 1 bit
>  > 32 times....
> 
> The chip designers don't agree.

  I would argue that the x86 simply does not _provide_ a shift-by-32 bits
instruction, owing to that implicit modulo, any more than a RISC cpu with a
5-bit-wide field in the opcode to encode a shift amount does so.

  I myself would want "(n >> 32)" to produce the same result as "((n >> 16)
>> 16)" and indeed "for (int i = 32; i > 0; i--, n >>= 1) ;", and it seems
to be generally agreed that the compiler would be at liberty to so do if it
wants to.

    cheers, 
      DaveK
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: warning: right shift count >= width of type
  2004-11-29 18:29       ` Peter Barada
@ 2004-11-29 18:53         ` Dave Korn
  0 siblings, 0 replies; 19+ messages in thread
From: Dave Korn @ 2004-11-29 18:53 UTC (permalink / raw)
  To: 'Peter Barada', aph; +Cc: dalej, gcc, nathan

> -----Original Message-----
> From: Peter Barada  
> Sent: 29 November 2004 18:09

> > > ISTM reasonable that the result of a right-shift by 32 bits could
> > > be assumed to be the same thing you get if you 
> right-shift by 1 bit
> > > 32 times....
> >
> >The chip designers don't agree.
> 
> They *definitely* don't agree.  Most shift hardware is designed as a
> barrel shifter which is a large combinational logic block 
> that takes the
> n-bits of the shift count and using them determine what each bit of
> the result is supposed to be.  This allows a shift that takes only one
> clock, wheter the shift is arithmetic or logical, right or left, and a
> shift count from 0 up to the number of bits in the register-1.
> 
> Any shift count outside of that range is considered "undefined".

  No, I think it's more accurate to say that any shift count outside that
range is *unimplemented*.  "Undefined" is a concept from the C language
standard; mathematically, the operation is well defined, and in a practical
physical implementation, the operation is either "implemented" or
"unimplemented", but either way can hardly fail to be "defined", owing to
the deterministic nature of hardware implementations.
 
> n 1-bit shifts is equivient to 1 n-bit shift only if n is less than
> the size of the register in bits, at least for a hardware
> implementation described above.

  Similarly, I would say that 1 n-bit shift simply cannot be expressed on
such hardware, and it is meaningless to compare the outcome of a series of
operations that exist with some entirely hypothetical outcome of an
operation that simply does *not* exist.


    cheers, 
      DaveK
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: warning: right shift count >= width of type
  2004-11-29 18:52       ` Dave Korn
@ 2004-11-29 19:09         ` Andrew Haley
  2004-11-29 19:17           ` Dale Johannesen
  0 siblings, 1 reply; 19+ messages in thread
From: Andrew Haley @ 2004-11-29 19:09 UTC (permalink / raw)
  To: Dave Korn; +Cc: 'Dale Johannesen', gcc, 'Nathan Sidwell'

Dave Korn writes:
 > > -----Original Message-----
 > > From: gcc-owner On Behalf Of Andrew Haley
 > > Sent: 29 November 2004 17:11
 > 
 > > Dave Korn writes:
 > 
 > >  >   So my question is really "Given that it's undefined, 
 > > which means that
 > >  > whatever the compiler does is correct, and given that 
 > > there's already code
 > >  > in there to detect the situation and issue a warning, 
 > > which probably means
 > >  > that it would be very easy at such a point to replace the 
 > > offending RTL with
 > >  > (const_int 0), is there any specific reason why not to?"
 > > 
 > > I think the idea is that 
 > > 
 > >   a << n  /* n == 32 */
 > > 
 > > and 
 > > 
 > >   a << 32
 > > 
 > > should do the same thing.  This seems IMO more helpful than
 > > optimizing away the shift.
 > 
 >   Ah, well I can see that as a desirable goal (although who ever said
 > undefined behaviour had to produce the same results consistently across
 > different methods of invoking said undefined behaviour?) I suppose.  

Well, I said "helpful".  We don't try deliberately to be inconsistent
when people invoke undefined behaviour, it just happens as a
side-effect.  :-)

 > > No, not at all.  The x86 processors interpret this as 
 > > 
 > >   a << (n % 32)
 > > 
 > >  > but it's surely only an issue of bugward-compatibility:
 > >  > mathematically, there's really no problem with right-shifting more
 > >  > than the width of the integer, all that happens is that _all_ the
 > >  > bits drop out the right-hand side and you're left with nothing.
 > > 
 > > That's not what all hardware actually does with shift instructions.
 > > 
 > >  > ISTM reasonable that the result of a right-shift by 32 bits could
 > >  > be assumed to be the same thing you get if you right-shift by 1 bit
 > >  > 32 times....
 > > 
 > > The chip designers don't agree.
 > 
 >   I would argue that the x86 simply does not _provide_ a shift-by-32 bits
 > instruction, owing to that implicit modulo, any more than a RISC cpu with a
 > 5-bit-wide field in the opcode to encode a shift amount does so.
 > 
 >   I myself would want "(n >> 32)" to produce the same result as "((n >> 16)
 > >> 16)" and indeed "for (int i = 32; i > 0; i--, n >>= 1) ;", and it seems
 > to be generally agreed that the compiler would be at liberty to so do if it
 > wants to.

But you could never depend on it.  If it only works when the shift
count is a constant, a failure to do constant folding would break it.

Andrew.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: warning: right shift count >= width of type
  2004-11-29 19:09         ` Andrew Haley
@ 2004-11-29 19:17           ` Dale Johannesen
  2004-11-29 19:54             ` Dave Korn
  0 siblings, 1 reply; 19+ messages in thread
From: Dale Johannesen @ 2004-11-29 19:17 UTC (permalink / raw)
  To: Andrew Haley; +Cc: gcc, Dave Korn, Dale Johannesen, 'Nathan Sidwell'


On Nov 29, 2004, at 10:51 AM, Andrew Haley wrote:
>>   I myself would want "(n >> 32)" to produce the same result as "((n 
>> >> 16)
>>>> 16)" and indeed "for (int i = 32; i > 0; i--, n >>= 1) ;", and it 
>>>> seems
>> to be generally agreed that the compiler would be at liberty to so do 
>> if it
>> wants to.
>
> But you could never depend on it.  If it only works when the shift
> count is a constant, a failure to do constant folding would break it.

Or constant propagation, or inlining, or ...

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: warning: right shift count >= width of type
  2004-11-29 18:46       ` Dave Korn
@ 2004-11-29 19:19         ` Chris Jefferson
  2004-11-29 19:46           ` Dave Korn
  0 siblings, 1 reply; 19+ messages in thread
From: Chris Jefferson @ 2004-11-29 19:19 UTC (permalink / raw)
  To: Dave Korn
  Cc: 'Dale Johannesen', gcc, 'Andrew Haley',
	'Nathan Sidwell'

Dave Korn wrote:

>>-----Original Message-----
>>From: Chris Jefferson 
>>Sent: 29 November 2004 17:13
>>    
>>
>
>  
>
>>> So my question is really "Given that it's undefined, which 
>>>      
>>>
>>means that
>>    
>>
>>>whatever the compiler does is correct, and given that 
>>>      
>>>
>>there's already code
>>    
>>
>>>in there to detect the situation and issue a warning, which 
>>>      
>>>
>>probably means
>>    
>>
>>>that it would be very easy at such a point to replace the 
>>>      
>>>
>>offending RTL with
>>    
>>
>>>(const_int 0), is there any specific reason why not to?" 
>>>
>>>      
>>>
>>One reason (of course) not to would be if you are bit-shifting by a 
>>variable. Adding a check at runtime to see if the value of 
>>this variable 
>>is <32 and if not setting the variable to zero would be 
>>frowned upon by 
>>many people, particuarily because the kind of people who undertake 
>>bitshifting are doing it for performance-related reasons...
>>
>>Chris
>>    
>>
>
>  What on earth made you suppose I would for one instant suggest anything so
>ridiculous?  I was talking about static compile-time checking.
>
>  
>
I apologise. Then I would instead ask why you would want to add some 
compiler-specific extension that may or may not activate depending upon 
the current level of optimisation? Or would you forbid this optimisation 
if gcc can deduce an expression is constant when it isn't obvious 
without optimisation?

Chris

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: warning: right shift count >= width of type
  2004-11-29 19:19         ` Chris Jefferson
@ 2004-11-29 19:46           ` Dave Korn
  0 siblings, 0 replies; 19+ messages in thread
From: Dave Korn @ 2004-11-29 19:46 UTC (permalink / raw)
  To: 'Chris Jefferson'
  Cc: 'Dale Johannesen', gcc, 'Andrew Haley',
	'Nathan Sidwell'

> -----Original Message-----
> From: Chris Jefferson 
> Sent: 29 November 2004 19:07

> I apologise. Then I would instead ask why you would want to add some 
> compiler-specific extension that may or may not activate 
> depending upon 
> the current level of optimisation? Or would you forbid this 
> optimisation 
> if gcc can deduce an expression is constant when it isn't obvious 
> without optimisation?
> 
> Chris


  Well, if the compiler can issue a warning, it could also in theory do
something about it.  It's not an "extension", since *anything* the compiler
does is valid according to the standard.  And the truth is I was only
interested in catching obvious cases, so that you can write something like

ARBITRARY_INT_TYPE x, y, z;

   /* Separate x into 32-bit chunks */
   y = (x >> 32) & 0xffffffffUL;
   z = x & 0xffffffffUL;

and have it DTRT regardless of whether the int's are 32 or 64 bits wide
naturally....

    cheers, 
      DaveK
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: warning: right shift count >= width of type
  2004-11-29 19:17           ` Dale Johannesen
@ 2004-11-29 19:54             ` Dave Korn
  0 siblings, 0 replies; 19+ messages in thread
From: Dave Korn @ 2004-11-29 19:54 UTC (permalink / raw)
  To: 'Dale Johannesen', 'Andrew Haley'
  Cc: gcc, 'Nathan Sidwell'

> -----Original Message-----
> From: Dale Johannesen 
> Sent: 29 November 2004 18:57

> On Nov 29, 2004, at 10:51 AM, Andrew Haley wrote:
> >>   I myself would want "(n >> 32)" to produce the same 
> result as "((n 
> >> >> 16)
> >>>> 16)" and indeed "for (int i = 32; i > 0; i--, n >>= 1) 
> ;", and it 
> >>>> seems
> >> to be generally agreed that the compiler would be at 
> liberty to so do 
> >> if it
> >> wants to.
> >
> > But you could never depend on it.  If it only works when the shift
> > count is a constant, a failure to do constant folding would 
> break it.
> 
> Or constant propagation, or inlining, or ...
> 

Ah.  Good point.

Of course, in such cases, the compiler will also fail to produce the warning
message too.......


    cheers, 
      DaveK
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: warning: right shift count >= width of type
@ 2004-11-30  4:23 Paul Schlie
  0 siblings, 0 replies; 19+ messages in thread
From: Paul Schlie @ 2004-11-30  4:23 UTC (permalink / raw)
  To: gcc

> Andreas wrote;
>> Paul Schlie <schlie@comcast.net> writes:
>> ...
>> It likely needs to define what (x << z) means if:
>>
>> - z lesser-or-equal-to 0, [i.e. does (x << -1) == (x >> 1) ?]
>
> Since left and right shift are usually separate insns this would result
> in a runtime penalty.

Sorry if I wasn't clear, the statement was made within the context of
what would likely be necessary if (x * <pow2>) == (x << (log2 <pow2>), etc.
equivalence was generally assumed to algebraically simplify expressions.

As:

((x * <pow2a>) / <pow2b>) => (x << (- <pow2a> <pow2b))

would be valid if the above and previously cited were consistently defined.


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: warning: right shift count >= width of type
  2004-11-29 23:49 Paul Schlie
@ 2004-11-30  1:50 ` Andreas Schwab
  0 siblings, 0 replies; 19+ messages in thread
From: Andreas Schwab @ 2004-11-30  1:50 UTC (permalink / raw)
  To: Paul Schlie; +Cc: gcc

Paul Schlie <schlie@comcast.net> writes:

> It likely needs to define what (x << z) means if:
>
> - z lesser-or-equal-to 0, [i.e. does (x << -1) == (x >> 1) ?]

Since left and right shift are usually separate insns this would result in
a runtime penalty.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: warning: right shift count >= width of type
@ 2004-11-29 23:49 Paul Schlie
  2004-11-30  1:50 ` Andreas Schwab
  0 siblings, 1 reply; 19+ messages in thread
From: Paul Schlie @ 2004-11-29 23:49 UTC (permalink / raw)
  To: gcc

>> On Nov 29, 2004, at 10:51 AM, Andrew Haley wrote:
>>> I myself would want "(n >> 32)" to produce the same result as "((n >> 16)
>>> 16)" and indeed "for (int i = 32; i > 0; i--, n >>= 1) ;", and it seems
>>> to be generally agreed that the compiler would be at liberty to so do if
>>> it wants to.
>>
>> But you could never depend on it.  If it only works when the shift
>> count is a constant, a failure to do constant folding would break it.
>
> Or constant propagation, or inlining, or ...

Would think that if GCC wants to define an equivalence between:

 (x * <pow2>) == (x << (log2 <pow2>))

and/or

 (x / <pow2>) == (x >> (log2 <pow2>))


And generally algebraically manipulate such expressions:

 (x * <pow2-a>) * (y >> z) / <pow2-b>

=> 

 (x * y) << (+ z (- <pow2-a> <pow2-b>))
or
 (x * y) >> (+ z (- <pow2-a> <pow2-b>))


It likely needs to define what (x << z) means if:

- z lesser-or-equal-to 0, [i.e. does (x << -1) == (x >> 1) ?]

- z greater-or-equal-to bit-size-of( x * z )
  [i.e. does (x * <pow2-bits-in-x>) == (x << (log2 <pow2-bits-in-x>)) ?]

Regardless of what the "less than concise" C standard says, or the
assumption of such equivalences are fragile.





^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2004-11-30  2:58 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-11-29 16:30 warning: right shift count >= width of type Dave Korn
2004-11-29 16:33 ` Nathan Sidwell
2004-11-29 17:01 ` Andrew Haley
2004-11-29 17:12 ` Dale Johannesen
2004-11-29 17:14   ` Dave Korn
2004-11-29 17:26     ` Andrew Haley
2004-11-29 18:29       ` Peter Barada
2004-11-29 18:53         ` Dave Korn
2004-11-29 18:52       ` Dave Korn
2004-11-29 19:09         ` Andrew Haley
2004-11-29 19:17           ` Dale Johannesen
2004-11-29 19:54             ` Dave Korn
2004-11-29 17:38     ` Chris Jefferson
2004-11-29 18:46       ` Dave Korn
2004-11-29 19:19         ` Chris Jefferson
2004-11-29 19:46           ` Dave Korn
2004-11-29 23:49 Paul Schlie
2004-11-30  1:50 ` Andreas Schwab
2004-11-30  4:23 Paul Schlie

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).