Hello! Wide-int merge triggered following ICE:
In file included from ../../gcc-svn/trunk/gcc/wide-int.cc:37:0: ../../gcc-svn/trunk/gcc/wide-int.cc: In function ‘unsigned int wi::mul_internal(long int*, const long int*, unsigned int, const long int*, unsigned int, unsigned int, signop, bool*, bool)’: ../../gcc-svn/trunk/gcc/../include/longlong.h:145:10: sorry, unimplemented: unexpected AST of kind mult_highpart_expr (ph) = __builtin_alpha_umulh (__m0, __m1); \ ^ ../../gcc-svn/trunk/gcc/wide-int.cc:1269:4: note: in expansion of macro ‘umul_ppmm’ umul_ppmm (val[1], val[0], op1.ulow (), op2.ulow ()); ^ ../../gcc-svn/trunk/gcc/../include/longlong.h:145:10: internal compiler error: in potential_constant_expression_1, at cp/semantics.c:10575 (ph) = __builtin_alpha_umulh (__m0, __m1); \ ^ ../../gcc-svn/trunk/gcc/wide-int.cc:1269:4: note: in expansion of macro ‘umul_ppmm’ umul_ppmm (val[1], val[0], op1.ulow (), op2.ulow ()); ^ As instructed by Jakub, target builtins should be folded during gimplification. 2014-05-08 Uros Bizjak <ubiz...@gmail.com> PR target/61092 * config/alpha/alpha.c: Include gimple-iterator.h. (alpha_gimple_fold_builtin): New function. Move ALPHA_BUILTIN_UMULH folding from ... (alpha_fold_builtin): ... here. (TARGET_GIMPLE_FOLD_BUILTIN): New define. Patch was bootstrapped and regression tested on alphaev68-pc-linux-gnu. If there are no objections, I will commit the patch to mainline and 4.9. Uros.
Index: config/alpha/alpha.c =================================================================== --- config/alpha/alpha.c (revision 210120) +++ config/alpha/alpha.c (working copy) @@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-expr.h" #include "is-a.h" #include "gimple.h" +#include "gimple-iterator.h" #include "gimplify.h" #include "gimple-ssa.h" #include "stringpool.h" @@ -7042,9 +7043,6 @@ alpha_fold_builtin (tree fndecl, int n_args, tree case ALPHA_BUILTIN_MSKQH: return alpha_fold_builtin_mskxx (op, opint, op_const, 0xff, true); - case ALPHA_BUILTIN_UMULH: - return fold_build2 (MULT_HIGHPART_EXPR, alpha_dimode_u, op[0], op[1]); - case ALPHA_BUILTIN_ZAP: opint[1] ^= 0xff; /* FALLTHRU */ @@ -7094,6 +7092,49 @@ alpha_fold_builtin (tree fndecl, int n_args, tree return NULL; } } + +bool +alpha_gimple_fold_builtin (gimple_stmt_iterator *gsi) +{ + bool changed = false; + gimple stmt = gsi_stmt (*gsi); + tree call = gimple_call_fn (stmt); + gimple new_stmt = NULL; + + if (call) + { + tree fndecl = gimple_call_fndecl (stmt); + + if (fndecl) + { + tree arg0, arg1; + + switch (DECL_FUNCTION_CODE (fndecl)) + { + case ALPHA_BUILTIN_UMULH: + arg0 = gimple_call_arg (stmt, 0); + arg1 = gimple_call_arg (stmt, 1); + + new_stmt + = gimple_build_assign_with_ops (MULT_HIGHPART_EXPR, + gimple_call_lhs (stmt), + arg0, + arg1); + break; + default: + break; + } + } + } + + if (new_stmt) + { + gsi_replace (gsi, new_stmt, true); + changed = true; + } + + return changed; +} /* This page contains routines that are used to determine what the function prologue and epilogue code will do and write them out. */ @@ -9790,6 +9831,8 @@ alpha_canonicalize_comparison (int *code, rtx *op0 #define TARGET_EXPAND_BUILTIN alpha_expand_builtin #undef TARGET_FOLD_BUILTIN #define TARGET_FOLD_BUILTIN alpha_fold_builtin +#undef TARGET_GIMPLE_FOLD_BUILTIN +#define TARGET_GIMPLE_FOLD_BUILTIN alpha_gimple_fold_builtin #undef TARGET_FUNCTION_OK_FOR_SIBCALL #define TARGET_FUNCTION_OK_FOR_SIBCALL alpha_function_ok_for_sibcall