re PR other/31852 (Missing __builtin_memchr)
2007-05-11 Paolo Carlini <pcarlini@suse.de> PR other/31852 * builtin-types.def: Add BT_FN_PTR_CONST_PTR_INT_SIZE. * builtins.def: Add BUILT_IN_MEMCHR, use the latter. * builtins.c (fold_builtin_memchr): New. (expand_builtin_memchr): Call the latter. (expand_builtin, fold_builtin_3): Deal with BUILT_IN_MEMCHR. * doc/extend.texi ([Other built-in functions provided by GCC]): Document memchr. /testsuite 2007-05-11 Paolo Carlini <pcarlini@suse.de> PR other/31852 * gcc.c-torture/execute/builtins/memchr.c: New. * gcc.c-torture/execute/builtins/memchr-lib.c: New. * gcc.c-torture/execute/builtins/lib/memchr.c: New. From-SVN: r124617
This commit is contained in:
parent
fc2d8680dd
commit
2a5fce6d48
9 changed files with 164 additions and 9 deletions
|
@ -1,3 +1,14 @@
|
|||
2007-05-11 Paolo Carlini <pcarlini@suse.de>
|
||||
|
||||
PR other/31852
|
||||
* builtin-types.def: Add BT_FN_PTR_CONST_PTR_INT_SIZE.
|
||||
* builtins.def: Add BUILT_IN_MEMCHR, use the latter.
|
||||
* builtins.c (fold_builtin_memchr): New.
|
||||
(expand_builtin_memchr): Call the latter.
|
||||
(expand_builtin, fold_builtin_3): Deal with BUILT_IN_MEMCHR.
|
||||
* doc/extend.texi ([Other built-in functions provided by GCC]):
|
||||
Document memchr.
|
||||
|
||||
2007-05-11 Andreas Krebbel <krebbel1@de.ibm.com>
|
||||
|
||||
* config/s390/s390.md (GPR0_REGNUM, FPR0_REGNUM, FPR2_REGNUM,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
|
||||
/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
@ -371,6 +371,8 @@ DEF_FUNCTION_TYPE_3 (BT_FN_I16_VPTR_I16_I16, BT_I16, BT_VOLATILE_PTR,
|
|||
BT_I16, BT_I16)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_OMPFN_PTR_UINT, BT_VOID, BT_PTR_FN_VOID_PTR,
|
||||
BT_PTR, BT_UINT)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_PTR_CONST_PTR_INT_SIZE, BT_PTR,
|
||||
BT_CONST_PTR, BT_INT, BT_SIZE)
|
||||
|
||||
DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR,
|
||||
BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_FILEPTR)
|
||||
|
|
|
@ -105,6 +105,7 @@ static rtx expand_builtin_next_arg (void);
|
|||
static rtx expand_builtin_va_start (tree);
|
||||
static rtx expand_builtin_va_end (tree);
|
||||
static rtx expand_builtin_va_copy (tree);
|
||||
static rtx expand_builtin_memchr (tree, rtx, enum machine_mode);
|
||||
static rtx expand_builtin_memcmp (tree, rtx, enum machine_mode);
|
||||
static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
|
||||
static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
|
||||
|
@ -172,6 +173,7 @@ static tree fold_builtin_int_roundingfn (tree, tree);
|
|||
static tree fold_builtin_bitop (tree, tree);
|
||||
static tree fold_builtin_memory_op (tree, tree, tree, tree, bool, int);
|
||||
static tree fold_builtin_strchr (tree, tree, tree);
|
||||
static tree fold_builtin_memchr (tree, tree, tree, tree);
|
||||
static tree fold_builtin_memcmp (tree, tree, tree);
|
||||
static tree fold_builtin_strcmp (tree, tree);
|
||||
static tree fold_builtin_strncmp (tree, tree, tree);
|
||||
|
@ -3978,6 +3980,26 @@ expand_builtin_bzero (tree exp)
|
|||
const0_rtx, VOIDmode, exp);
|
||||
}
|
||||
|
||||
/* Expand a call to the memchr builtin. Return NULL_RTX if we failed the
|
||||
caller should emit a normal call, otherwise try to get the result
|
||||
in TARGET, if convenient (and in mode MODE if that's convenient). */
|
||||
|
||||
static rtx
|
||||
expand_builtin_memchr (tree exp, rtx target, enum machine_mode mode)
|
||||
{
|
||||
if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE,
|
||||
INTEGER_TYPE, VOID_TYPE))
|
||||
{
|
||||
tree type = TREE_TYPE (exp);
|
||||
tree result = fold_builtin_memchr (CALL_EXPR_ARG (exp, 0),
|
||||
CALL_EXPR_ARG (exp, 1),
|
||||
CALL_EXPR_ARG (exp, 2), type);
|
||||
if (result)
|
||||
return expand_expr (result, target, mode, EXPAND_NORMAL);
|
||||
}
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
||||
/* Expand expression EXP, which is a call to the memcmp built-in function.
|
||||
Return NULL_RTX if we failed and the
|
||||
caller should emit a normal call, otherwise try to get the result in
|
||||
|
@ -6345,6 +6367,12 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
|
|||
return target;
|
||||
break;
|
||||
|
||||
case BUILT_IN_MEMCHR:
|
||||
target = expand_builtin_memchr (exp, target, mode);
|
||||
if (target)
|
||||
return target;
|
||||
break;
|
||||
|
||||
case BUILT_IN_BCMP:
|
||||
case BUILT_IN_MEMCMP:
|
||||
target = expand_builtin_memcmp (exp, target, mode);
|
||||
|
@ -8654,6 +8682,48 @@ fold_builtin_strncpy (tree fndecl, tree dest, tree src, tree len, tree slen)
|
|||
build_call_expr (fn, 3, dest, src, len));
|
||||
}
|
||||
|
||||
/* Fold function call to builtin memchr. ARG1, ARG2 and LEN are the
|
||||
arguments to the call, and TYPE is its return type.
|
||||
Return NULL_TREE if no simplification can be made. */
|
||||
|
||||
static tree
|
||||
fold_builtin_memchr (tree arg1, tree arg2, tree len, tree type)
|
||||
{
|
||||
if (!validate_arg (arg1, POINTER_TYPE)
|
||||
|| !validate_arg (arg2, INTEGER_TYPE)
|
||||
|| !validate_arg (len, INTEGER_TYPE))
|
||||
return NULL_TREE;
|
||||
else
|
||||
{
|
||||
const char *p1;
|
||||
|
||||
if (TREE_CODE (arg2) != INTEGER_CST
|
||||
|| !host_integerp (len, 1))
|
||||
return NULL_TREE;
|
||||
|
||||
p1 = c_getstr (arg1);
|
||||
if (p1 && compare_tree_int (len, strlen (p1) + 1) <= 0)
|
||||
{
|
||||
char c;
|
||||
const char *r;
|
||||
tree tem;
|
||||
|
||||
if (target_char_cast (arg2, &c))
|
||||
return NULL_TREE;
|
||||
|
||||
r = memchr (p1, c, tree_low_cst (len, 1));
|
||||
|
||||
if (r == NULL)
|
||||
return build_int_cst (TREE_TYPE (arg1), 0);
|
||||
|
||||
tem = fold_build2 (PLUS_EXPR, TREE_TYPE (arg1), arg1,
|
||||
build_int_cst (TREE_TYPE (arg1), r - p1));
|
||||
return fold_convert (type, tem);
|
||||
}
|
||||
return NULL_TREE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fold function call to builtin memcmp with arguments ARG1 and ARG2.
|
||||
Return NULL_TREE if no simplification can be made. */
|
||||
|
||||
|
@ -9983,6 +10053,9 @@ fold_builtin_3 (tree fndecl, tree arg0, tree arg1, tree arg2, bool ignore)
|
|||
case BUILT_IN_STRNCMP:
|
||||
return fold_builtin_strncmp (arg0, arg1, arg2);
|
||||
|
||||
case BUILT_IN_MEMCHR:
|
||||
return fold_builtin_memchr (arg0, arg1, arg2, type);
|
||||
|
||||
case BUILT_IN_BCMP:
|
||||
case BUILT_IN_MEMCMP:
|
||||
return fold_builtin_memcmp (arg0, arg1, arg2);;
|
||||
|
|
|
@ -502,6 +502,7 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_BCMP, "bcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZ
|
|||
DEF_EXT_LIB_BUILTIN (BUILT_IN_BCOPY, "bcopy", BT_FN_VOID_CONST_PTR_PTR_SIZE, ATTR_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_BZERO, "bzero", BT_FN_VOID_PTR_SIZE, ATTR_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_INDEX, "index", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MEMCHR, "memchr", BT_FN_PTR_CONST_PTR_INT_SIZE, ATTR_PURE_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MEMCMP, "memcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MEMCPY, "memcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MEMMOVE, "memmove", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL)
|
||||
|
|
|
@ -5592,6 +5592,7 @@ should be called and the @var{flag} argument passed to it.
|
|||
@findex lroundf
|
||||
@findex lroundl
|
||||
@findex malloc
|
||||
@findex memchr
|
||||
@findex memcmp
|
||||
@findex memcpy
|
||||
@findex mempcpy
|
||||
|
@ -5836,14 +5837,14 @@ The ISO C90 functions
|
|||
@code{isgraph}, @code{islower}, @code{isprint}, @code{ispunct},
|
||||
@code{isspace}, @code{isupper}, @code{isxdigit}, @code{tolower},
|
||||
@code{toupper}, @code{labs}, @code{ldexp}, @code{log10}, @code{log},
|
||||
@code{malloc}, @code{memcmp}, @code{memcpy}, @code{memset}, @code{modf},
|
||||
@code{pow}, @code{printf}, @code{putchar}, @code{puts}, @code{scanf},
|
||||
@code{sinh}, @code{sin}, @code{snprintf}, @code{sprintf}, @code{sqrt},
|
||||
@code{sscanf}, @code{strcat}, @code{strchr}, @code{strcmp},
|
||||
@code{strcpy}, @code{strcspn}, @code{strlen}, @code{strncat},
|
||||
@code{strncmp}, @code{strncpy}, @code{strpbrk}, @code{strrchr},
|
||||
@code{strspn}, @code{strstr}, @code{tanh}, @code{tan}, @code{vfprintf},
|
||||
@code{vprintf} and @code{vsprintf}
|
||||
@code{malloc}, @code{memchr}, @code{memcmp}, @code{memcpy},
|
||||
@code{memset}, @code{modf}, @code{pow}, @code{printf}, @code{putchar},
|
||||
@code{puts}, @code{scanf}, @code{sinh}, @code{sin}, @code{snprintf},
|
||||
@code{sprintf}, @code{sqrt}, @code{sscanf}, @code{strcat},
|
||||
@code{strchr}, @code{strcmp}, @code{strcpy}, @code{strcspn},
|
||||
@code{strlen}, @code{strncat}, @code{strncmp}, @code{strncpy},
|
||||
@code{strpbrk}, @code{strrchr}, @code{strspn}, @code{strstr},
|
||||
@code{tanh}, @code{tan}, @code{vfprintf}, @code{vprintf} and @code{vsprintf}
|
||||
are all recognized as built-in functions unless
|
||||
@option{-fno-builtin} is specified (or @option{-fno-builtin-@var{function}}
|
||||
is specified for an individual function). All of these functions have
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2007-05-11 Paolo Carlini <pcarlini@suse.de>
|
||||
|
||||
PR other/31852
|
||||
* gcc.c-torture/execute/builtins/memchr.c: New.
|
||||
* gcc.c-torture/execute/builtins/memchr-lib.c: New.
|
||||
* gcc.c-torture/execute/builtins/lib/memchr.c: New.
|
||||
|
||||
2007-05-11 Paul Thomas <pault@gcc.gnu.org>
|
||||
|
||||
PR fortran/30876
|
||||
|
|
21
gcc/testsuite/gcc.c-torture/execute/builtins/lib/memchr.c
Normal file
21
gcc/testsuite/gcc.c-torture/execute/builtins/lib/memchr.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
extern void abort(void);
|
||||
extern int inside_main;
|
||||
|
||||
void *
|
||||
memchr (const void *s, int c, __SIZE_TYPE__ n)
|
||||
{
|
||||
const unsigned char uc = c;
|
||||
const unsigned char *sp;
|
||||
|
||||
#ifdef __OPTIMIZE__
|
||||
if (inside_main)
|
||||
abort ();
|
||||
#endif
|
||||
|
||||
sp = s;
|
||||
for (; n != 0; ++sp, --n)
|
||||
if (*sp == uc)
|
||||
return (void *) sp;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
#include "lib/memchr.c"
|
38
gcc/testsuite/gcc.c-torture/execute/builtins/memchr.c
Normal file
38
gcc/testsuite/gcc.c-torture/execute/builtins/memchr.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* Copyright (C) 2007 Free Software Foundation.
|
||||
|
||||
Ensure all expected transformations of builtin memchr occur
|
||||
and perform correctly.
|
||||
|
||||
Written by Paolo Carlini, 10/5/2007. */
|
||||
|
||||
extern void abort (void);
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
extern void *memchr (const void *, int, size_t);
|
||||
|
||||
void
|
||||
main_test (void)
|
||||
{
|
||||
const char* const foo1 = "hello world";
|
||||
|
||||
if (memchr (foo1, 'x', 11))
|
||||
abort ();
|
||||
if (memchr (foo1, 'o', 11) != foo1 + 4)
|
||||
abort ();
|
||||
if (memchr (foo1, 'w', 2))
|
||||
abort ();
|
||||
if (memchr (foo1 + 5, 'o', 6) != foo1 + 7)
|
||||
abort ();
|
||||
if (memchr (foo1, 'd', 11) != foo1 + 10)
|
||||
abort ();
|
||||
if (memchr (foo1, 'd', 10))
|
||||
abort ();
|
||||
if (memchr (foo1, '\0', 11))
|
||||
abort ();
|
||||
if (memchr (foo1, '\0', 12) != foo1 + 11)
|
||||
abort ();
|
||||
|
||||
/* Test at least one instance of the __builtin_ style. We do this
|
||||
to ensure that it works and that the prototype is correct. */
|
||||
if (__builtin_memchr (foo1, 'r', 11) != foo1 + 8)
|
||||
abort ();
|
||||
}
|
Loading…
Add table
Reference in a new issue