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

Collapse All | Expand All

(-)gcc/cp/typeck.c (-2 / +30 lines)
Lines 4368-4388 cp_build_binary_op (const op_location_t Link Here
4368
  int converted = 0;
4368
  int converted = 0;
4369
4369
4370
  /* Nonzero means create the expression with this type, rather than
4370
  /* Nonzero means create the expression with this type, rather than
4371
     RESULT_TYPE.  */
4371
     RESULT_TYPE.  */
4372
  tree build_type = 0;
4372
  tree build_type = 0;
4373
4373
4374
  /* Nonzero means after finally constructing the expression
4374
  /* Nonzero means after finally constructing the expression
4375
     convert it to this type.  */
4375
     convert it to this type.  */
4376
  tree final_type = 0;
4376
  tree final_type = 0;
4377
4377
4378
  tree result, result_ovl;
4378
  tree result = NULL, result_ovl;
4379
4379
4380
  /* Nonzero if this is an operation like MIN or MAX which can
4380
  /* Nonzero if this is an operation like MIN or MAX which can
4381
     safely be computed in short if both args are promoted shorts.
4381
     safely be computed in short if both args are promoted shorts.
4382
     Also implies COMMON.
4382
     Also implies COMMON.
4383
     -1 indicates a bitwise operation; this makes a difference
4383
     -1 indicates a bitwise operation; this makes a difference
4384
     in the exact conditions for when it is safe to do the operation
4384
     in the exact conditions for when it is safe to do the operation
4385
     in a narrower mode.  */
4385
     in a narrower mode.  */
4386
  int shorten = 0;
4386
  int shorten = 0;
4387
4387
4388
  /* Nonzero if this is a comparison operation;
4388
  /* Nonzero if this is a comparison operation;
Lines 5544-5564 cp_build_binary_op (const op_location_t Link Here
5544
	  if (TREE_TYPE (cop0) != orig_type)
5544
	  if (TREE_TYPE (cop0) != orig_type)
5545
	    cop0 = cp_convert (orig_type, op0, complain);
5545
	    cop0 = cp_convert (orig_type, op0, complain);
5546
	  if (TREE_TYPE (cop1) != orig_type)
5546
	  if (TREE_TYPE (cop1) != orig_type)
5547
	    cop1 = cp_convert (orig_type, op1, complain);
5547
	    cop1 = cp_convert (orig_type, op1, complain);
5548
	  instrument_expr = ubsan_instrument_division (location, cop0, cop1);
5548
	  instrument_expr = ubsan_instrument_division (location, cop0, cop1);
5549
	}
5549
	}
5550
      else if (doing_shift && sanitize_flags_p (SANITIZE_SHIFT))
5550
      else if (doing_shift && sanitize_flags_p (SANITIZE_SHIFT))
5551
	instrument_expr = ubsan_instrument_shift (location, code, op0, op1);
5551
	instrument_expr = ubsan_instrument_shift (location, code, op0, op1);
5552
    }
5552
    }
5553
5553
5554
  result = build2_loc (location, resultcode, build_type, op0, op1);
5554
  // FIXME: vectors and complex as well
5555
  if (flag_rounding_math && SCALAR_FLOAT_TYPE_P (build_type))
5556
    {
5557
      bool do_fenv_subst = true;
5558
      internal_fn ifn;
5559
      switch (resultcode)
5560
	{
5561
	case PLUS_EXPR:
5562
	  ifn = IFN_FENV_PLUS;
5563
	  break;
5564
	case MINUS_EXPR:
5565
	  ifn = IFN_FENV_MINUS;
5566
	  break;
5567
	case MULT_EXPR:
5568
	  ifn = IFN_FENV_MULT;
5569
	  break;
5570
	case RDIV_EXPR:
5571
	  ifn = IFN_FENV_DIV;
5572
	  break;
5573
	default:
5574
	  do_fenv_subst = false;
5575
	}
5576
      if (do_fenv_subst)
5577
	return build_call_expr_internal_loc (location, ifn, build_type,
5578
					     2, op0, op1);
5579
    }
5580
5581
  if (!result)
5582
    result = build2_loc (location, resultcode, build_type, op0, op1);
5555
  if (final_type != 0)
5583
  if (final_type != 0)
5556
    result = cp_convert (final_type, result, complain);
5584
    result = cp_convert (final_type, result, complain);
5557
5585
5558
  if (instrument_expr != NULL)
5586
  if (instrument_expr != NULL)
5559
    result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
5587
    result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
5560
		     instrument_expr, result);
5588
		     instrument_expr, result);
5561
5589
5562
  if (!processing_template_decl)
5590
  if (!processing_template_decl)
5563
    {
5591
    {
5564
      op0 = cp_fully_fold (op0);
5592
      op0 = cp_fully_fold (op0);
(-)gcc/internal-fn.c (+26 lines)
Lines 2869-2888 expand_DIVMOD (internal_fn, gcall *call_ Link Here
2869
}
2869
}
2870
2870
2871
/* Expand a NOP.  */
2871
/* Expand a NOP.  */
2872
2872
2873
static void
2873
static void
2874
expand_NOP (internal_fn, gcall *)
2874
expand_NOP (internal_fn, gcall *)
2875
{
2875
{
2876
  /* Nothing.  But it shouldn't really prevail.  */
2876
  /* Nothing.  But it shouldn't really prevail.  */
2877
}
2877
}
2878
2878
2879
/* This should get expanded in the wmul pass.  */
2880
2881
static void
2882
expand_FENV_PLUS (internal_fn, gcall *)
2883
{
2884
  gcc_unreachable ();
2885
}
2886
2887
static void
2888
expand_FENV_MINUS (internal_fn, gcall *)
2889
{
2890
  gcc_unreachable ();
2891
}
2892
2893
static void
2894
expand_FENV_MULT (internal_fn, gcall *)
2895
{
2896
  gcc_unreachable ();
2897
}
2898
2899
static void
2900
expand_FENV_DIV (internal_fn, gcall *)
2901
{
2902
  gcc_unreachable ();
2903
}
2904
2879
/* Expand a call to FN using the operands in STMT.  FN has a single
2905
/* Expand a call to FN using the operands in STMT.  FN has a single
2880
   output operand and NARGS input operands.  */
2906
   output operand and NARGS input operands.  */
2881
2907
2882
static void
2908
static void
2883
expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
2909
expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
2884
			unsigned int nargs)
