On May 20, 2018 11:01:54 AM GMT+02:00, Allan Sandfeld Jensen <li...@carewolf.com> wrote: >A little over a year back we had a regression in a point release of gcc > >because the builtin __builtin_clzs got removed from i386, in part >because it >is was wrongly named for a target specific builtin, but we were using >it in Qt >since it existed in multiple compilers. I got the patch removing it >partially >reverted and the problem solved, but in the meantime I had worked on a >patch >to make it a generic builtin instead. I have rebased it and added it >below, >should I clean it up futher, finish the other builtins add tests and >propose >it, or is this not something we want?
Can't users simply do clz((unsigned short) s) - 16? GCC should be able to handle this for instruction selection With The addition of some folding patterns using the corresponding internal function. Richard. >diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def >index 5365befd351..74a84e653e4 100644 >--- a/gcc/builtin-types.def >+++ b/gcc/builtin-types.def >@@ -232,6 +232,8 @@ DEF_FUNCTION_TYPE_1 (BT_FN_INT_LONG, BT_INT, >BT_LONG) > DEF_FUNCTION_TYPE_1 (BT_FN_INT_ULONG, BT_INT, BT_ULONG) > DEF_FUNCTION_TYPE_1 (BT_FN_INT_LONGLONG, BT_INT, BT_LONGLONG) > DEF_FUNCTION_TYPE_1 (BT_FN_INT_ULONGLONG, BT_INT, BT_ULONGLONG) >+DEF_FUNCTION_TYPE_1 (BT_FN_INT_INT16, BT_INT, BT_INT16) >+DEF_FUNCTION_TYPE_1 (BT_FN_INT_UINT16, BT_INT, BT_UINT16) > DEF_FUNCTION_TYPE_1 (BT_FN_INT_INTMAX, BT_INT, BT_INTMAX) > DEF_FUNCTION_TYPE_1 (BT_FN_INT_UINTMAX, BT_INT, BT_UINTMAX) > DEF_FUNCTION_TYPE_1 (BT_FN_INT_PTR, BT_INT, BT_PTR) >diff --git a/gcc/builtins.c b/gcc/builtins.c >index 9a2bf8c7d38..a8ad00e8016 100644 >--- a/gcc/builtins.c >+++ b/gcc/builtins.c >@@ -10689,14 +10689,17 @@ is_inexpensive_builtin (tree decl) > case BUILT_IN_CLZIMAX: > case BUILT_IN_CLZL: > case BUILT_IN_CLZLL: >+ case BUILT_IN_CLZS: > case BUILT_IN_CTZ: > case BUILT_IN_CTZIMAX: > case BUILT_IN_CTZL: > case BUILT_IN_CTZLL: >+ case BUILT_IN_CTZS: > case BUILT_IN_FFS: > case BUILT_IN_FFSIMAX: > case BUILT_IN_FFSL: > case BUILT_IN_FFSLL: >+ case BUILT_IN_FFSS: > case BUILT_IN_IMAXABS: > case BUILT_IN_FINITE: > case BUILT_IN_FINITEF: >@@ -10734,10 +10737,12 @@ is_inexpensive_builtin (tree decl) > case BUILT_IN_POPCOUNTL: > case BUILT_IN_POPCOUNTLL: > case BUILT_IN_POPCOUNTIMAX: >+ case BUILT_IN_POPCOUNTS: > case BUILT_IN_POPCOUNT: > case BUILT_IN_PARITYL: > case BUILT_IN_PARITYLL: > case BUILT_IN_PARITYIMAX: >+ case BUILT_IN_PARITYS: > case BUILT_IN_PARITY: > case BUILT_IN_LABS: > case BUILT_IN_LLABS: >diff --git a/gcc/builtins.def b/gcc/builtins.def >index 449d08d682f..618ee798767 100644 >--- a/gcc/builtins.def >+++ b/gcc/builtins.def >@@ -848,15 +848,18 @@ DEF_GCC_BUILTIN (BUILT_IN_CLZ, "clz", >BT_FN_INT_UINT, ATTR_CONST_NOTHROW_ >DEF_GCC_BUILTIN (BUILT_IN_CLZIMAX, "clzimax", BT_FN_INT_UINTMAX, > >ATTR_CONST_NOTHROW_LEAF_LIST) > DEF_GCC_BUILTIN (BUILT_IN_CLZL, "clzl", BT_FN_INT_ULONG, >ATTR_CONST_NOTHROW_LEAF_LIST) > DEF_GCC_BUILTIN (BUILT_IN_CLZLL, "clzll", BT_FN_INT_ULONGLONG, >ATTR_CONST_NOTHROW_LEAF_LIST) >+DEF_GCC_BUILTIN (BUILT_IN_CLZS, "clzs", BT_FN_INT_UINT16, >ATTR_CONST_NOTHROW_LEAF_LIST) >DEF_GCC_BUILTIN (BUILT_IN_CONSTANT_P, "constant_p", >BT_FN_INT_VAR, >ATTR_CONST_NOTHROW_LEAF_LIST) > DEF_GCC_BUILTIN (BUILT_IN_CTZ, "ctz", BT_FN_INT_UINT, >ATTR_CONST_NOTHROW_LEAF_LIST) >DEF_GCC_BUILTIN (BUILT_IN_CTZIMAX, "ctzimax", BT_FN_INT_UINTMAX, > >ATTR_CONST_NOTHROW_LEAF_LIST) > DEF_GCC_BUILTIN (BUILT_IN_CTZL, "ctzl", BT_FN_INT_ULONG, >ATTR_CONST_NOTHROW_LEAF_LIST) > DEF_GCC_BUILTIN (BUILT_IN_CTZLL, "ctzll", BT_FN_INT_ULONGLONG, >ATTR_CONST_NOTHROW_LEAF_LIST) >+DEF_GCC_BUILTIN (BUILT_IN_CTZS, "ctzs", BT_FN_INT_UINT16, >ATTR_CONST_NOTHROW_LEAF_LIST) > DEF_GCC_BUILTIN (BUILT_IN_CLRSB, "clrsb", BT_FN_INT_INT, >ATTR_CONST_NOTHROW_LEAF_LIST) >DEF_GCC_BUILTIN (BUILT_IN_CLRSBIMAX, "clrsbimax", >BT_FN_INT_INTMAX, >ATTR_CONST_NOTHROW_LEAF_LIST) > DEF_GCC_BUILTIN (BUILT_IN_CLRSBL, "clrsbl", BT_FN_INT_LONG, >ATTR_CONST_NOTHROW_LEAF_LIST) >DEF_GCC_BUILTIN (BUILT_IN_CLRSBLL, "clrsbll", >BT_FN_INT_LONGLONG, >ATTR_CONST_NOTHROW_LEAF_LIST) >+DEF_GCC_BUILTIN (BUILT_IN_CLRSBS, "clrsbs", BT_FN_INT_INT16, >ATTR_CONST_NOTHROW_LEAF_LIST) > DEF_EXT_LIB_BUILTIN (BUILT_IN_DCGETTEXT, "dcgettext", >BT_FN_STRING_CONST_STRING_CONST_STRING_INT, ATTR_FORMAT_ARG_2) > DEF_EXT_LIB_BUILTIN (BUILT_IN_DGETTEXT, "dgettext", >BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_FORMAT_ARG_2) > DEF_GCC_BUILTIN (BUILT_IN_DWARF_CFA, "dwarf_cfa", BT_FN_PTR, >ATTR_NULL) >@@ -878,6 +881,7 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_FFS, "ffs", >BT_FN_INT_INT, ATTR_CONST_NOTHROW_L >DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSIMAX, "ffsimax", BT_FN_INT_INTMAX, >ATTR_CONST_NOTHROW_LEAF_LIST) > DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSL, "ffsl", BT_FN_INT_LONG, >ATTR_CONST_NOTHROW_LEAF_LIST) > DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSLL, "ffsll", BT_FN_INT_LONGLONG, >ATTR_CONST_NOTHROW_LEAF_LIST) >+DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSS, "ffss", BT_FN_INT_INT16, >ATTR_CONST_NOTHROW_LEAF_LIST) > DEF_EXT_LIB_BUILTIN (BUILT_IN_FORK, "fork", BT_FN_PID, >ATTR_NOTHROW_LIST) > DEF_GCC_BUILTIN (BUILT_IN_FRAME_ADDRESS, "frame_address", >BT_FN_PTR_UINT, ATTR_NULL) >/* [trans-mem]: Adjust BUILT_IN_TM_FREE if BUILT_IN_FREE is changed. >*/ >@@ -924,10 +928,12 @@ DEF_GCC_BUILTIN (BUILT_IN_PARITY, >"parity", >BT_FN_INT_UINT, ATTR_CONST_NO >DEF_GCC_BUILTIN (BUILT_IN_PARITYIMAX, "parityimax", >BT_FN_INT_UINTMAX, >ATTR_CONST_NOTHROW_LEAF_LIST) > DEF_GCC_BUILTIN (BUILT_IN_PARITYL, "parityl", BT_FN_INT_ULONG, >ATTR_CONST_NOTHROW_LEAF_LIST) >DEF_GCC_BUILTIN (BUILT_IN_PARITYLL, "parityll", >BT_FN_INT_ULONGLONG, >ATTR_CONST_NOTHROW_LEAF_LIST) >+DEF_GCC_BUILTIN (BUILT_IN_PARITYS, "paritys", BT_FN_INT_UINT16, > >ATTR_CONST_NOTHROW_LEAF_LIST) >DEF_GCC_BUILTIN (BUILT_IN_POPCOUNT, "popcount", BT_FN_INT_UINT, >ATTR_CONST_NOTHROW_LEAF_LIST) > DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTIMAX, "popcountimax", >BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST) >DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTL, "popcountl", >BT_FN_INT_ULONG, >ATTR_CONST_NOTHROW_LEAF_LIST) > DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTLL, "popcountll", >BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST) >+DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTS, "popcounts", >BT_FN_INT_UINT16, >ATTR_CONST_NOTHROW_LEAF_LIST) > DEF_EXT_LIB_BUILTIN (BUILT_IN_POSIX_MEMALIGN, "posix_memalign", >BT_FN_INT_PTRPTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) > DEF_GCC_BUILTIN (BUILT_IN_PREFETCH, "prefetch", >BT_FN_VOID_CONST_PTR_VAR, ATTR_NOVOPS_LEAF_LIST) >DEF_LIB_BUILTIN (BUILT_IN_REALLOC, "realloc", >BT_FN_PTR_PTR_SIZE, >ATTR_ALLOC_SIZE_2_NOTHROW_LEAF_LIST) >diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386- >builtin.def >index 1b9c63a16db..2fb5f3000ed 100644 >--- a/gcc/config/i386/i386-builtin.def >+++ b/gcc/config/i386/i386-builtin.def >@@ -1228,8 +1228,6 @@ BDESC (OPTION_MASK_ISA_AVX2, >CODE_FOR_avx2_lshrvv4si, >"__builtin_ia32_psrlv4si", > > /* LZCNT */ >BDESC (OPTION_MASK_ISA_LZCNT, CODE_FOR_lzcnt_hi, >"__builtin_ia32_lzcnt_u16", >IX86_BUILTIN_LZCNT16, UNKNOWN, (int) UINT16_FTYPE_UINT16) >-/* Same as above, for backward compatibility. */ >-BDESC (OPTION_MASK_ISA_LZCNT, CODE_FOR_lzcnt_hi, "__builtin_clzs", >IX86_BUILTIN_CLZS, UNKNOWN, (int) UINT16_FTYPE_UINT16) >BDESC (OPTION_MASK_ISA_LZCNT, CODE_FOR_lzcnt_si, >"__builtin_ia32_lzcnt_u32", >IX86_BUILTIN_LZCNT32, UNKNOWN, (int) UINT_FTYPE_UINT) >BDESC (OPTION_MASK_ISA_LZCNT | OPTION_MASK_ISA_64BIT, >CODE_FOR_lzcnt_di, >"__builtin_ia32_lzcnt_u64", IX86_BUILTIN_LZCNT64, UNKNOWN, (int) >UINT64_FTYPE_UINT64) > >@@ -1238,8 +1236,6 @@ BDESC (OPTION_MASK_ISA_BMI, >CODE_FOR_bmi_bextr_si, >"__builtin_ia32_bextr_u32", I >BDESC (OPTION_MASK_ISA_BMI | OPTION_MASK_ISA_64BIT, >CODE_FOR_bmi_bextr_di, >"__builtin_ia32_bextr_u64", IX86_BUILTIN_BEXTR64, UNKNOWN, (int) >UINT64_FTYPE_UINT64_UINT64) > >BDESC (OPTION_MASK_ISA_BMI, CODE_FOR_tzcnt_hi, >"__builtin_ia32_tzcnt_u16", >IX86_BUILTIN_TZCNT16, UNKNOWN, (int) UINT16_FTYPE_UINT16) >-/* Same as above, for backward compatibility. */ >-BDESC (OPTION_MASK_ISA_BMI, CODE_FOR_tzcnt_hi, "__builtin_ctzs", >IX86_BUILTIN_CTZS, UNKNOWN, (int) UINT16_FTYPE_UINT16) >BDESC (OPTION_MASK_ISA_BMI, CODE_FOR_tzcnt_si, >"__builtin_ia32_tzcnt_u32", >IX86_BUILTIN_TZCNT32, UNKNOWN, (int) UINT_FTYPE_UINT) >BDESC (OPTION_MASK_ISA_BMI | OPTION_MASK_ISA_64BIT, CODE_FOR_tzcnt_di, >"__builtin_ia32_tzcnt_u64", IX86_BUILTIN_TZCNT64, UNKNOWN, (int) >UINT64_FTYPE_UINT64) > >diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c >index 184b721dbf3..4c65c16b91d 100644 >--- a/gcc/config/i386/i386.c >+++ b/gcc/config/i386/i386.c >@@ -33430,7 +33430,6 @@ ix86_fold_builtin (tree fndecl, int n_args, > } > > case IX86_BUILTIN_TZCNT16: >- case IX86_BUILTIN_CTZS: > case IX86_BUILTIN_TZCNT32: > case IX86_BUILTIN_TZCNT64: > gcc_assert (n_args == 1); >@@ -33438,8 +33437,7 @@ ix86_fold_builtin (tree fndecl, int n_args, > { > tree type = TREE_TYPE (TREE_TYPE (fndecl)); > tree arg = args[0]; >- if (fn_code == IX86_BUILTIN_TZCNT16 >- || fn_code == IX86_BUILTIN_CTZS) >+ if (fn_code == IX86_BUILTIN_TZCNT16) > arg = fold_convert (short_unsigned_type_node, arg); > if (integer_zerop (arg)) > return build_int_cst (type, TYPE_PRECISION (TREE_TYPE (arg))); >@@ -33449,7 +33447,6 @@ ix86_fold_builtin (tree fndecl, int n_args, > break; > > case IX86_BUILTIN_LZCNT16: >- case IX86_BUILTIN_CLZS: > case IX86_BUILTIN_LZCNT32: > case IX86_BUILTIN_LZCNT64: > gcc_assert (n_args == 1); >@@ -33457,8 +33454,7 @@ ix86_fold_builtin (tree fndecl, int n_args, > { > tree type = TREE_TYPE (TREE_TYPE (fndecl)); > tree arg = args[0]; >- if (fn_code == IX86_BUILTIN_LZCNT16 >- || fn_code == IX86_BUILTIN_CLZS) >+ if (fn_code == IX86_BUILTIN_LZCNT16) > arg = fold_convert (short_unsigned_type_node, arg); > if (integer_zerop (arg)) > return build_int_cst (type, TYPE_PRECISION (TREE_TYPE (arg))); >@@ -33867,6 +33863,10 @@ ix86_gimple_fold_builtin (gimple_stmt_iterator >*gsi) > > switch (fn_code) > { >+ case IX86_BUILTIN_TZCNT16: >+ decl = builtin_decl_implicit (BUILT_IN_CTZS); >+ goto fold_tzcnt_lzcnt; >+ > case IX86_BUILTIN_TZCNT32: > decl = builtin_decl_implicit (BUILT_IN_CTZ); > goto fold_tzcnt_lzcnt; >@@ -33875,6 +33875,10 @@ ix86_gimple_fold_builtin (gimple_stmt_iterator >*gsi) > decl = builtin_decl_implicit (BUILT_IN_CTZLL); > goto fold_tzcnt_lzcnt; > >+ case IX86_BUILTIN_LZCNT16: >+ decl = builtin_decl_implicit (BUILT_IN_CLZS); >+ goto fold_tzcnt_lzcnt; >+ > case IX86_BUILTIN_LZCNT32: > decl = builtin_decl_implicit (BUILT_IN_CLZ); > goto fold_tzcnt_lzcnt; >diff --git a/gcc/gencfn-macros.c b/gcc/gencfn-macros.c >index 28f7b6f7298..d2edceb0a2e 100644 >--- a/gcc/gencfn-macros.c >+++ b/gcc/gencfn-macros.c >@@ -160,7 +160,7 @@ static const char *const fltfn_suffixes[] = { >"F16", >"F32", "F64", "F128", >static const char *const fltall_suffixes[] = { "F", "", "L", "F16", >"F32", > "F64", "F128", "F32X", "F64X", > "F128X", NULL }; >-static const char *const int_suffixes[] = { "", "L", "LL", "IMAX", >NULL }; >+static const char *const int_suffixes[] = { "", "L", "LL", "S", >"IMAX", NULL >}; > > static const char *const *const suffix_lists[] = { > flt_suffixes, >diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c >index 74d5f07b3cb..00f783b883d 100644 >--- a/gcc/hsa-gen.c >+++ b/gcc/hsa-gen.c >@@ -5390,12 +5390,14 @@ gen_hsa_insns_for_call (gimple *stmt, hsa_bb >*hbb) > case BUILT_IN_CLZ: > case BUILT_IN_CLZL: > case BUILT_IN_CLZLL: >+ case BUILT_IN_CLZS: > gen_hsa_unaryop_for_builtin (BRIG_OPCODE_FIRSTBIT, stmt, hbb); > break; > > case BUILT_IN_CTZ: > case BUILT_IN_CTZL: > case BUILT_IN_CTZLL: >+ case BUILT_IN_CTZS: > gen_hsa_unaryop_for_builtin (BRIG_OPCODE_LASTBIT, stmt, hbb); > break; > >diff --git a/gcc/tree.h b/gcc/tree.h >index ef8bff405fe..9b43238eebf 100644 >--- a/gcc/tree.h >+++ b/gcc/tree.h >@@ -217,7 +217,7 @@ as_internal_fn (combined_fn code) > case FN##F16: case FN##F32: case FN##F64: case FN##F128: \ > case FN##F32X: case FN##F64X: case FN##F128X > #define CASE_FLT_FN_REENT(FN) case FN##_R: case FN##F_R: case FN##L_R >-#define CASE_INT_FN(FN) case FN: case FN##L: case FN##LL: case >FN##IMAX >+#define CASE_INT_FN(FN) case FN: case FN##L: case FN##LL: case FN##S: >case >FN##IMAX > > #define NULL_TREE (tree) NULL >