This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Bad choices by expand_mult_highpart


Richard Sandiford <rsandifo@redhat.com> writes:
> Richard Sandiford <rsandifo@redhat.com> writes:
>> I'm assuming that CNST1, as passed to expand_mult_highpart, is required
>> to be a legitimate INTVAL for mode MODE.  That means it'll be legitimate
>> for WIDER_MODE as well.
>
> Duh.  Sorry, I was forgetting that INTVAL is always sign-extended.

So how does this look?  It zero extends cnst1 to wider_mode if unsignedp,
otherwise it sign extends.

Bootstrapped & regression tested on alpha-linux-gnu.  Bootstrap on
sparc-linux-gnu in progress, but it's got well into building libjava,
which was later than the original SPARC failure.  Bootstrap on
i686-pc-linux-gnu and mips-linux-gnu in progress too.

OK if the tests pass?

Richard


	* expmed.c (expand_mult_highpart): Extend cnst1 to wider_mode before
	using choose_mult_variant and expand_mult_const.

Index: expmed.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expmed.c,v
retrieving revision 1.154
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.154 expmed.c
*** expmed.c	21 Mar 2004 19:31:29 -0000	1.154
--- expmed.c	22 Mar 2004 20:30:18 -0000
*************** expand_mult_highpart (enum machine_mode 
*** 2978,2984 ****
  {
    enum machine_mode wider_mode = GET_MODE_WIDER_MODE (mode);
    int extra_cost;
-   bool sign_adjust = false;
    enum mult_variant variant;
    struct algorithm alg;
    rtx op1, tem;
--- 2978,2983 ----
*************** expand_mult_highpart (enum machine_mode 
*** 2987,3015 ****
    if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
      abort ();
  
    op1 = gen_int_mode (cnst1, mode);
-   cnst1 &= GET_MODE_MASK (mode);
  
!   /* We can't optimize modes wider than BITS_PER_WORD. 
!      ??? We might be able to perform double-word arithmetic if 
!      mode == word_mode, however all the cost calculations in
!      synth_mult etc. assume single-word operations.  */
!   if (GET_MODE_BITSIZE (wider_mode) > BITS_PER_WORD)
!     return expand_mult_highpart_optab (mode, op0, op1, target,
! 				       unsignedp, max_cost);
  
    extra_cost = shift_cost[GET_MODE_BITSIZE (mode) - 1];
  
-   /* Check whether we try to multiply by a negative constant.  */
-   if (!unsignedp && ((cnst1 >> (GET_MODE_BITSIZE (mode) - 1)) & 1))
-     {
-       sign_adjust = true;
-       extra_cost += add_cost;
-     }
- 
    /* See whether shift/add multiplication is cheap enough.  */
!   if (choose_mult_variant (wider_mode, cnst1, &alg, &variant,
! 			   max_cost - extra_cost))
      {
        /* See whether the specialized multiplication optabs are
  	 cheaper than the shift/add version.  */
--- 2986,3005 ----
    if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
      abort ();
  
+   /* Create an rtx suitable for multiplication in mode MODE.  */
    op1 = gen_int_mode (cnst1, mode);
  
!   /* Get the equivalent constant for WIDER_MODE.  */
!   cnst1 = INTVAL (op1);
!   if (unsignedp)
!     cnst1 &= GET_MODE_MASK (mode);
  
    extra_cost = shift_cost[GET_MODE_BITSIZE (mode) - 1];
  
    /* See whether shift/add multiplication is cheap enough.  */
!   if (GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD
!       && choose_mult_variant (wider_mode, cnst1, &alg, &variant,
! 			      max_cost - extra_cost))
      {
        /* See whether the specialized multiplication optabs are
  	 cheaper than the shift/add version.  */
*************** expand_mult_highpart (enum machine_mode 
*** 3020,3032 ****
  
        tem = convert_to_mode (wider_mode, op0, unsignedp);
        tem = expand_mult_const (wider_mode, tem, cnst1, 0, &alg, variant);
!       tem = extract_high_half (mode, tem);
! 
!       /* Adjust result for signedness. */
!       if (sign_adjust)
! 	tem = force_operand (gen_rtx_MINUS (mode, tem, op0), tem);
! 
!       return tem;
      }
    return expand_mult_highpart_optab (mode, op0, op1, target,
  				     unsignedp, max_cost);
--- 3010,3016 ----
  
        tem = convert_to_mode (wider_mode, op0, unsignedp);
        tem = expand_mult_const (wider_mode, tem, cnst1, 0, &alg, variant);
!       return extract_high_half (mode, tem);
      }
    return expand_mult_highpart_optab (mode, op0, op1, target,
  				     unsignedp, max_cost);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]