[tree-ssa] Why are bools cast to int in conditionals?

Dan Nicolaescu dann@godzilla.ics.uci.edu
Thu Apr 22 18:22:00 GMT 2004


"Joseph S. Myers" <jsm@polyomino.org.uk> writes:

  > On Wed, 21 Apr 2004, Dan Nicolaescu wrote:
  > 
  > >   > Here, the usual arithmetic conversions are applied to the operands of !=,
  > >   > which includes the integer promotions, which promote _Bool to int.
  > > 
  > > Is _Bool different from other types in this respect? short, chars and
  > > enums don't seem to get the same treatment. 
  > 
  > Perhaps some optimization is allowing INTEGER_TYPE but not BOOLEAN_TYPE.  
  > Various optimizations of operations on promoted types are presently in 
  > build_binary_op and shorten_compare.

I looked at the difference between the handling of _Bool and unsigned
char using the following 2 functions:

t1.c:
unsigned char foo (unsigned char a, unsigned char b)
{
  if (a != b)
    return 1;
  else
    return 0;
}

t2.c:
_Bool foo (_Bool a, _Bool b)
{
  if (a != b)
    return 1;
  else
    return 0;
}



build_binary_op calls default_conversion
default_conversion ends up calling convert_to_integer

This code is triggered in convert_to_integer:

[1]	  if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (TREE_TYPE (expr))
               && (TYPE_PRECISION (TREE_TYPE (expr))
                   != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr)))))

for the "unsigned char" function the if is false because
        TYPE_PRECISION (TREE_TYPE (expr) = 8
        GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr))) = 8

so the return value for convert_to_integer will be
 build1 (NOP_EXPR, type, expr)

for the "_Bool" case this is false because 
        TYPE_PRECISION (TREE_TYPE (expr) = 1
        GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr))) = 8

so the return value for convert_to_integer will be
 build1 (CONVERT_EXPR, type, expr)


The call to "shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode)"
in build_binary_op will get rid of the NOP_EXPR, but it won't get rid
of the CONVERT_EXPR. So for the "_Bool" function the comparison
generated by build_binary_op is:  "(int)a != (int)b"
and for the "unsigned char" function is: "a != b"


Is the code at [1] correct? Should it generate a CONVERT_EXPR for the
_Bool case? 
Should shorten_compare be changed to handle the CONVERT_EXPR generated
by [1]? 
Is there a different solution? 



More information about the Gcc mailing list