2910
			unsigned int nargs)
2885
{
2911
{
2886
  expand_operand *ops = XALLOCAVEC (expand_operand, nargs + 1);
2912
  expand_operand *ops = XALLOCAVEC (expand_operand, nargs + 1);
2887
2913
2888
  tree_pair types = direct_internal_fn_types (fn, stmt);
2914
  tree_pair types = direct_internal_fn_types (fn, stmt);
(-)gcc/internal-fn.def (+6 lines)
Lines 345-360 DEF_INTERNAL_FN (FALLTHROUGH, ECF_LEAF | Link Here
345
345
346
/* To implement __builtin_launder.  */
346
/* To implement __builtin_launder.  */
347
DEF_INTERNAL_FN (LAUNDER, ECF_LEAF | ECF_NOTHROW | ECF_NOVOPS, NULL)
347
DEF_INTERNAL_FN (LAUNDER, ECF_LEAF | ECF_NOTHROW | ECF_NOVOPS, NULL)
348
348
349
/* Divmod function.  */
349
/* Divmod function.  */
350
DEF_INTERNAL_FN (DIVMOD, ECF_CONST | ECF_LEAF, NULL)
350
DEF_INTERNAL_FN (DIVMOD, ECF_CONST | ECF_LEAF, NULL)
351
351
352
/* A NOP function with arbitrary arguments and return value.  */
352
/* A NOP function with arbitrary arguments and return value.  */
353
DEF_INTERNAL_FN (NOP, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
353
DEF_INTERNAL_FN (NOP, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
354
354
355
/* float operations with rounding / exception flags.  */
356
DEF_INTERNAL_FN (FENV_PLUS, ECF_LEAF | ECF_NOTHROW, NULL)
357
DEF_INTERNAL_FN (FENV_MINUS, ECF_LEAF | ECF_NOTHROW, NULL)
358
DEF_INTERNAL_FN (FENV_MULT, ECF_LEAF | ECF_NOTHROW, NULL)
359
DEF_INTERNAL_FN (FENV_DIV, ECF_LEAF | ECF_NOTHROW, NULL)
360
355
#undef DEF_INTERNAL_INT_FN
361
#undef DEF_INTERNAL_INT_FN
356
#undef DEF_INTERNAL_FLT_FN
362
#undef DEF_INTERNAL_FLT_FN
357
#undef DEF_INTERNAL_FLT_FLOATN_FN
363
#undef DEF_INTERNAL_FLT_FLOATN_FN
358
#undef DEF_INTERNAL_SIGNED_OPTAB_FN
364
#undef DEF_INTERNAL_SIGNED_OPTAB_FN
359
#undef DEF_INTERNAL_OPTAB_FN
365
#undef DEF_INTERNAL_OPTAB_FN
360
#undef DEF_INTERNAL_FN
366
#undef DEF_INTERNAL_FN
(-)gcc/tree-ssa-math-opts.c (+63 lines)
Lines 3732-3751 public: Link Here
3732
3732
3733
  /* Set of results of chains of multiply and add statement combinations that
3733
  /* Set of results of chains of multiply and add statement combinations that
3734
     were not transformed into FMAs because of active deferring.  */
3734
     were not transformed into FMAs because of active deferring.  */
3735
  hash_set<tree> m_last_result_set;
3735
  hash_set<tree> m_last_result_set;
3736
3736
3737
  /* Pointer to a flag of the user that needs to be set if CFG has been
3737
  /* Pointer to a flag of the user that needs to be set if CFG has been
3738
     modified.  */
3738
     modified.  */
3739
  bool *m_cfg_changed_p;
3739
  bool *m_cfg_changed_p;
3740
};
3740
};
3741
3741
3742
static gasm*
3743
barrier1 (tree out, tree in)
3744
{
3745
  vec<tree, va_gc> *inputs = NULL, *outputs = NULL;
3746
  vec_safe_push (inputs,
3747
		 build_tree_list (build_tree_list
3748
				  (NULL_TREE, build_string (2, "0")), in));
3749
  vec_safe_push (outputs,
3750
		 build_tree_list (build_tree_list
3751
				  (NULL_TREE, build_string (3, "=g")), out));
3752
  gasm *g = gimple_build_asm_vec ("", inputs, outputs, NULL, NULL);
3753
  gimple_asm_set_volatile (g, true);
3754
  SSA_NAME_DEF_STMT (out) = g;
3755
  return g;
3756
}
3757
3742
void
3758
void
3743
math_opts_dom_walker::after_dom_children (basic_block bb)
3759
math_opts_dom_walker::after_dom_children (basic_block bb)
3744
{
3760
{
3745
  gimple_stmt_iterator gsi;
3761
  gimple_stmt_iterator gsi;
3746
3762
3747
  fma_deferring_state fma_state (PARAM_VALUE (PARAM_AVOID_FMA_MAX_BITS) > 0);
3763
  fma_deferring_state fma_state (PARAM_VALUE (PARAM_AVOID_FMA_MAX_BITS) > 0);
3748
3764
3749
  for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
3765
  for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
3750
    {
3766
    {
3751
      gimple *stmt = gsi_stmt (gsi);
3767
      gimple *stmt = gsi_stmt (gsi);
Lines 3808-3827 math_opts_dom_walker::after_dom_children Link Here
3808
			  && gimple_purge_dead_eh_edges (bb))
3824
			  && gimple_purge_dead_eh_edges (bb))
3809
			*m_cfg_changed_p = true;
3825
			*m_cfg_changed_p = true;
3810
		      release_defs (stmt);
3826
		      release_defs (stmt);
3811
		      continue;
3827
		      continue;
3812
		    }
3828
		    }
3813
		  break;
3829
		  break;
3814
3830
3815
		default:;
3831
		default:;
3816
		}
3832
		}
3817
	    }
