mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
c05986b936
commit
9c4c8b7bbb
|
|
@ -1,5 +1,13 @@
|
||||||
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
|
||||||
#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,
|
||||||
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,
|
||||||
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)
|
||||||
#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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
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>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
/* 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 } } } */
|
||||||
Loading…
Reference in New Issue