This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

__builtin_constant_p regression


Consider the following example, where the strcpy macro is a greatly
simplyfied copy from the GNU libc:

------------------------------
typedef __SIZE_TYPE__ size_t;
char *strcpy (char *, const char *);
void *memcpy (void *, const void *, size_t);

char one[50], two[50];

#define strcpy(a, b)				\
  (__builtin_constant_p (b)			\
   ? (strlen (b) < 4				\
      ? ({ char *__dest = (a);			\
	   switch (strlen (b))			\
	     {					\
	     case 3: __dest[3] = (b)[3];	\
	     case 2: __dest[2] = (b)[2];	\
	     case 1: __dest[1] = (b)[1];	\
	     case 0: __dest[0] = (b)[0];	\
	     }					\
	   __dest;				\
	 })					\
      : (char *) memcpy (a, b, strlen (b) + 1))	\
   : strcpy (a, b))

int main ()
{
  strcpy (one, two);
  return 0;
}
------------------------------

When compiled with egcs this generates horrible code:

------------------------------
	.file	"const.c"
	.version	"01.01"
gcc2_compiled.:
.text
	.align 	2
.globl main
	.type	 main,@function
main:
	link.w %a6,#0
	movm.l #0x2030,-(%sp)
	pea two
	lea strlen,%a3
	jbsr (%a3)
	addq.l #4,%sp
	moveq.l #3,%d1
	cmp.l %d0,%d1
	jbcs .L12
	lea one,%a2
	pea two
	jbsr (%a3)
	moveq.l #1,%d1
	cmp.l %d0,%d1
	jbeq .L6
	jbhi .L7
	moveq.l #2,%d1
	cmp.l %d0,%d1
	jbeq .L5
	moveq.l #3,%d1
	cmp.l %d0,%d1
	jbne .L11
	move.b two+3,3(%a2)
.L5:
	move.b two+2,2(%a2)
.L6:
	move.b two+1,1(%a2)
.L7:
	move.b two,(%a2)
	jbra .L11
	.align 	2
.L12:
	move.l #two,%d2
	move.l %d2,-(%sp)
	jbsr strlen
	addq.l #4,%sp
	addq.l #1,%d0
	move.l %d0,-(%sp)
	move.l %d2,-(%sp)
	pea one
	jbsr memcpy
.L11:
	clr.l %d0
	movm.l -12(%a6),#0xc04
	unlk %a6
	rts
.Lfe1:
	.size	 main,.Lfe1-main
	.comm	one,50,1
	.comm	two,50,1
	.ident	"GCC: (GNU) egcs-2.92.32 19981220 (gcc2 ss-980609 experimental)"
------------------------------

This is because egcs erroneously considers the address of a variable as a
compile time constant.  But things don't work that way.  By contrast, gcc
2.8.1 is doing it right:

------------------------------
	.file	"const.c"
	.version	"01.01"
gcc2_compiled.:
.globl memcpy
.text
	.align 	2
.globl main
	.type	 main,@function
main:
	link.w %a6,#0
	pea two
	pea one
	jbsr strcpy
	clr.l %d0
	unlk %a6
	rts
.Lfe1:
	.size	 main,.Lfe1-main
	.comm	one,50,1
	.comm	two,50,1
	.ident	"GCC: (GNU) 2.8.1"
------------------------------

1998-12-27  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* expr.c (expand_builtin, case BUILT_IN_CONSTANT_P): Return true
	only for compile-time constants.
	* cse.c (fold_rtx): Check that the argument of CONSTANT_P_RTX is a
	compile-time constant.

--- egcs-2.92/gcc/cse.c.~1~	Mon Dec 14 20:33:16 1998
+++ egcs-2.92/gcc/cse.c	Mon Dec 14 21:07:41 1998
@@ -5854,7 +5854,12 @@
     case 'x':
       /* Always eliminate CONSTANT_P_RTX at this stage. */
       if (code == CONSTANT_P_RTX)
-	return (const_arg0 ? const1_rtx : const0_rtx);
+	return ((const_arg0
+		 && (GET_CODE (const_arg0) == CONST_INT
+		     || GET_CODE (const_arg0) == CONST_DOUBLE
+		     || (GET_CODE (const_arg0) == SYMBOL_REF
+			 && CONSTANT_POOL_ADDRESS_P (const_arg0))))
+		? const1_rtx : const0_rtx);
       break;
     }
 
--- egcs-2.92/gcc/expr.c.~1~	Mon Dec 21 19:16:24 1998
+++ egcs-2.92/gcc/expr.c	Mon Dec 21 20:15:10 1998
@@ -9011,8 +9011,12 @@
 	{
 	  tree arg = TREE_VALUE (arglist);
 
-	  STRIP_NOPS (arg);
-	  if (really_constant_p (arg)
+	  /* This is not quite the same as STRIP_NOPS.  It does more.  */
+	  while (TREE_CODE (arg) == NOP_EXPR
+		 || TREE_CODE (arg) == CONVERT_EXPR
+		 || TREE_CODE (arg) == NON_LVALUE_EXPR)
+	    arg = TREE_OPERAND (arg, 0);
+	  if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'c'
 	      || (TREE_CODE (arg) == ADDR_EXPR
 		  && TREE_CODE (TREE_OPERAND (arg, 0)) == STRING_CST))
 	    return const1_rtx;

-- 
Andreas Schwab                                      "And now for something
schwab@issan.cs.uni-dortmund.de                      completely different"
schwab@gnu.org


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]