This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Fix PR middle-end/85496
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 23 Apr 2018 13:24:27 +0200
- Subject: [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;
}