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][RFC] Introduce BIT_FIELD_INSERT


Sorry, that was the wrong vector-6.c â should have realized.  In any case, for each of the vector tests, we get appropriate use of element-wise loads, and no load-hit-store bitfield assignments, so the code generation is what we want to see.  Sorry for the misleading information.

Bill

> On May 15, 2016, at 7:55 PM, Bill Schmidt <wschmidt@linux.vnet.ibm.com> wrote:
> 
> Hi Richard,
> 
> (Sorry for duplication to your personal email, I had new-mailer issues.)
> 
> The new vector-6 test produces very good code for powerpc64le with this patch:
> 
>        addis 9,2,.LC0@toc@ha
>        sldi 3,3,32
>        addi 9,9,.LC0@toc@l
>        rldicl 9,9,0,32
>        or 3,9,3
>        blr
> 
> I did run into some ICEs with bootstrap/regtest, though:
> 
> 26c26
> < /home/wschmidt/gcc/build/gcc-mainline-base/gcc/testsuite/g++/../../xg++  version 7.0.0 20160515 (experimental) [trunk revision 236259] (GCC) 
> ---
>> /home/wschmidt/gcc/build/gcc-mainline-test/gcc/testsuite/g++/../../xg++  version 7.0.0 20160515 (experimental) [trunk revision 236259] (GCC) 
> 31a32,39
>> FAIL: gcc.c-torture/compile/pr70240.c   -O1  (internal compiler error)
>> FAIL: gcc.c-torture/compile/pr70240.c   -O1  (test for excess errors)
>> FAIL: gcc.c-torture/compile/pr70240.c   -O2  (internal compiler error)
>> FAIL: gcc.c-torture/compile/pr70240.c   -O2  (test for excess errors)
>> FAIL: gcc.c-torture/compile/pr70240.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (internal compiler error)
>> FAIL: gcc.c-torture/compile/pr70240.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (test for excess errors)
>> FAIL: gcc.c-torture/compile/pr70240.c   -Os  (internal compiler error)
>> FAIL: gcc.c-torture/compile/pr70240.c   -Os  (test for excess errors)
> 53a62,66
>> FAIL: gcc.dg/pr69896.c (internal compiler error)
>> FAIL: gcc.dg/pr69896.c (test for excess errors)
>> UNRESOLVED: gcc.dg/pr69896.c compilation failed to produce executable
>> FAIL: gcc.dg/pr70326.c (internal compiler error)
>> FAIL: gcc.dg/pr70326.c (test for excess errors)
> 281a295,353
>> FAIL: gcc.dg/torture/pr69613.c   -O1  (internal compiler error)
>> FAIL: gcc.dg/torture/pr69613.c   -O1  (test for excess errors)
>> UNRESOLVED: gcc.dg/torture/pr69613.c   -O1  compilation failed to produce executable
>> FAIL: gcc.dg/torture/pr69613.c   -O2  (internal compiler error)
>> FAIL: gcc.dg/torture/pr69613.c   -O2  (test for excess errors)
>> UNRESOLVED: gcc.dg/torture/pr69613.c   -O2  compilation failed to produce executable
>> FAIL: gcc.dg/torture/pr69613.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (internal compiler error)
>> FAIL: gcc.dg/torture/pr69613.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (test for excess errors)
>> UNRESOLVED: gcc.dg/torture/pr69613.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  compilation failed to produce executable
>> FAIL: gcc.dg/torture/pr69613.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (internal compiler error)
>> FAIL: gcc.dg/torture/pr69613.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (test for excess errors)
>> UNRESOLVED: gcc.dg/torture/pr69613.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  compilation failed to produce executable
>> FAIL: gcc.dg/torture/pr69613.c   -O3 -g  (internal compiler error)
>> FAIL: gcc.dg/torture/pr69613.c   -O3 -g  (test for excess errors)
>> UNRESOLVED: gcc.dg/torture/pr69613.c   -O3 -g  compilation failed to produce executable
>> FAIL: gcc.dg/torture/pr69613.c   -Os  (internal compiler error)
>> FAIL: gcc.dg/torture/pr69613.c   -Os  (test for excess errors)
>> UNRESOLVED: gcc.dg/torture/pr69613.c   -Os  compilation failed to produce executable
>> FAIL: gcc.dg/torture/pr69909.c   -O1  (internal compiler error)
>> FAIL: gcc.dg/torture/pr69909.c   -O1  (test for excess errors)
>> UNRESOLVED: gcc.dg/torture/pr69909.c   -O1  compilation failed to produce executable
>> FAIL: gcc.dg/torture/pr69909.c   -O2  (internal compiler error)
>> FAIL: gcc.dg/torture/pr69909.c   -O2  (test for excess errors)
>> UNRESOLVED: gcc.dg/torture/pr69909.c   -O2  compilation failed to produce executable
>> FAIL: gcc.dg/torture/pr69909.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (internal compiler error)
>> FAIL: gcc.dg/torture/pr69909.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (test for excess errors)
>> UNRESOLVED: gcc.dg/torture/pr69909.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  compilation failed to produce executable
>> FAIL: gcc.dg/torture/pr69909.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (internal compiler error)
>> FAIL: gcc.dg/torture/pr69909.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (test for excess errors)
>> UNRESOLVED: gcc.dg/torture/pr69909.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  compilation failed to produce executable
>> FAIL: gcc.dg/torture/pr69909.c   -O3 -g  (internal compiler error)
>> FAIL: gcc.dg/torture/pr69909.c   -O3 -g  (test for excess errors)
>> UNRESOLVED: gcc.dg/torture/pr69909.c   -O3 -g  compilation failed to produce executable
>> FAIL: gcc.dg/torture/pr69909.c   -Os  (internal compiler error)
>> FAIL: gcc.dg/torture/pr69909.c   -Os  (test for excess errors)
>> UNRESOLVED: gcc.dg/torture/pr69909.c   -Os  compilation failed to produce executable
>> FAIL: gcc.dg/torture/pr70083.c   -O1  (internal compiler error)
>> FAIL: gcc.dg/torture/pr70083.c   -O2  (internal compiler error)
>> FAIL: gcc.dg/torture/pr70083.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (internal compiler error)
>> FAIL: gcc.dg/torture/pr70083.c   -O3 -g  (internal compiler error)
>> FAIL: gcc.dg/torture/pr70083.c   -Os  (internal compiler error)
>> FAIL: gcc.dg/torture/pr70421.c   -O1  (internal compiler error)
>> FAIL: gcc.dg/torture/pr70421.c   -O1  (test for excess errors)
>> UNRESOLVED: gcc.dg/torture/pr70421.c   -O1  compilation failed to produce executable
>> FAIL: gcc.dg/torture/pr70421.c   -O2  (internal compiler error)
>> FAIL: gcc.dg/torture/pr70421.c   -O2  (test for excess errors)
>> UNRESOLVED: gcc.dg/torture/pr70421.c   -O2  compilation failed to produce executable
>> FAIL: gcc.dg/torture/pr70421.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (internal compiler error)
>> FAIL: gcc.dg/torture/pr70421.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (test for excess errors)
>> UNRESOLVED: gcc.dg/torture/pr70421.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  compilation failed to produce executable
>> FAIL: gcc.dg/torture/pr70421.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (internal compiler error)
>> FAIL: gcc.dg/torture/pr70421.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (test for excess errors)
>> UNRESOLVED: gcc.dg/torture/pr70421.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  compilation failed to produce executable
>> FAIL: gcc.dg/torture/pr70421.c   -O3 -g  (internal compiler error)
>> FAIL: gcc.dg/torture/pr70421.c   -O3 -g  (test for excess errors)
>> UNRESOLVED: gcc.dg/torture/pr70421.c   -O3 -g  compilation failed to produce executable
>> FAIL: gcc.dg/torture/pr70421.c   -Os  (internal compiler error)
>> FAIL: gcc.dg/torture/pr70421.c   -Os  (test for excess errors)
>> UNRESOLVED: gcc.dg/torture/pr70421.c   -Os  compilation failed to produce executable
> 295,296c367,368
> 
> Thanks for adding BIT_FIELD_INSERT, I think this will help us in several places.
> 
> Bill 
> 
>> On May 13, 2016, at 5:51 AM, Richard Biener <rguenther@suse.de> wrote:
>> 
>> 
>> The following patch adds BIT_FIELD_INSERT, an operation to
>> facilitate doing bitfield inserts on registers (as opposed
>> to currently where we'd have a BIT_FIELD_REF store).
>> 
>> Originally this was developed as part of bitfield lowering
>> where bitfield stores were lowered into read-modify-write
>> cycles and the modify part, instead of doing shifting and masking,
>> be kept in a more high-level form to ease combining them.
>> 
>> A second use case (the above is still valid) is vector element
>> inserts which we currently can only do via memory or
>> by extracting all components and re-building the vector using
>> a CONSTRUCTOR.  For this second use case I added code
>> re-writing the BIT_FIELD_REF stores the C family FEs produce
>> into BIT_FIELD_INSERT when update-address-taken can otherwise
>> re-write a decl into SSA form (the testcase shows we miss
>> a similar opportunity with the MEM_REF form of a vector insert,
>> I plan to fix that for the final submission).
>> 
>> One speciality of BIT_FIELD_INSERT as opposed to BIT_FIELD_REF
>> is that the size of the insertion is given implicitely via the
>> type size/precision of the value to insert.  That avoids
>> introducing ways to have quaternary ops in folding and GIMPLE stmts.
>> 
>> Bootstrapped and tested on x86_64-unknown-linux-gnu.
>> 
>> Richard.
>> 
>> 2011-06-16  Richard Guenther  <rguenther@suse.de>
>> 
>> 	PR tree-optimization/29756
>> 	* tree.def (BIT_FIELD_INSERT): New tcc_expression tree code.
>> 	* expr.c (expand_expr_real_2): Handle BIT_FIELD_INSERT.
>> 	* fold-const.c (operand_equal_p): Likewise.
>> 	(fold_ternary_loc): Add constant folding of BIT_FIELD_INSERT.
>> 	* gimplify.c (gimplify_expr): Handle BIT_FIELD_INSERT.
>> 	* tree-inline.c (estimate_operator_cost): Likewise.
>> 	* tree-pretty-print.c (dump_generic_node): Likewise.
>> 	* tree-ssa-operands.c (get_expr_operands): Likewise.
>> 	* cfgexpand.c (expand_debug_expr): Likewise.
>> 	* gimple-pretty-print.c (dump_ternary_rhs): Likewise.
>> 	* gimple.c (get_gimple_rhs_num_ops): Handle BIT_FIELD_INSERT.
>> 	* tree-cfg.c (verify_gimple_assign_ternary): Verify BIT_FIELD_INSERT.
>> 
>> 	* tree-ssa.c (non_rewritable_lvalue_p): We can rewrite
>> 	vector inserts using BIT_FIELD_REF on the lhs.
>> 	(execute_update_addresses_taken): Do it.
>> 
>> 	* gcc.dg/tree-ssa/vector-6.c: New testcase.
>> 
>> Index: trunk/gcc/expr.c
>> ===================================================================
>> *** trunk.orig/gcc/expr.c	2016-05-12 13:40:30.704262951 +0200
>> --- trunk/gcc/expr.c	2016-05-12 15:40:32.481225744 +0200
>> *************** expand_expr_real_2 (sepops ops, rtx targ
>> *** 9358,9363 ****
>> --- 9358,9380 ----
>>       target = expand_vec_cond_expr (type, treeop0, treeop1, treeop2, target);
>>       return target;
>> 
>> +     case BIT_FIELD_INSERT:
>> +       {
>> + 	unsigned bitpos = tree_to_uhwi (treeop2);
>> + 	unsigned bitsize;
>> + 	if (INTEGRAL_TYPE_P (TREE_TYPE (treeop1)))
>> + 	  bitsize = TYPE_PRECISION (TREE_TYPE (treeop1));
>> + 	else
>> + 	  bitsize = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (treeop1)));
>> + 	rtx op0 = expand_normal (treeop0);
>> + 	rtx op1 = expand_normal (treeop1);
>> + 	rtx dst = gen_reg_rtx (mode);
>> + 	emit_move_insn (dst, op0);
>> + 	store_bit_field (dst, bitsize, bitpos, 0, 0,
>> + 			 TYPE_MODE (TREE_TYPE (treeop1)), op1, false);
>> + 	return dst;
>> +       }
>> + 
>>     default:
>>       gcc_unreachable ();
>>     }
>> Index: trunk/gcc/fold-const.c
>> ===================================================================
>> *** trunk.orig/gcc/fold-const.c	2016-05-12 13:40:30.704262951 +0200
>> --- trunk/gcc/fold-const.c	2016-05-13 09:41:13.509812127 +0200
>> *************** operand_equal_p (const_tree arg0, const_
>> *** 3163,3168 ****
>> --- 3163,3169 ----
>> 
>> 	case VEC_COND_EXPR:
>> 	case DOT_PROD_EXPR:
>> + 	case BIT_FIELD_INSERT:
>> 	  return OP_SAME (0) && OP_SAME (1) && OP_SAME (2);
>> 
>> 	default:
>> *************** fold_ternary_loc (location_t loc, enum t
>> *** 11870,11875 ****
>> --- 11871,11916 ----
>> 	}
>>       return NULL_TREE;
>> 
>> +     case BIT_FIELD_INSERT:
>> +       /* Perform (partial) constant folding of BIT_FIELD_INSERT.  */
>> +       if (TREE_CODE (arg0) == INTEGER_CST
>> + 	  && TREE_CODE (arg1) == INTEGER_CST)
>> + 	{
>> + 	  unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (op2);
>> + 	  unsigned bitsize = TYPE_PRECISION (TREE_TYPE (arg1));
>> + 	  wide_int tem = wi::bit_and (arg0,
>> + 				      wi::shifted_mask (bitpos, bitsize, true,
>> + 							TYPE_PRECISION (type)));
>> + 	  wide_int tem2
>> + 	    = wi::lshift (wi::zext (wi::to_wide (arg1, TYPE_PRECISION (type)),
>> + 				    bitsize), bitpos);
>> + 	  return wide_int_to_tree (type, wi::bit_or (tem, tem2));
>> + 	}
>> +       else if (TREE_CODE (arg0) == VECTOR_CST
>> + 	       && CONSTANT_CLASS_P (arg1)
>> + 	       && types_compatible_p (TREE_TYPE (TREE_TYPE (arg0)),
>> + 				      TREE_TYPE (arg1)))
>> + 	{
>> + 	  unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (op2);
>> + 	  unsigned HOST_WIDE_INT elsize
>> + 	    = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (arg1)));
>> + 	  if (bitpos % elsize == 0)
>> + 	    {
>> + 	      unsigned k = bitpos / elsize;
>> + 	      if (operand_equal_p (VECTOR_CST_ELT (arg0, k), arg1, 0))
>> + 		return arg0;
>> + 	      else
>> + 		{
>> + 		  tree *elts = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (type));
>> + 		  memcpy (elts, VECTOR_CST_ELTS (arg0),
>> + 			  sizeof (tree) * TYPE_VECTOR_SUBPARTS (type));
>> + 		  elts[k] = arg1;
>> + 		  return build_vector (type, elts);
>> + 		}
>> + 	    }
>> + 	}
>> +       return NULL_TREE;
>> + 
>>     default:
>>       return NULL_TREE;
>>     } /* switch (code) */
>> Index: trunk/gcc/gimplify.c
>> ===================================================================
>> *** trunk.orig/gcc/gimplify.c	2016-05-12 13:40:30.704262951 +0200
>> --- trunk/gcc/gimplify.c	2016-05-12 13:56:18.679120641 +0200
>> *************** gimplify_expr (tree *expr_p, gimple_seq
>> *** 10936,10941 ****
>> --- 10936,10945 ----
>> 	  /* Classified as tcc_expression.  */
>> 	  goto expr_3;
>> 
>> + 	case BIT_FIELD_INSERT:
>> + 	  /* Argument 3 is a constant.  */
>> + 	  goto expr_2;
>> + 
>> 	case POINTER_PLUS_EXPR:
>> 	  {
>> 	    enum gimplify_status r0, r1;
>> Index: trunk/gcc/tree-inline.c
>> ===================================================================
>> *** trunk.orig/gcc/tree-inline.c	2016-05-12 13:40:30.704262951 +0200
>> --- trunk/gcc/tree-inline.c	2016-05-12 13:42:45.465811959 +0200
>> *************** estimate_operator_cost (enum tree_code c
>> *** 3941,3946 ****
>> --- 3941,3950 ----
>>         return weights->div_mod_cost;
>>       return 1;
>> 
>> +     /* Bit-field insertion needs several shift and mask operations.  */
>> +     case BIT_FIELD_INSERT:
>> +       return 3;
>> + 
>>     default:
>>       /* We expect a copy assignment with no operator.  */
>>       gcc_assert (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS);
>> Index: trunk/gcc/tree-pretty-print.c
>> ===================================================================
>> *** trunk.orig/gcc/tree-pretty-print.c	2016-05-12 13:40:30.704262951 +0200
>> --- trunk/gcc/tree-pretty-print.c	2016-05-12 14:30:05.781944740 +0200
>> *************** dump_generic_node (pretty_printer *pp, t
>> *** 1876,1881 ****
>> --- 1876,1898 ----
>>       pp_greater (pp);
>>       break;
>> 
>> +     case BIT_FIELD_INSERT:
>> +       pp_string (pp, "BIT_FIELD_INSERT <");
>> +       dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
>> +       pp_string (pp, ", ");
>> +       dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
>> +       pp_string (pp, ", ");
>> +       dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
>> +       pp_string (pp, " (");
>> +       if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (node, 1))))
>> + 	pp_decimal_int (pp,
>> + 			TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (node, 1))));
>> +       else
>> + 	dump_generic_node (pp, TYPE_SIZE (TREE_TYPE (TREE_OPERAND (node, 1))),
>> + 			   spc, flags, false);
>> +       pp_string (pp, " bits)>");
>> +       break;
>> + 
>>     case ARRAY_REF:
>>     case ARRAY_RANGE_REF:
>>       op0 = TREE_OPERAND (node, 0);
>> Index: trunk/gcc/tree-ssa-operands.c
>> ===================================================================
>> *** trunk.orig/gcc/tree-ssa-operands.c	2016-05-12 13:42:45.465811959 +0200
>> --- trunk/gcc/tree-ssa-operands.c	2016-05-12 13:48:26.881736503 +0200
>> *************** get_expr_operands (struct function *fn,
>> *** 833,838 ****
>> --- 833,839 ----
>>       get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 0), flags);
>>       return;
>> 
>> +     case BIT_FIELD_INSERT:
>>     case COMPOUND_EXPR:
>>     case OBJ_TYPE_REF:
>>     case ASSERT_EXPR:
>> Index: trunk/gcc/tree.def
>> ===================================================================
>> *** trunk.orig/gcc/tree.def	2016-05-12 13:40:30.704262951 +0200
>> --- trunk/gcc/tree.def	2016-05-12 13:47:09.972852423 +0200
>> *************** DEFTREECODE (ADDR_EXPR, "addr_expr", tcc
>> *** 852,857 ****
>> --- 852,868 ----
>>    descriptor of type ptr_mode.  */
>> DEFTREECODE (FDESC_EXPR, "fdesc_expr", tcc_expression, 2)
>> 
>> + /* Given a word, a value and a bitfield position within the word,
>> +    produce the value that results if replacing the
>> +    described parts of word with value.
>> +    Operand 0 is a tree for the word of integral type;
>> +    Operand 1 is a tree for the value of integral type;
>> +    Operand 2 is a tree giving the constant position of the first referenced bit;
>> +    The number of bits replaced is given by the precision of the value
>> +    type if that is integral or by its size if it is non-integral.
>> +    The replaced bits shall be fully inside the word.  */
>> + DEFTREECODE (BIT_FIELD_INSERT, "bit_field_insert", tcc_expression, 3)
>> + 
>> /* Given two real or integer operands of the same type,
>>    returns a complex value of the corresponding complex type.  */
>> DEFTREECODE (COMPLEX_EXPR, "complex_expr", tcc_binary, 2)
>> Index: trunk/gcc/cfgexpand.c
>> ===================================================================
>> *** trunk.orig/gcc/cfgexpand.c	2016-05-12 13:42:45.469812005 +0200
>> --- trunk/gcc/cfgexpand.c	2016-05-13 11:48:04.513407495 +0200
>> *************** expand_debug_expr (tree exp)
>> *** 5025,5030 ****
>> --- 5025,5031 ----
>>     case FIXED_CONVERT_EXPR:
>>     case OBJ_TYPE_REF:
>>     case WITH_SIZE_EXPR:
>> +     case BIT_FIELD_INSERT:
>>       return NULL;
>> 
>>     case DOT_PROD_EXPR:
>> Index: trunk/gcc/gimple-pretty-print.c
>> ===================================================================
>> *** trunk.orig/gcc/gimple-pretty-print.c	2016-05-12 11:23:09.261375157 +0200
>> --- trunk/gcc/gimple-pretty-print.c	2016-05-12 14:57:22.096175579 +0200
>> *************** dump_ternary_rhs (pretty_printer *buffer
>> *** 479,484 ****
>> --- 479,502 ----
>>       pp_greater (buffer);
>>       break;
>> 
>> +     case BIT_FIELD_INSERT:
>> +       pp_string (buffer, "BIT_FIELD_INSERT <");
>> +       dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
>> +       pp_string (buffer, ", ");
>> +       dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
>> +       pp_string (buffer, ", ");
>> +       dump_generic_node (buffer, gimple_assign_rhs3 (gs), spc, flags, false);
>> +       pp_string (buffer, " (");
>> +       if (INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs2 (gs))))
>> + 	pp_decimal_int (buffer,
>> + 			TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs2 (gs))));
>> +       else
>> + 	dump_generic_node (buffer,
>> + 			   TYPE_SIZE (TREE_TYPE (gimple_assign_rhs2 (gs))),
>> + 			   spc, flags, false);
>> +       pp_string (buffer, " bits)>");
>> +       break;
>> + 
>>     default:
>>       gcc_unreachable ();
>>     }
>> Index: trunk/gcc/gimple.c
>> ===================================================================
>> *** trunk.orig/gcc/gimple.c	2016-05-12 13:40:30.704262951 +0200
>> --- trunk/gcc/gimple.c	2016-05-12 14:49:37.066994969 +0200
>> *************** get_gimple_rhs_num_ops (enum tree_code c
>> *** 2044,2049 ****
>> --- 2044,2050 ----
>>       || (SYM) == REALIGN_LOAD_EXPR					    \
>>       || (SYM) == VEC_COND_EXPR						    \
>>       || (SYM) == VEC_PERM_EXPR                                             \
>> +       || (SYM) == BIT_FIELD_INSERT					    \
>>       || (SYM) == FMA_EXPR) ? GIMPLE_TERNARY_RHS			    \
>>    : ((SYM) == CONSTRUCTOR						    \
>>       || (SYM) == OBJ_TYPE_REF						    \
>> Index: trunk/gcc/tree-cfg.c
>> ===================================================================
>> *** trunk.orig/gcc/tree-cfg.c	2016-05-06 14:38:33.959495081 +0200
>> --- trunk/gcc/tree-cfg.c	2016-05-13 09:25:01.670630730 +0200
>> *************** verify_gimple_assign_ternary (gassign *s
>> *** 4155,4160 ****
>> --- 4155,4207 ----
>> 
>>       return false;
>> 
>> +     case BIT_FIELD_INSERT:
>> +       if (! useless_type_conversion_p (lhs_type, rhs1_type))
>> + 	{
>> + 	  error ("type mismatch in BIT_FIELD_INSERT");
>> + 	  debug_generic_expr (lhs_type);
>> + 	  debug_generic_expr (rhs1_type);
>> + 	  return true;
>> + 	}
>> +       if (! ((INTEGRAL_TYPE_P (rhs1_type)
>> + 	      && INTEGRAL_TYPE_P (rhs2_type))
>> + 	     || (VECTOR_TYPE_P (rhs1_type)
>> + 		 && types_compatible_p (TREE_TYPE (rhs1_type), rhs2_type))))
>> + 	{
>> + 	  error ("not allowed type combination in BIT_FIELD_INSERT");
>> + 	  debug_generic_expr (rhs1_type);
>> + 	  debug_generic_expr (rhs2_type);
>> + 	  return true;
>> + 	}
>> +       if (! tree_fits_uhwi_p (rhs3)
>> + 	  || ! tree_fits_uhwi_p (TYPE_SIZE (rhs2_type)))
>> + 	{
>> + 	  error ("invalid position or size in BIT_FIELD_INSERT");
>> + 	  return true;
>> + 	}
>> +       if (INTEGRAL_TYPE_P (rhs1_type))
>> + 	{
>> + 	  unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (rhs3);
>> + 	  if (bitpos >= TYPE_PRECISION (rhs1_type)
>> + 	      || (bitpos + TYPE_PRECISION (rhs2_type)
>> + 		  > TYPE_PRECISION (rhs1_type)))
>> + 	    {
>> + 	      error ("insertion out of range in BIT_FIELD_INSERT");
>> + 	      return true;
>> + 	    }
>> + 	}
>> +       else if (VECTOR_TYPE_P (rhs1_type))
>> + 	{
>> + 	  unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (rhs3);
>> + 	  unsigned HOST_WIDE_INT bitsize = tree_to_uhwi (TYPE_SIZE (rhs2_type));
>> + 	  if (bitpos % bitsize != 0)
>> + 	    {
>> + 	      error ("vector insertion not at element boundary");
>> + 	      return true;
>> + 	    }
>> + 	}
>> +       return false;
>> + 
>>     case DOT_PROD_EXPR:
>>     case REALIGN_LOAD_EXPR:
>>       /* FIXME.  */
>> Index: trunk/gcc/tree-ssa.c
>> ===================================================================
>> *** trunk.orig/gcc/tree-ssa.c	2016-05-13 09:38:02.263611726 +0200
>> --- trunk/gcc/tree-ssa.c	2016-05-13 09:50:31.020226585 +0200
>> *************** non_rewritable_lvalue_p (tree lhs)
>> *** 1318,1323 ****
>> --- 1318,1335 ----
>> 	return false;
>>     }
>> 
>> +   /* A vector-insert using a BIT_FIELD_REF is rewritable using
>> +      BIT_FIELD_INSERT.  */
>> +   if (TREE_CODE (lhs) == BIT_FIELD_REF
>> +       && DECL_P (TREE_OPERAND (lhs, 0))
>> +       && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs, 0)))
>> +       /* && bitsize % element-size == 0 */
>> +       && types_compatible_p (TREE_TYPE (lhs),
>> + 			     TREE_TYPE (TREE_TYPE (TREE_OPERAND (lhs, 0))))
>> +       && (tree_to_uhwi (TREE_OPERAND (lhs, 2))
>> + 	  % tree_to_uhwi (TYPE_SIZE (TREE_TYPE (lhs)))) == 0)
>> +     return false;
>> + 
>>   return true;
>> }
>> 
>> *************** execute_update_addresses_taken (void)
>> *** 1536,1541 ****
>> --- 1548,1576 ----
>> 		    stmt = gsi_stmt (gsi);
>> 		    unlink_stmt_vdef (stmt);
>> 		    update_stmt (stmt);
>> + 		    continue;
>> + 		  }
>> + 
>> + 		/* Rewrite a vector insert via a BIT_FIELD_REF on the LHS
>> + 		   into a BIT_FIELD_INSERT.  */
>> + 		if (TREE_CODE (lhs) == BIT_FIELD_REF
>> + 		    && DECL_P (TREE_OPERAND (lhs, 0))
>> + 		    && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs, 0)))
>> + 		    && types_compatible_p (TREE_TYPE (lhs),
>> + 					   TREE_TYPE (TREE_TYPE
>> + 						       (TREE_OPERAND (lhs, 0))))
>> + 		    && (tree_to_uhwi (TREE_OPERAND (lhs, 2))
>> + 			% tree_to_uhwi (TYPE_SIZE (TREE_TYPE (lhs))) == 0))
>> + 		  {
>> + 		    tree var = TREE_OPERAND (lhs, 0);
>> + 		    tree val = gimple_assign_rhs1 (stmt);
>> + 		    tree bitpos = TREE_OPERAND (lhs, 2);
>> + 		    gimple_assign_set_lhs (stmt, var);
>> + 		    gimple_assign_set_rhs_with_ops
>> + 		      (&gsi, BIT_FIELD_INSERT, var, val, bitpos);
>> + 		    stmt = gsi_stmt (gsi);
>> + 		    unlink_stmt_vdef (stmt);
>> + 		    update_stmt (stmt);
>> 		    continue;
>> 		  }
>> 
>> Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/vector-6.c
>> ===================================================================
>> *** /dev/null	1970-01-01 00:00:00.000000000 +0000
>> --- trunk/gcc/testsuite/gcc.dg/tree-ssa/vector-6.c	2016-05-13 09:54:16.026814995 +0200
>> ***************
>> *** 0 ****
>> --- 1,34 ----
>> + /* { dg-do compile } */
>> + /* { dg-options "-O -fdump-tree-ccp1" } */
>> + 
>> + typedef int v4si __attribute__((vector_size (4 * sizeof (int))));
>> + 
>> + v4si test1 (v4si v, int i)
>> + {
>> +   ((int *)&v)[0] = i;
>> +   return v;
>> + }
>> + 
>> + v4si test2 (v4si v, int i)
>> + {
>> +   int *p = (int *)&v;
>> +   *p = i;
>> +   return v;
>> + }
>> + 
>> + v4si test3 (v4si v, int i)
>> + {
>> +   ((int *)&v)[3] = i;
>> +   return v;
>> + }
>> + 
>> + v4si test4 (v4si v, int i)
>> + {
>> +   int *p = (int *)&v;
>> +   p += 3;
>> +   *p = i;
>> +   return v;
>> + }
>> + 
>> + /* { dg-final { scan-tree-dump-times "Now a gimple register: v" 2 "ccp1" } } */
>> + /* { dg-final { scan-tree-dump-times "Now a gimple register: v" 4 "ccp1" { xfail *-*-* } } } */
>> 
> 


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