View | Details | Return to bug 78007 | Differences between
and this patch

Collapse All | Expand All

(-)gcc/tree-vect-stmts.c (+112 lines)
Lines 2423-2428 vectorizable_mask_load_store (gimple *st Link Here
2423
  return true;
2423
  return true;
2424
}
2424
}
2425
2425
2426
static bool
2427
vectorizable_bswap (gimple *stmt, gimple_stmt_iterator *gsi,
2428
		    gimple **vec_stmt, slp_tree slp_node)
2429
{
2430
  tree op, vectype, vectype_in;
2431
  stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2432
  loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
2433
  enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
2434
  unsigned ncopies, nunits;
2435
  gimple *def_stmt;
2436
2437
  op = gimple_call_arg (stmt, 0);
2438
  vectype = STMT_VINFO_VECTYPE (stmt_info);
2439
  nunits = TYPE_VECTOR_SUBPARTS (vectype);
2440
2441
  /* Multiple types in SLP are handled by creating the appropriate number of
2442
     vectorized stmts for each SLP node.  Hence, NCOPIES is always 1 in
2443
     case of SLP.  */
2444
  if (slp_node)
2445
    ncopies = 1;
2446
  else
2447
    ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
2448
2449
  gcc_assert (ncopies >= 1);
2450
2451
  if (!vect_is_simple_use (op, loop_vinfo, &def_stmt, &dt[0], &vectype_in))
2452
    {
2453
      if (dump_enabled_p ())
2454
        dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2455
                         "use not simple.\n");
2456
      return false;
2457
    }
2458
2459
  tree char_vectype = get_same_sized_vectype (char_type_node, vectype_in);
2460
  if (! char_vectype)
2461
    return false;
2462
2463
  unsigned char *elts
2464
    = XALLOCAVEC (unsigned char, TYPE_VECTOR_SUBPARTS (char_vectype));
2465
  unsigned char *elt = elts;
2466
  unsigned word_bytes = TYPE_VECTOR_SUBPARTS (char_vectype) / nunits;
2467
  for (unsigned i = 0; i < nunits; ++i)
2468
    for (unsigned j = 0; j < word_bytes; ++j)
2469
      *elt++ = word_bytes - j - 1;
2470
2471
  if (! can_vec_perm_p (TYPE_MODE (char_vectype), false, elts))
2472
    return false;
2473
2474
  if (! vec_stmt)
2475
    {
2476
      STMT_VINFO_TYPE (stmt_info) = call_vec_info_type;
2477
      return true;
2478
    }
2479
2480
  tree *telts = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (char_vectype));
2481
  for (unsigned i = 0; i < TYPE_VECTOR_SUBPARTS (char_vectype); ++i)
2482
    telts[i] = build_int_cst (char_type_node, elts[i]);
2483
  tree bswap_vconst = build_vector (char_vectype, telts);
2484
2485
  /* Transform.  */
2486
  vec<tree> vec_oprnds = vNULL;
2487
  gimple *new_stmt;
2488
  stmt_vec_info prev_stmt_info = NULL;
2489
  for (unsigned j = 0; j < ncopies; j++)
2490
    {
2491
      /* Handle uses.  */
2492
      if (j == 0)
2493
        vect_get_vec_defs (op, NULL, stmt, &vec_oprnds, NULL, slp_node, -1);
2494
      else
2495
        vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds, NULL);
2496
2497
      /* Arguments are ready. create the new vector stmt.  */
2498
      unsigned i;
2499
      tree vop;
2500
      FOR_EACH_VEC_ELT (vec_oprnds, i, vop)
2501
       {
2502
	 tree tem = make_ssa_name (char_vectype);
2503
	 new_stmt = gimple_build_assign (tem, build1 (VIEW_CONVERT_EXPR,
2504
						      char_vectype, vop));
2505
	 vect_finish_stmt_generation (stmt, new_stmt, gsi);
2506
	 tree tem2 = make_ssa_name (char_vectype);
2507
	 new_stmt = gimple_build_assign (tem2, VEC_PERM_EXPR,
2508
					 tem, tem, bswap_vconst);
2509
	 vect_finish_stmt_generation (stmt, new_stmt, gsi);
2510
	 tem = make_ssa_name (vectype);
2511
	 new_stmt = gimple_build_assign (tem, build1 (VIEW_CONVERT_EXPR,
2512
						      vectype, tem2));
2513
	 vect_finish_stmt_generation (stmt, new_stmt, gsi);
2514
         if (slp_node)
2515
           SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
2516
       }
2517
2518
      if (slp_node)
2519
        continue;
2520
2521
      if (j == 0)
2522
        STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
2523
      else
2524
        STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
2525
2526
      prev_stmt_info = vinfo_for_stmt (new_stmt);
2527
    }
2528
2529
  vec_oprnds.release ();
2530
  return true;
2531
}
2532
2426
/* Return true if vector types VECTYPE_IN and VECTYPE_OUT have
2533
/* Return true if vector types VECTYPE_IN and VECTYPE_OUT have
2427
   integer elements and if we can narrow VECTYPE_IN to VECTYPE_OUT
2534
   integer elements and if we can narrow VECTYPE_IN to VECTYPE_OUT
2428
   in a single step.  On success, store the binary pack code in
2535
   in a single step.  On success, store the binary pack code in
Lines 2501-2506 vectorizable_call (gimple *gs, gimple_st Link Here
2501
    return vectorizable_mask_load_store (stmt, gsi, vec_stmt,
2608
    return vectorizable_mask_load_store (stmt, gsi, vec_stmt,
2502
					 slp_node);
2609
					 slp_node);
2503
2610
2611
  if (gimple_call_builtin_p (stmt, BUILT_IN_BSWAP16)
2612
      || gimple_call_builtin_p (stmt, BUILT_IN_BSWAP32)
2613
      || gimple_call_builtin_p (stmt, BUILT_IN_BSWAP64))
2614
    return vectorizable_bswap (stmt, gsi, vec_stmt, slp_node);
2615
2504
  if (gimple_call_lhs (stmt) == NULL_TREE
2616
  if (gimple_call_lhs (stmt) == NULL_TREE
2505
      || TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME)
2617
      || TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME)
2506
    return false;
2618
    return false;

Return to bug 78007