Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE
gcc48.8043
pr58369.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File pr58369.patch of Package gcc48.8043
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. testsuite/ * PR rtl-optimization/58369 * g++.dg/torture/pr58369.C: New test. Index: gcc-4.8.2-r203692/gcc/reload1.c =================================================================== --- gcc-4.8.2-r203692.orig/gcc/reload1.c +++ gcc-4.8.2-r203692/gcc/reload1.c @@ -6362,6 +6362,37 @@ replaced_subreg (rtx x) } #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 into hard regs for this insn. Also output the instructions to copy them in and out of the hard regs. @@ -6499,6 +6530,7 @@ choose_reload_regs (struct insn_chain *c int byte = 0; int regno = -1; enum machine_mode mode = VOIDmode; + rtx subreg = NULL_RTX; if (rld[r].in == 0) ; @@ -6519,7 +6551,10 @@ choose_reload_regs (struct insn_chain *c if (regno < FIRST_PSEUDO_REGISTER) regno = subreg_regno (rld[r].in_reg); else - byte = SUBREG_BYTE (rld[r].in_reg); + { + subreg = rld[r].in_reg; + byte = SUBREG_BYTE (subreg); + } mode = GET_MODE (rld[r].in_reg); } #ifdef AUTO_INC_DEC @@ -6557,6 +6592,9 @@ choose_reload_regs (struct insn_chain *c rtx last_reg = reg_last_reload_reg[regno]; 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); last_class = REGNO_REG_CLASS (i); Index: gcc-4.8.2-r203692/gcc/testsuite/g++.dg/torture/pr58369.C =================================================================== --- /dev/null +++ gcc-4.8.2-r203692/gcc/testsuite/g++.dg/torture/pr58369.C @@ -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); +} +
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor