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: [patch] PR 32283


Hi,

> > this transformation is different from the one needed (this piece of
> > code is turning ((x << 2) - 4) & ~3 to (x << 2) - 4).
> 
> Oops, yes, the transformation I had in mind is still done (by
> force_to_mode and simplify_and_const_int) in combine.c only.
> 
> > However,
> > implementing the required transformation using nonzero_bits would
> > indeed be a better idea,
> 
> Good, thanks.

here is the new version.  I kept the transformation (x-4) & 3 -> x & 3
(even though it is not necessary to achieve the optimization), as it
might be useful by itself.

Zdenek

Index: tree-ssa-loop-niter.c
===================================================================
*** tree-ssa-loop-niter.c	(revision 141981)
--- tree-ssa-loop-niter.c	(working copy)
*************** scev_probably_wraps_p (tree base, tree s
*** 3053,3059 ****
  
    /* If we can use the fact that signed and pointer arithmetics does not
       wrap, we are done.  */
!   if (use_overflow_semantics && nowrap_type_p (type))
      return false;
  
    /* To be able to use estimates on number of iterations of the loop,
--- 3053,3059 ----
  
    /* If we can use the fact that signed and pointer arithmetics does not
       wrap, we are done.  */
!   if (use_overflow_semantics && nowrap_type_p (TREE_TYPE (base)))
      return false;
  
    /* To be able to use estimates on number of iterations of the loop,
Index: tree-ssa-loop-ivopts.c
===================================================================
*** tree-ssa-loop-ivopts.c	(revision 141981)
--- tree-ssa-loop-ivopts.c	(working copy)
*************** rewrite_use_compare (struct ivopts_data 
*** 5323,5333 ****
      {
        tree var = var_at_stmt (data->current_loop, cand, use->stmt);
        tree var_type = TREE_TYPE (var);
  
        compare = iv_elimination_compare (data, use);
        bound = unshare_expr (fold_convert (var_type, bound));
!       op = force_gimple_operand_gsi (&bsi, bound, true, NULL_TREE,
! 				     true, GSI_SAME_STMT);
  
        gimple_cond_set_lhs (use->stmt, var);
        gimple_cond_set_code (use->stmt, compare);
--- 5323,5337 ----
      {
        tree var = var_at_stmt (data->current_loop, cand, use->stmt);
        tree var_type = TREE_TYPE (var);
+       gimple_seq stmts;
  
        compare = iv_elimination_compare (data, use);
        bound = unshare_expr (fold_convert (var_type, bound));
!       op = force_gimple_operand (bound, &stmts, true, NULL_TREE);
!       if (stmts)
! 	gsi_insert_seq_on_edge_immediate (
! 		loop_preheader_edge (data->current_loop),
! 		stmts);
  
        gimple_cond_set_lhs (use->stmt, var);
        gimple_cond_set_code (use->stmt, compare);
Index: simplify-rtx.c
===================================================================
*** simplify-rtx.c	(revision 141981)
--- simplify-rtx.c	(working copy)
*************** simplify_binary_operation_1 (enum rtx_co
*** 2304,2315 ****
      case AND:
        if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
  	return trueop1;
-       /* If we are turning off bits already known off in OP0, we need
- 	 not do an AND.  */
        if (GET_CODE (trueop1) == CONST_INT
! 	  && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
! 	  && (nonzero_bits (trueop0, mode) & ~INTVAL (trueop1)) == 0)
! 	return op0;
        if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
  	  && GET_MODE_CLASS (mode) != MODE_CC)
  	return op0;
--- 2304,2322 ----
      case AND:
        if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
  	return trueop1;
        if (GET_CODE (trueop1) == CONST_INT
! 	  && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
! 	{
! 	  HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, mode);
! 	  HOST_WIDE_INT val1 = INTVAL (trueop1);
! 	  /* If we are turning off bits already known off in OP0, we need
! 	     not do an AND.  */
! 	  if ((nzop0 & ~val1) == 0)
! 	    return op0;
! 	  /* If we are clearing all the nonzero bits, the result is zero.  */
! 	  if ((val1 & nzop0) == 0 && !side_effects_p (op0))
! 	    return CONST0_RTX (mode);
! 	}
        if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
  	  && GET_MODE_CLASS (mode) != MODE_CC)
  	return op0;
*************** simplify_binary_operation_1 (enum rtx_co
*** 2391,2397 ****
  	 ((A & N) + B) & M -> (A + B) & M
  	 Similarly if (N & M) == 0,
  	 ((A | N) + B) & M -> (A + B) & M
! 	 and for - instead of + and/or ^ instead of |.  */
        if (GET_CODE (trueop1) == CONST_INT
  	  && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
  	  && ~INTVAL (trueop1)
--- 2398,2406 ----
  	 ((A & N) + B) & M -> (A + B) & M
  	 Similarly if (N & M) == 0,
  	 ((A | N) + B) & M -> (A + B) & M
! 	 and for - instead of + and/or ^ instead of |.
!          Also, if (N & M) == 0, then
! 	 (A +- N) & M -> A & M.  */
        if (GET_CODE (trueop1) == CONST_INT
  	  && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
  	  && ~INTVAL (trueop1)
*************** simplify_binary_operation_1 (enum rtx_co
*** 2404,2409 ****
--- 2413,2422 ----
  	  pmop[0] = XEXP (op0, 0);
  	  pmop[1] = XEXP (op0, 1);
  
+ 	  if (GET_CODE (pmop[1]) == CONST_INT
+ 	      && (INTVAL (pmop[1]) & INTVAL (trueop1)) == 0)
+ 	    return simplify_gen_binary (AND, mode, pmop[0], op1);
+ 
  	  for (which = 0; which < 2; which++)
  	    {
  	      tem = pmop[which];
*************** simplify_plus_minus (enum rtx_code code,
*** 3591,3600 ****
            ops[j + 1] = save;
          }
  
-       /* This is only useful the first time through.  */
-       if (!canonicalized)
-         return NULL_RTX;
- 
        changed = 0;
        for (i = n_ops - 1; i > 0; i--)
  	for (j = i - 1; j >= 0; j--)
--- 3604,3609 ----
*************** simplify_plus_minus (enum rtx_code code,
*** 3650,3659 ****
--- 3659,3673 ----
  		    ops[i].neg = lneg;
  		    ops[j].op = NULL_RTX;
  		    changed = 1;
+ 		    canonicalized = 1;
  		  }
  	      }
  	  }
  
+       /* If nothing changed, fail.  */
+       if (!canonicalized)
+         return NULL_RTX;
+ 
        /* Pack all the operands to the lower-numbered entries.  */
        for (i = 0, j = 0; j < n_ops; j++)
          if (ops[j].op)
Index: loop-iv.c
===================================================================
*** loop-iv.c	(revision 141981)
--- loop-iv.c	(working copy)
*************** simple_rhs_p (rtx rhs)
*** 1337,1349 ****
      case MINUS:
        op0 = XEXP (rhs, 0);
        op1 = XEXP (rhs, 1);
!       /* Allow reg + const sets only.  */
!       if (REG_P (op0) && !HARD_REGISTER_P (op0) && CONSTANT_P (op1))
! 	return true;
!       if (REG_P (op1) && !HARD_REGISTER_P (op1) && CONSTANT_P (op0))
! 	return true;
  
!       return false;
  
      default:
        return false;
--- 1337,1362 ----
      case MINUS:
        op0 = XEXP (rhs, 0);
        op1 = XEXP (rhs, 1);
!       /* Allow reg + const and reg + reg.  */
!       if (!(REG_P (op0) && !HARD_REGISTER_P (op0))
! 	  && !CONSTANT_P (op0))
! 	return false;
!       if (!(REG_P (op1) && !HARD_REGISTER_P (op1))
! 	  && !CONSTANT_P (op1))
! 	return false;
  
!       return true;
! 
!     case ASHIFT:
!       op0 = XEXP (rhs, 0);
!       op1 = XEXP (rhs, 1);
!       /* Allow reg << const.  */
!       if (!(REG_P (op0) && !HARD_REGISTER_P (op0)))
! 	return false;
!       if (!CONSTANT_P (op1))
! 	return false;
! 
!       return true;
  
      default:
        return false;


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