Hi!

On Tue, Jun 09, 2020 at 05:01:45PM -0700, Carl Love wrote:
> On Fri, 2020-06-05 at 16:28 -0500, Segher Boessenkool wrote:
> > > +;; Return 1 if op is a 32-bit constant signed integer
> > > +(define_predicate "s32bit_cint_operand"
> > > +  (and (match_code "const_int")
> > > +       (match_test "INTVAL (op) >= -2147483648
> > > +          && INTVAL (op) <= 2147483647")))
> > 
> > There probably is a nicer way to write this than with big decimal
> > numbers.  (I'll not suggest one here because I'll just make a fool of
> > myself with overflow or signed/unsigned etc. :-) )
> > 
> > > +;; Return 1 if op is a constant 32-bit signed or unsigned integer
> > > +(define_predicate "c32bit_cint_operand"
> > > +  (and (match_code "const_int")
> > > +       (match_test "((INTVAL (op) >> 32) == 0)")))
> 
> The more I look at the above two they really are the same.  Basically,
> it boils down to ... can the value signed or unsigned fit in 32-bits or
> not?

s32bit_cint_operand is testing if it fits in signed 32 bit.
c32bit_cint_operand is testing if it fits in unsigned 32 bit (but that
is not what its description says).

> It seems like both of the above just need to test if the INTVAL
> (op) has any bits above bits 0:31 set.  So seems like (INTVAL (op) >>
> 32) == 0) should be sufficient for both predicates, i.e. replace the
> two with a single generic predicate "cint_32bit_operand".  

That isn't the range for signed 32 bit though.  As a 64-bit number, the
top half is the sign extension of the bottom half, so the top half is
-1 (i.e. all bits set) for negative numbers.  A 64-bit number with 0 as
the high half but the top bit of the low half set is out of range for a
signed 32-bit number.

> > > +;; Return 1 if op is a constant 32-bit floating point value
> > > +(define_predicate "f32bit_const_operand"
> > > +  (match_code "const_double"))
> > 
> > Either the predicate name is misleading (if you do allow all
> > const_double values), or there should be some test for the alloed
> > values
> > here.
> 
> The predicate is used to check for a 32-bit float constant.  Looking
> thru the code not sure if const_double is a 64-bit float?

It is.

> I don't think
> that is what I want.  I want a 32-bit floating point value,
> const_float, const_real?

As a constant number that will still be done as a const_double.  You
should test its actual value to see if it is a valid single-presicision
floating point number.  There probably already is a helper for that?

> Don't see a a const_float or anything that
> looks like that?  Not having much luck to see where const_double gets
> defined to see what other definitions there are.

It is defined in rtl.def:
/* numeric floating point or integer constant.  If the mode is
   VOIDmode it is an int otherwise it has a floating point mode and a
   floating point value.  Operands hold the value.  They are all 'w'
   and there may be from 2 to 6; see real.h.  */
DEF_RTL_EXPR(CONST_DOUBLE, "const_double", CONST_DOUBLE_FORMAT, RTX_CONST_OBJ)

(this is probably more confusing than helpful, but you asked ;-) )

> I am assuming at this point in the compilation process, the constant
> that is passed has type info (signed int, unsigned int, float)
> associated with it from the front end parsing of the source code.

RTL uses modes, not types.  What is the mode of the const_double here?
If it is SFmode you are fine (but do test for that mode then).  If it is
DFmode, you need to check its actual value.  We want to support *both*,
and checking the value works in all cases.

(What you need to check is if that floating point value can be exactly
expressed as a 32-bit IEEE float, no rounding or truncation etc.)


Segher

Reply via email to