summaryrefslogtreecommitdiff
path: root/gcc48-pr78416.patch
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2024-08-01 14:23:42 +0000
committerCoprDistGit <infra@openeuler.org>2024-08-01 14:23:42 +0000
commit82711f6567ef069eebb942e382e2c3fa61fbf538 (patch)
tree22200b7326b32ca672ffb6e4ce6d19a09dc476e5 /gcc48-pr78416.patch
parent5d624aa0d36abe76a344f0593eae5cf36d083b15 (diff)
automatic import of compat-libgfortran-48openeuler24.03_LTSopeneuler23.09
Diffstat (limited to 'gcc48-pr78416.patch')
-rw-r--r--gcc48-pr78416.patch108
1 files changed, 108 insertions, 0 deletions
diff --git a/gcc48-pr78416.patch b/gcc48-pr78416.patch
new file mode 100644
index 0000000..76e6e93
--- /dev/null
+++ b/gcc48-pr78416.patch
@@ -0,0 +1,108 @@
+2016-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/78416
+ * expmed.c (expand_divmod): For modes wider than HWI, take into
+ account implicit 1 bits above msb for EXACT_POWER_OF_2_OR_ZERO_P.
+
+ * gcc.dg/torture/pr78416.c: New test.
+
+--- gcc/expmed.c
++++ gcc/expmed.c
+@@ -3844,7 +3844,15 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
+ if (unsignedp)
+ ext_op1 &= GET_MODE_MASK (mode);
+ op1_is_pow2 = ((EXACT_POWER_OF_2_OR_ZERO_P (ext_op1)
+- || (! unsignedp && EXACT_POWER_OF_2_OR_ZERO_P (-ext_op1))));
++ /* If mode is wider than HWI and op1 has msb set,
++ then it has there extra implicit 1 bits above it. */
++ && (GET_MODE_PRECISION (mode) <= HOST_BITS_PER_WIDE_INT
++ || INTVAL (op1) >= 0))
++ || (! unsignedp
++ && EXACT_POWER_OF_2_OR_ZERO_P (-ext_op1)
++ && (GET_MODE_PRECISION (mode)
++ <= HOST_BITS_PER_WIDE_INT
++ || INTVAL (op1) < 0)));
+ }
+
+ /*
+@@ -3987,8 +3995,17 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
+ op1_is_constant = CONST_INT_P (op1);
+ op1_is_pow2 = (op1_is_constant
+ && ((EXACT_POWER_OF_2_OR_ZERO_P (INTVAL (op1))
+- || (! unsignedp
+- && EXACT_POWER_OF_2_OR_ZERO_P (-UINTVAL (op1))))));
++ /* If mode is wider than HWI and op1 has msb set,
++ then it has there extra implicit 1 bits above
++ it. */
++ && (GET_MODE_PRECISION (compute_mode)
++ <= HOST_BITS_PER_WIDE_INT
++ || INTVAL (op1) >= 0))
++ || (! unsignedp
++ && EXACT_POWER_OF_2_OR_ZERO_P (-UINTVAL (op1))
++ && (GET_MODE_PRECISION (compute_mode)
++ <= HOST_BITS_PER_WIDE_INT
++ || INTVAL (op1) < 0))));
+ }
+
+ /* If one of the operands is a volatile MEM, copy it into a register. */
+@@ -4031,7 +4048,8 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
+ unsigned HOST_WIDE_INT d = (INTVAL (op1)
+ & GET_MODE_MASK (compute_mode));
+
+- if (EXACT_POWER_OF_2_OR_ZERO_P (d))
++ if (EXACT_POWER_OF_2_OR_ZERO_P (d)
++ && (INTVAL (op1) >= 0 || size <= HOST_BITS_PER_WIDE_INT))
+ {
+ pre_shift = floor_log2 (d);
+ if (rem_flag)
+@@ -4179,6 +4197,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
+ goto fail1;
+ }
+ else if (EXACT_POWER_OF_2_OR_ZERO_P (d)
++ && (size <= HOST_BITS_PER_WIDE_INT || d >= 0)
+ && (rem_flag
+ ? smod_pow2_cheap (speed, compute_mode)
+ : sdiv_pow2_cheap (speed, compute_mode))
+@@ -4192,7 +4211,9 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
+ compute_mode)
+ != CODE_FOR_nothing)))
+ ;
+- else if (EXACT_POWER_OF_2_OR_ZERO_P (abs_d))
++ else if (EXACT_POWER_OF_2_OR_ZERO_P (abs_d)
++ && (size <= HOST_BITS_PER_WIDE_INT
++ || abs_d != (unsigned HOST_WIDE_INT) d))
+ {
+ if (rem_flag)
+ {
+@@ -4504,7 +4525,10 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
+ case CEIL_MOD_EXPR:
+ if (unsignedp)
+ {
+- if (op1_is_constant && EXACT_POWER_OF_2_OR_ZERO_P (INTVAL (op1)))
++ if (op1_is_constant
++ && EXACT_POWER_OF_2_OR_ZERO_P (INTVAL (op1))
++ && (size <= HOST_BITS_PER_WIDE_INT
++ || INTVAL (op1) >= 0))
+ {
+ rtx t1, t2, t3;
+ unsigned HOST_WIDE_INT d = INTVAL (op1);
+--- gcc/testsuite/gcc.dg/torture/pr78416.c
++++ gcc/testsuite/gcc.dg/torture/pr78416.c
+@@ -0,0 +1,17 @@
++/* PR middle-end/78416 */
++/* { dg-do run { target int128 } } */
++
++int
++main ()
++{
++ unsigned __int128 x;
++ x = 0xFFFFFFFFFFFFFFFFULL;
++ x /= ~0x7FFFFFFFFFFFFFFFLL;
++ if (x != 0)
++ __builtin_abort ();
++ x = ~0x7FFFFFFFFFFFFFFELL;
++ x /= ~0x7FFFFFFFFFFFFFFFLL;
++ if (x != 1)
++ __builtin_abort ();
++ return 0;
++}