3833
	    }
3834
	  else if (gimple_call_internal_p (stmt))
3835
	    {
3836
	      internal_fn ifn = gimple_call_internal_fn (stmt);
3837
	      bool doit = true;
3838
	      tree_code code;
3839
	      switch (ifn)
3840
		{
3841
		case IFN_FENV_PLUS:
3842
		  code = PLUS_EXPR;
3843
		  break;
3844
		case IFN_FENV_MINUS:
3845
		  code = MINUS_EXPR;
3846
		  break;
3847
		case IFN_FENV_MULT:
3848
		  code = MULT_EXPR;
3849
		  break;
3850
		case IFN_FENV_DIV:
3851
		  code = RDIV_EXPR;
3852
		  break;
3853
		default:
3854
		  doit = false;
3855
		}
3856
	      tree lhs = gimple_call_lhs (stmt);
3857
	      if (!lhs)
3858
		doit = false;
3859
3860
	      if (doit)
3861
		{
3862
		  tree op0 = gimple_call_arg (stmt, 0);
3863
		  tree op1 = gimple_call_arg (stmt, 1);
3864
		  tree nop0 = make_ssa_name (TREE_TYPE (op0));
3865
		  tree nop1 = make_ssa_name (TREE_TYPE (op1));
3866
		  gsi_insert_before (&gsi, barrier1 (nop0, op0),
3867
				     GSI_SAME_STMT);
3868
		  gsi_insert_before (&gsi, barrier1 (nop1, op1),
3869
				     GSI_SAME_STMT);
3870
3871
		  tree nlhs = make_ssa_name (TREE_TYPE (lhs));
3872
		  gimple *new_stmt = gimple_build_assign (nlhs, code,
3873
							  nop0, nop1);
3874
		  gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
3875
		  gsi_replace (&gsi, barrier1 (lhs, nlhs), false);
3876
		  unlink_stmt_vdef (stmt);
3877
3878
		  release_ssa_name (gimple_vdef (stmt));
3879
		}
3880
	    }
3818
	  else
3881
	  else
3819
	    cancel_fma_deferring (&fma_state);
3882
	    cancel_fma_deferring (&fma_state);
3820
	}
3883
	}
3821
      gsi_next (&gsi);
3884
      gsi_next (&gsi);
3822
    }
3885
    }
3823
  if (fma_state.m_deferring_p
3886
  if (fma_state.m_deferring_p
3824
      && fma_state.m_initial_phi)
3887
      && fma_state.m_initial_phi)
3825
    {
3888
    {
3826
      gcc_checking_assert (fma_state.m_last_result);
3889
      gcc_checking_assert (fma_state.m_last_result);
3827
      if (!last_fma_candidate_feeds_initial_phi (&fma_state,
3890
      if (!last_fma_candidate_feeds_initial_phi (&fma_state,

Return to bug 34678