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]

[patch] Fix PR middle-end/85496


Hi,

this is a regression present on all the active branches for targets that 
return values in registers using PARALLELs, when optimization is enabled.
store_field changes the mode of a temporary to ensure that it can be used to 
create a register, leading to a mode mismatch downstream, but that's not 
necessary in this case.  The proposed fix is to get back to the previous 
version of the code, which changed it only for BLKmode and VOIDmode.

Tested on x86-64/Linux and SPARC64/Linux, OK for all active branches?


2018-04-23  Eric Botcazou  <ebotcazou@adacore.com>

	PR middle-end/85496
	* expr.c (store_field): In the bitfield case, if the value comes from
	a function call and is returned in registers by means of a PARALLEL,
	do not change the mode of the temporary unless BLKmode and VOIDmode.


2018-04-23  Eric Botcazou  <ebotcazou@adacore.com>

	* g++.dg/torture/pr85496.C: New test.

-- 
Eric Botcazou
Index: expr.c
===================================================================
--- expr.c	(revision 259515)
+++ expr.c	(working copy)
@@ -6989,8 +6989,9 @@ store_field (rtx target, poly_int64 bits
       if (GET_CODE (temp) == PARALLEL)
 	{
 	  HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
-	  scalar_int_mode temp_mode
-	    = smallest_int_mode_for_size (size * BITS_PER_UNIT);
+	  machine_mode temp_mode = GET_MODE (temp);
+	  if (temp_mode == BLKmode || temp_mode == VOIDmode)
+	    temp_mode = smallest_int_mode_for_size (size * BITS_PER_UNIT);
 	  rtx temp_target = gen_reg_rtx (temp_mode);
 	  emit_group_store (temp_target, temp, TREE_TYPE (exp), size);
 	  temp = temp_target;
// PR middle-end/85496
// Reported by Marek Polacek <mpolacek@gcc.gnu.org>

template <typename> class complex;
template <typename _Tp> complex<_Tp> operator*(complex<_Tp>, complex<_Tp>);
template <> struct complex<float> { _Complex float _M_value; };
class A {
  complex<float> _f0, _f1;

public:
  complex<float> &m_fn1() { return _f1; }
};
complex<float> a;
void cos() {
  A b;
  complex<float> c;
  b.m_fn1() = c * a;
}

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