[PATCH] Fix fold_read_from_constant_string for unsigned-char hosts

Ulrich Weigand weigand@i1.informatik.uni-erlangen.de
Fri May 21 23:52:00 GMT 2004


since the tree-ssa merge I'm seeing the following two test suite
regressions on s390(x):
FAIL: gcc.c-torture/compile/20020319-1.c (test for excess errors)
FAIL: gcc.c-torture/execute/921218-1.c compilation,  -O0
UNRESOLVED: gcc.c-torture/execute/921218-1.c execution,  -O0

The compiler ICEs because it generates invalid RTL like
   (set (reg:QI) (const_int 136))
(i.e. constant out of range for QImode).

This in turn happens because the new fold_read_from_constant_string
routine does:
       return build_int_2 ((TREE_STRING_POINTER (string)
                            [TREE_INT_CST_LOW (index)]), 0);

Note that TREE_STRING_POINTER returns a 'char *', while build_int_2
expects a HOST_WIDE_INT.  The conversion depends on the whether the
*host* platform uses a signed or unsigned char type, which certainly
should be of no relevance to generated code.

Furthermore, the result of the build_int_2 is of type 'integer'
(SImode), even if the original expression passed into that routine
was of another type (usually QImode).  This is especially problematical
as the caller simply expects the type to stay the same, and generates
moves like the above without conversion.

I'm not completely sure how to fix this, but generally the routines
in fold-const tend to use fold_convert to make sure they return the
same type as they got.  Doing the same here fixes the regressions
on s390(x).

Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux.


	* fold-const.c (fold_read_from_constant_string): Convert result to
	requested type.

Index: gcc/fold-const.c
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.377
diff -c -p -r1.377 fold-const.c
*** gcc/fold-const.c	19 May 2004 13:14:18 -0000	1.377
--- gcc/fold-const.c	20 May 2004 22:23:44 -0000
*************** fold_read_from_constant_string (tree exp
*** 9832,9839 ****
  	      == MODE_INT)
  	  && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (string)))) == 1))
! 	return build_int_2 ((TREE_STRING_POINTER (string)
! 			     [TREE_INT_CST_LOW (index)]), 0);
    return NULL;
--- 9832,9840 ----
  	      == MODE_INT)
  	  && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (string)))) == 1))
! 	return fold_convert (TREE_TYPE (exp),
! 			     build_int_2 ((TREE_STRING_POINTER (string)
! 					  [TREE_INT_CST_LOW (index)]), 0));
    return NULL;
  Dr. Ulrich Weigand

More information about the Gcc-patches mailing list