mirror of git://gcc.gnu.org/git/gcc.git
re PR rtl-optimization/58369 (ICE in subreg_get_info when compiling boost for m68k-linux)
PR rtl-optimization/58369 * reload1.c (compute_reload_subreg_offset): New function. (choose_reload_regs): Use it to pass endian-correct offset to subreg_regno_offset. * PR rtl-optimization/58369 * g++.dg/torture/pr58369.C: New test. From-SVN: r204224
This commit is contained in:
parent
c5028d807f
commit
4608893952
|
|
@ -1,3 +1,10 @@
|
||||||
|
2013-10-18 Mikael Pettersson <mikpelinux@gmail.com>
|
||||||
|
|
||||||
|
PR rtl-optimization/58369
|
||||||
|
* reload1.c (compute_reload_subreg_offset): New function.
|
||||||
|
(choose_reload_regs): Use it to pass endian-correct
|
||||||
|
offset to subreg_regno_offset.
|
||||||
|
|
||||||
2013-10-30 Tobias Burnus <burnus@net-b.de>
|
2013-10-30 Tobias Burnus <burnus@net-b.de>
|
||||||
|
|
||||||
PR other/33426
|
PR other/33426
|
||||||
|
|
|
||||||
|
|
@ -6371,6 +6371,37 @@ replaced_subreg (rtx x)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Compute the offset to pass to subreg_regno_offset, for a pseudo of
|
||||||
|
mode OUTERMODE that is available in a hard reg of mode INNERMODE.
|
||||||
|
SUBREG is non-NULL if the pseudo is a subreg whose reg is a pseudo,
|
||||||
|
otherwise it is NULL. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
compute_reload_subreg_offset (enum machine_mode outermode,
|
||||||
|
rtx subreg,
|
||||||
|
enum machine_mode innermode)
|
||||||
|
{
|
||||||
|
int outer_offset;
|
||||||
|
enum machine_mode middlemode;
|
||||||
|
|
||||||
|
if (!subreg)
|
||||||
|
return subreg_lowpart_offset (outermode, innermode);
|
||||||
|
|
||||||
|
outer_offset = SUBREG_BYTE (subreg);
|
||||||
|
middlemode = GET_MODE (SUBREG_REG (subreg));
|
||||||
|
|
||||||
|
/* If SUBREG is paradoxical then return the normal lowpart offset
|
||||||
|
for OUTERMODE and INNERMODE. Our caller has already checked
|
||||||
|
that OUTERMODE fits in INNERMODE. */
|
||||||
|
if (outer_offset == 0
|
||||||
|
&& GET_MODE_SIZE (outermode) > GET_MODE_SIZE (middlemode))
|
||||||
|
return subreg_lowpart_offset (outermode, innermode);
|
||||||
|
|
||||||
|
/* SUBREG is normal, but may not be lowpart; return OUTER_OFFSET
|
||||||
|
plus the normal lowpart offset for MIDDLEMODE and INNERMODE. */
|
||||||
|
return outer_offset + subreg_lowpart_offset (middlemode, innermode);
|
||||||
|
}
|
||||||
|
|
||||||
/* Assign hard reg targets for the pseudo-registers we must reload
|
/* Assign hard reg targets for the pseudo-registers we must reload
|
||||||
into hard regs for this insn.
|
into hard regs for this insn.
|
||||||
Also output the instructions to copy them in and out of the hard regs.
|
Also output the instructions to copy them in and out of the hard regs.
|
||||||
|
|
@ -6508,6 +6539,7 @@ choose_reload_regs (struct insn_chain *chain)
|
||||||
int byte = 0;
|
int byte = 0;
|
||||||
int regno = -1;
|
int regno = -1;
|
||||||
enum machine_mode mode = VOIDmode;
|
enum machine_mode mode = VOIDmode;
|
||||||
|
rtx subreg = NULL_RTX;
|
||||||
|
|
||||||
if (rld[r].in == 0)
|
if (rld[r].in == 0)
|
||||||
;
|
;
|
||||||
|
|
@ -6528,7 +6560,10 @@ choose_reload_regs (struct insn_chain *chain)
|
||||||
if (regno < FIRST_PSEUDO_REGISTER)
|
if (regno < FIRST_PSEUDO_REGISTER)
|
||||||
regno = subreg_regno (rld[r].in_reg);
|
regno = subreg_regno (rld[r].in_reg);
|
||||||
else
|
else
|
||||||
byte = SUBREG_BYTE (rld[r].in_reg);
|
{
|
||||||
|
subreg = rld[r].in_reg;
|
||||||
|
byte = SUBREG_BYTE (subreg);
|
||||||
|
}
|
||||||
mode = GET_MODE (rld[r].in_reg);
|
mode = GET_MODE (rld[r].in_reg);
|
||||||
}
|
}
|
||||||
#ifdef AUTO_INC_DEC
|
#ifdef AUTO_INC_DEC
|
||||||
|
|
@ -6566,6 +6601,9 @@ choose_reload_regs (struct insn_chain *chain)
|
||||||
rtx last_reg = reg_last_reload_reg[regno];
|
rtx last_reg = reg_last_reload_reg[regno];
|
||||||
|
|
||||||
i = REGNO (last_reg);
|
i = REGNO (last_reg);
|
||||||
|
byte = compute_reload_subreg_offset (mode,
|
||||||
|
subreg,
|
||||||
|
GET_MODE (last_reg));
|
||||||
i += subreg_regno_offset (i, GET_MODE (last_reg), byte, mode);
|
i += subreg_regno_offset (i, GET_MODE (last_reg), byte, mode);
|
||||||
last_class = REGNO_REG_CLASS (i);
|
last_class = REGNO_REG_CLASS (i);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
2013-10-30 Mikael Pettersson <mikpe@it.uu.se>
|
||||||
|
|
||||||
|
* PR rtl-optimization/58369
|
||||||
|
* g++.dg/torture/pr58369.C: New test.
|
||||||
|
|
||||||
2013-10-30 Tobias Burnus <burnus@net-b.de>
|
2013-10-30 Tobias Burnus <burnus@net-b.de>
|
||||||
|
|
||||||
PR other/33426
|
PR other/33426
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,109 @@
|
||||||
|
// { dg-do compile }
|
||||||
|
// Reduced from boost-1.54
|
||||||
|
|
||||||
|
int pow(int, int);
|
||||||
|
int sqrt(int);
|
||||||
|
|
||||||
|
class PolicyA { };
|
||||||
|
|
||||||
|
template <class>
|
||||||
|
int max_value() { return 0x7fffffff; }
|
||||||
|
|
||||||
|
template <class>
|
||||||
|
int min_value() { return 1; }
|
||||||
|
|
||||||
|
void raise_denorm_error();
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void raise_domain_error(int, int, const T &, const PolicyA &);
|
||||||
|
|
||||||
|
template <class>
|
||||||
|
int check_overflow(long double p1) {
|
||||||
|
long double __trans_tmp_2 = __builtin_fabsl(p1);
|
||||||
|
if (__trans_tmp_2 > max_value<int>())
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class>
|
||||||
|
int check_underflow(long double p1) {
|
||||||
|
if (p1 && (double)p1)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class>
|
||||||
|
int check_denorm(long double p1) {
|
||||||
|
long double __trans_tmp_3 = __builtin_fabsl(p1);
|
||||||
|
if (__trans_tmp_3 < min_value<int>() && (double)p1) {
|
||||||
|
raise_denorm_error();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class, class>
|
||||||
|
double checked_narrowing_cast(long double p1) {
|
||||||
|
if (check_overflow<int>(p1))
|
||||||
|
return 0;
|
||||||
|
if (check_underflow<int>(p1))
|
||||||
|
return 0;
|
||||||
|
if (check_denorm<int>(p1))
|
||||||
|
return 0;
|
||||||
|
return (double)p1;
|
||||||
|
}
|
||||||
|
|
||||||
|
long double ellint_rf_imp(long double, long double, long double);
|
||||||
|
|
||||||
|
template <typename T, typename Policy>
|
||||||
|
T ellint_rj_imp(T p1, T p2, T p3, T p4, Policy &p5) {
|
||||||
|
T value, tolerance, P, S3;
|
||||||
|
if (p4)
|
||||||
|
return 0;
|
||||||
|
if (p3 || p1)
|
||||||
|
raise_domain_error(0, 0, 0, p5);
|
||||||
|
tolerance = pow(0, 0);
|
||||||
|
if (p4) {
|
||||||
|
T q = -p4;
|
||||||
|
{
|
||||||
|
long double q6 = ellint_rj_imp((long double)p1, (long double)(double)p2, (long double)(double)p3, (long double)(int)0, p5);
|
||||||
|
value = checked_narrowing_cast<T, int>(q6);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
long double q7 = ellint_rf_imp((long double)p1, (long double)(double)p2, (long double)(double)p3);
|
||||||
|
value -= checked_narrowing_cast<T, const int>(q7);
|
||||||
|
}
|
||||||
|
value += p1 * p3 + p4 * q;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
P = p4 / p1;
|
||||||
|
if (0 < tolerance)
|
||||||
|
break;
|
||||||
|
sqrt(p3);
|
||||||
|
} while (1);
|
||||||
|
S3 = P * p2 * 0;
|
||||||
|
value = S3 / p1;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Policy>
|
||||||
|
void ellint_pi_imp4(double, double p3, Policy &p4) {
|
||||||
|
double x, y, z;
|
||||||
|
ellint_rj_imp(x, y, z, p3, p4);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Policy>
|
||||||
|
double ellint_pi_imp5(double, double p3, double p4, Policy &p5) {
|
||||||
|
double x, y, z, p;
|
||||||
|
if (p3 > 0)
|
||||||
|
return 0;
|
||||||
|
ellint_rj_imp(x, y, z, p, p5);
|
||||||
|
ellint_pi_imp4((double)0, p4, p5);
|
||||||
|
}
|
||||||
|
|
||||||
|
void boost_ellint_3f() {
|
||||||
|
PolicyA p4;
|
||||||
|
ellint_pi_imp5((double)0, (double)0, (double)0, p4);
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue