Commit 9c4c8b7b by Jakub Jelinek Committed by Jakub Jelinek

re PR target/78057 (FAIL: gcc.target/i386/bmi-{4,5,6}.c)

	PR target/78057
	* config/i386/i386.c: Include fold-const-call.h, tree-vrp.h
	and tree-ssanames.h.
	(ix86_fold_builtin): Fold IX86_BUILTIN_[LT]ZCNT{16,32,64}
	with INTEGER_CST argument.
	(ix86_gimple_fold_builtin): New function.
	(TARGET_GIMPLE_FOLD_BUILTIN): Define.

	* gcc.target/i386/pr78057.c: New test.

From-SVN: r241411
parent c05986b9
2016-10-21 Jakub Jelinek <jakub@redhat.com> 2016-10-21 Jakub Jelinek <jakub@redhat.com>
PR target/78057
* config/i386/i386.c: Include fold-const-call.h, tree-vrp.h
and tree-ssanames.h.
(ix86_fold_builtin): Fold IX86_BUILTIN_[LT]ZCNT{16,32,64}
with INTEGER_CST argument.
(ix86_gimple_fold_builtin): New function.
(TARGET_GIMPLE_FOLD_BUILTIN): Define.
* dwarf2out.c (ranges_table): Change into vec<dw_ranges, va_gc> *. * dwarf2out.c (ranges_table): Change into vec<dw_ranges, va_gc> *.
(ranges_by_label): Change into vec<dw_ranges_by_label, va_gc> *. (ranges_by_label): Change into vec<dw_ranges_by_label, va_gc> *.
(ranges_table_allocated, ranges_table_in_use, (ranges_table_allocated, ranges_table_in_use,
......
...@@ -77,6 +77,9 @@ along with GCC; see the file COPYING3. If not see ...@@ -77,6 +77,9 @@ along with GCC; see the file COPYING3. If not see
#include "case-cfn-macros.h" #include "case-cfn-macros.h"
#include "regrename.h" #include "regrename.h"
#include "dojump.h" #include "dojump.h"
#include "fold-const-call.h"
#include "tree-vrp.h"
#include "tree-ssanames.h"
/* This file should be included last. */ /* This file should be included last. */
#include "target-def.h" #include "target-def.h"
...@@ -33332,6 +33335,40 @@ ix86_fold_builtin (tree fndecl, int n_args, ...@@ -33332,6 +33335,40 @@ ix86_fold_builtin (tree fndecl, int n_args,
return build_real (type, inf); return build_real (type, inf);
} }
case IX86_BUILTIN_TZCNT16:
case IX86_BUILTIN_TZCNT32:
case IX86_BUILTIN_TZCNT64:
gcc_assert (n_args == 1);
if (TREE_CODE (args[0]) == INTEGER_CST)
{
tree type = TREE_TYPE (TREE_TYPE (fndecl));
tree arg = args[0];
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)));
else
return fold_const_call (CFN_CTZ, type, arg);
}
break;
case IX86_BUILTIN_LZCNT16:
case IX86_BUILTIN_LZCNT32:
case IX86_BUILTIN_LZCNT64:
gcc_assert (n_args == 1);
if (TREE_CODE (args[0]) == INTEGER_CST)
{
tree type = TREE_TYPE (TREE_TYPE (fndecl));
tree arg = args[0];
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)));
else
return fold_const_call (CFN_CLZ, type, arg);
}
break;
default: default:
break; break;
} }
...@@ -33344,6 +33381,70 @@ ix86_fold_builtin (tree fndecl, int n_args, ...@@ -33344,6 +33381,70 @@ ix86_fold_builtin (tree fndecl, int n_args,
return NULL_TREE; return NULL_TREE;
} }
/* Fold a MD builtin (use ix86_fold_builtin for folding into
constant) in GIMPLE. */
bool
ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi)
{
gimple *stmt = gsi_stmt (*gsi);
tree fndecl = gimple_call_fndecl (stmt);
gcc_checking_assert (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD);
int n_args = gimple_call_num_args (stmt);
enum ix86_builtins fn_code = (enum ix86_builtins) DECL_FUNCTION_CODE (fndecl);
tree decl = NULL_TREE;
tree arg0;
switch (fn_code)
{
case IX86_BUILTIN_TZCNT32:
decl = builtin_decl_implicit (BUILT_IN_CTZ);
goto fold_tzcnt_lzcnt;
case IX86_BUILTIN_TZCNT64:
decl = builtin_decl_implicit (BUILT_IN_CTZLL);
goto fold_tzcnt_lzcnt;
case IX86_BUILTIN_LZCNT32:
decl = builtin_decl_implicit (BUILT_IN_CLZ);
goto fold_tzcnt_lzcnt;
case IX86_BUILTIN_LZCNT64:
decl = builtin_decl_implicit (BUILT_IN_CLZLL);
goto fold_tzcnt_lzcnt;
fold_tzcnt_lzcnt:
gcc_assert (n_args == 1);
arg0 = gimple_call_arg (stmt, 0);
if (TREE_CODE (arg0) == SSA_NAME && decl && gimple_call_lhs (stmt))
{
int prec = TYPE_PRECISION (TREE_TYPE (arg0));
/* If arg0 is provably non-zero, optimize into generic
__builtin_c[tl]z{,ll} function the middle-end handles
better. */
if (!expr_not_equal_to (arg0, wi::zero (prec)))
return false;
location_t loc = gimple_location (stmt);
gimple *g = gimple_build_call (decl, 1, arg0);
gimple_set_location (g, loc);
tree lhs = make_ssa_name (integer_type_node);
gimple_call_set_lhs (g, lhs);
gsi_insert_before (gsi, g, GSI_SAME_STMT);
g = gimple_build_assign (gimple_call_lhs (stmt), NOP_EXPR, lhs);
gimple_set_location (g, loc);
gsi_replace (gsi, g, true);
return true;
}
break;
default:
break;
}
return false;
}
/* Make builtins to detect cpu type and features supported. NAME is /* Make builtins to detect cpu type and features supported. NAME is
the builtin name, CODE is the builtin code, and FTYPE is the function the builtin name, CODE is the builtin code, and FTYPE is the function
type of the builtin. */ type of the builtin. */
...@@ -50531,6 +50632,9 @@ ix86_addr_space_zero_address_valid (addr_space_t as) ...@@ -50531,6 +50632,9 @@ ix86_addr_space_zero_address_valid (addr_space_t as)
#undef TARGET_FOLD_BUILTIN #undef TARGET_FOLD_BUILTIN
#define TARGET_FOLD_BUILTIN ix86_fold_builtin #define TARGET_FOLD_BUILTIN ix86_fold_builtin
#undef TARGET_GIMPLE_FOLD_BUILTIN
#define TARGET_GIMPLE_FOLD_BUILTIN ix86_gimple_fold_builtin
#undef TARGET_COMPARE_VERSION_PRIORITY #undef TARGET_COMPARE_VERSION_PRIORITY
#define TARGET_COMPARE_VERSION_PRIORITY ix86_compare_version_priority #define TARGET_COMPARE_VERSION_PRIORITY ix86_compare_version_priority
2016-10-21 Jakub Jelinek <jakub@redhat.com> 2016-10-21 Jakub Jelinek <jakub@redhat.com>
PR target/78057
* gcc.target/i386/pr78057.c: New test.
* g++.dg/debug/dwarf2/constexpr-var-1.C: New test. * g++.dg/debug/dwarf2/constexpr-var-1.C: New test.
2016-10-21 Paul Thomas <pault@gcc.gnu.org> 2016-10-21 Paul Thomas <pault@gcc.gnu.org>
......
/* PR target/78057 */
/* { dg-do compile } */
/* { dg-options "-O2 -mbmi -mlzcnt -fdump-tree-optimized" } */
extern void link_error (void);
int
foo (int x)
{
if (__builtin_ia32_tzcnt_u16 (16) != 4
|| __builtin_ia32_tzcnt_u16 (0) != 16
|| __builtin_ia32_lzcnt_u16 (0x1ff) != 7
|| __builtin_ia32_lzcnt_u16 (0) != 16
|| __builtin_ia32_tzcnt_u32 (8) != 3
|| __builtin_ia32_tzcnt_u32 (0) != 32
|| __builtin_ia32_lzcnt_u32 (0x3fffffff) != 2
|| __builtin_ia32_lzcnt_u32 (0) != 32
#ifdef __x86_64__
|| __builtin_ia32_tzcnt_u64 (4) != 2
|| __builtin_ia32_tzcnt_u64 (0) != 64
|| __builtin_ia32_lzcnt_u64 (0x1fffffff) != 35
|| __builtin_ia32_lzcnt_u64 (0) != 64
#endif
)
link_error ();
x += 2;
if (x == 0)
return 5;
return __builtin_ia32_tzcnt_u32 (x)
+ __builtin_ia32_lzcnt_u32 (x)
#ifdef __x86_64__
+ __builtin_ia32_tzcnt_u64 (x)
+ __builtin_ia32_lzcnt_u64 (x)
#endif
;
}
/* { dg-final { scan-tree-dump-not "link_error" "optimized" } } */
/* { dg-final { scan-tree-dump-not "__builtin_ia32_\[lt]zcnt" "optimized" } } */
/* { dg-final { scan-tree-dump-times "__builtin_ctz " 1 "optimized" } } */
/* { dg-final { scan-tree-dump-times "__builtin_clz " 1 "optimized" } } */
/* { dg-final { scan-tree-dump-times "__builtin_ctzll " 1 "optimized" { target lp64 } } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment