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  <ebotca...@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  <ebotca...@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 <mpola...@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;
}

Reply via email to