optimization/705: Performance regression with glibc's strcpymacro

Bernd Schmidt bernds@redhat.co.uk
Sun Oct 29 03:53:00 GMT 2000

On Sun, 29 Oct 2000, Joseph Myers wrote:

[How do i use the bug database properly - do I need to reply to gcc-gnats,
gcc-prs, or both?]

> >Fix:
> Fix constant folding for
>     (((char *)&"Foobar"[1]) - (char *)&"Foobar"[0]) == 1

It seems that this was broken by

Sat Nov 27 08:38:26 1999  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

        * fold-const.c (negate_expr, associate_trees, extract_muldiv): New.
        (split_tree): Completely rework to make more general.
        (make_range, fold): Call negate_expr.
        (fold, case NEGATE_EXPR): Simplify -(a-b) is -ffast-math.
        (fold, associate): Call new split_tree and associate_trees.
        (fold, case MULT_EXPR, case *_{DIV,MOD}_EXPR): Call extract_muldiv.

or possibly by later changes to the new code.

The function split_tree gets called with the following as IN 

 <plus_expr 0x40167040
    type <pointer_type 0x40151300
        type <integer_type 0x4014d200 char QI
            size <integer_cst 0x4014b380 constant 8>
            unit size <integer_cst 0x4014b3a0 constant 1>
            align 8 symtab 0 alias set 3 precision 8
            min <integer_cst 0x4014b460 constant -128>
            max <integer_cst 0x4014b480 constant 127>
            pointer_to_this <pointer_type 0x40151300>>
        unsigned DI
        size <integer_cst 0x4014bc20 constant 64>
        unit size <integer_cst 0x4014bc40 constant 8>
        align 64 symtab 0 alias set -1>
    arg 0 <nop_expr 0x40165f40 type <pointer_type 0x40151300>
        readonly constant
        arg 0 <addr_expr 0x40165f20 type <pointer_type 0x40159a80>
            readonly constant
            arg 0 <string_cst 0x40165da0 type <array_type 0x40159a00>
                readonly constant static "Foobar">>>
    arg 1 <integer_cst 0x40167020 type <pointer_type 0x40151300> constant 1>>

and returns the whole thing as the constant instead of breaking it up a bit.
The patch below makes the compiler generate decent code for this testcase:

int t;
int main ()
  t = ((char *)&"Foobar"[1]) - (char *)&"Foobar"[0];
  return 0;


	* fold-const.c (split_tree): First try to break up the expression, then
	see if it is constant as a whole.

Index: fold-const.c
RCS file: /cvs/gcc/egcs/gcc/fold-const.c,v
retrieving revision 1.134
diff -u -p -r1.134 fold-const.c
--- fold-const.c	2000/10/20 17:51:51	1.134
+++ fold-const.c	2000/10/29 11:49:07
@@ -1356,9 +1356,6 @@ split_tree (in, code, conp, litp, negate
   if (TREE_CODE (in) == INTEGER_CST || TREE_CODE (in) == REAL_CST)
     *litp = in;
-  else if (TREE_CONSTANT (in))
-    *conp = in;
   else if (TREE_CODE (in) == code
 	   || (! FLOAT_TYPE_P (TREE_TYPE (in))
 	       /* We can associate addition and subtraction together (even
@@ -1398,6 +1395,8 @@ split_tree (in, code, conp, litp, negate
       if (neg_conp_p) *conp = negate_expr (*conp);
       if (neg_var_p) var = negate_expr (var);
+  else if (TREE_CONSTANT (in))
+    *conp = in;
     var = in;

More information about the Gcc-bugs mailing list