This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
[PATCH] [tree-ssa] another miscompile due to BOOL_TYPE_SIZE being INT_TYPE_SIZE (bootstrap failure on ppc-apple-darwin)
- From: Andrew Pinski <pinskia at physics dot uc dot edu>
- To: gcc at gcc dot gnu dot org
- Cc: Andrew Pinski <pinskia at physics dot uc dot edu>
- Date: Sat, 27 Sep 2003 11:51:05 -0700
- Subject: [PATCH] [tree-ssa] another miscompile due to BOOL_TYPE_SIZE being INT_TYPE_SIZE (bootstrap failure on ppc-apple-darwin)
There are places which check TYPE_MODE without also checking
TYPE_PRECISION.
This causes a miscompile of gengtype on the second stage in
powerpc-apple-darwin.
I tried to find the place which is causing this miscompile but I could
not find it.
I made sure that it was BOOL_TYPE_SIZE being set to be the same as
INT_TYPE_SIZE by
commenting it out in config/rs6000/darwin.h and then I was able to get
passed
running gengtype.
Thanks,
Andrew Pinski
Here the patch I tried so far (but it was not enough) (the convert.c
part is from the mainline):
Index: convert.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/convert.c,v
retrieving revision 1.18.2.9
diff -u -p -r1.18.2.9 convert.c
--- convert.c 20 Aug 2003 20:44:13 -0000 1.18.2.9
+++ convert.c 27 Sep 2003 18:45:33 -0000
@@ -349,7 +349,27 @@ convert_to_integer (tree type, tree expr
we are truncating EXPR. */
else if (outprec >= inprec)
- return build1 (NOP_EXPR, type, expr);
+ {
+ enum tree_code code;
+
+ /* If the precision of the EXPR's type is K bits and the
+ destination mode has more bits, and the sign is changing,
+ it is not safe to use a NOP_EXPR. For example, suppose
+ that EXPR's type is a 3-bit unsigned integer type, the
+ TYPE is a 3-bit signed integer type, and the machine mode
+ for the types is 8-bit QImode. In that case, the
+ conversion necessitates an explicit sign-extension. In
+ the signed-to-unsigned case the high-order bits have to
+ be cleared. */
+ if (TREE_UNSIGNED (type) != TREE_UNSIGNED (TREE_TYPE (expr))
+ && (TYPE_PRECISION (TREE_TYPE (expr))
+ != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr)))))
+ code = CONVERT_EXPR;
+ else
+ code = NOP_EXPR;
+
+ return build1 (code, type, expr);
+ }
/* If TYPE is an enumeral type or a type with a precision less
than the number of bits in its mode, do the conversion to the
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.213.2.47
diff -u -p -r1.213.2.47 fold-const.c
--- fold-const.c 24 Sep 2003 08:04:04 -0000 1.213.2.47
+++ fold-const.c 27 Sep 2003 18:47:12 -0000
@@ -1856,7 +1856,8 @@ operand_equal_p (tree arg0, tree arg1, i
Might as well play it safe and always test this. */
|| TREE_CODE (TREE_TYPE (arg0)) == ERROR_MARK
|| TREE_CODE (TREE_TYPE (arg1)) == ERROR_MARK
- || TYPE_MODE (TREE_TYPE (arg0)) != TYPE_MODE (TREE_TYPE (arg1)))
+ || TYPE_MODE (TREE_TYPE (arg0)) != TYPE_MODE (TREE_TYPE (arg1))
+ || TYPE_PRECISION (TREE_TYPE (arg0)) != TYPE_PRECISION
(TREE_TYPE (arg1)))
return 0;
/* If ARG0 and ARG1 are the same SAVE_EXPR, they are necessarily
equal.
@@ -2857,7 +2858,9 @@ simple_operand_p (tree exp)
while ((TREE_CODE (exp) == NOP_EXPR
|| TREE_CODE (exp) == CONVERT_EXPR)
&& (TYPE_MODE (TREE_TYPE (exp))
- == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))))
+ == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))
+ && TYPE_PRECISION (TREE_TYPE (exp))
+ == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))))
exp = TREE_OPERAND (exp, 0);
return (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c'
Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.374.2.25
diff -u -p -r1.374.2.25 function.c
--- function.c 24 Sep 2003 21:43:03 -0000 1.374.2.25
+++ function.c 27 Sep 2003 18:48:12 -0000
@@ -5286,7 +5286,8 @@ promoted_input_arg (unsigned int regno,
arg = TREE_CHAIN (arg))
if (GET_CODE (DECL_INCOMING_RTL (arg)) == REG
&& REGNO (DECL_INCOMING_RTL (arg)) == regno
- && TYPE_MODE (DECL_ARG_TYPE (arg)) == TYPE_MODE (TREE_TYPE (arg)))
+ && TYPE_MODE (DECL_ARG_TYPE (arg)) == TYPE_MODE (TREE_TYPE (arg))
+ && TYPE_PRECISION (DECL_ARG_TYPE (arg)) == TYPE_PRECISION (TREE_TYPE
(arg)))
{
enum machine_mode mode = TYPE_MODE (TREE_TYPE (arg));
int unsignedp = TREE_UNSIGNED (TREE_TYPE (arg));