From 0b99f25372431148e637b98f02e7cbe03feef7f9 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 15 Nov 2017 10:01:42 +0100 Subject: re PR target/82981 (unnecessary __multi3 call for mips64r6 linux kernel) PR target/82981 * internal-fn.c: Include gimple-ssa.h, tree-phinodes.h and ssa-iterators.h. (can_widen_mult_without_libcall): New function. (expand_mul_overflow): If only checking unsigned mul overflow, not result, and can do efficiently MULT_HIGHPART_EXPR, emit that. Don't use WIDEN_MULT_EXPR if it would involve a libcall, unless no other way works. Add MULT_HIGHPART_EXPR + MULT_EXPR support. (expand_DIVMOD): Formatting fix. * expmed.h (expand_mult): Add NO_LIBCALL argument. * expmed.c (expand_mult): Likewise. Use OPTAB_WIDEN rather than OPTAB_LIB_WIDEN if NO_LIBCALL is true, and allow it to fail. * gcc.target/mips/pr82981.c: New test. From-SVN: r254758 --- gcc/expmed.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'gcc/expmed.c') diff --git a/gcc/expmed.c b/gcc/expmed.c index 8e9f15d..dacb2b9 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -3284,7 +3284,7 @@ expand_mult_const (machine_mode mode, rtx op0, HOST_WIDE_INT val, rtx expand_mult (machine_mode mode, rtx op0, rtx op1, rtx target, - int unsignedp) + int unsignedp, bool no_libcall) { enum mult_variant variant; struct algorithm algorithm; @@ -3420,14 +3420,16 @@ expand_mult (machine_mode mode, rtx op0, rtx op1, rtx target, { op0 = force_reg (GET_MODE (op0), op0); return expand_binop (mode, add_optab, op0, op0, - target, unsignedp, OPTAB_LIB_WIDEN); + target, unsignedp, + no_libcall ? OPTAB_WIDEN : OPTAB_LIB_WIDEN); } /* This used to use umul_optab if unsigned, but for non-widening multiply there is no difference between signed and unsigned. */ op0 = expand_binop (mode, do_trapv ? smulv_optab : smul_optab, - op0, op1, target, unsignedp, OPTAB_LIB_WIDEN); - gcc_assert (op0); + op0, op1, target, unsignedp, + no_libcall ? OPTAB_WIDEN : OPTAB_LIB_WIDEN); + gcc_assert (op0 || no_libcall); return op0; } -- cgit v1.1