]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR rtl-optimization/85925 (compilation of masking with 257 goes wrong in combine...
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 20 Nov 2018 09:04:12 +0000 (09:04 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 20 Nov 2018 09:04:12 +0000 (09:04 +0000)
2018-11-20  Eric Botcazou  <ebotcazou@adacore.com>

PR rtl-optimization/85925
* rtl.h (word_register_operation_p): New predicate.
* combine.c (record_dead_and_set_regs_1): Only apply specific handling
for WORD_REGISTER_OPERATIONS targets to word_register_operation_p RTX.
* rtlanal.c (nonzero_bits1): Likewise.  Adjust couple of comments.
(num_sign_bit_copies1): Likewise.

From-SVN: r266304

gcc/ChangeLog
gcc/combine.c
gcc/rtl.h
gcc/rtlanal.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20181120-1.c [new file with mode: 0644]

index 2d07ddf9d440db80d18cc7ee2bd90aa6b3344172..091748a6bad6e7af81cd2cb322b1dd1a3d35aa7b 100644 (file)
@@ -1,3 +1,12 @@
+2018-11-20  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR rtl-optimization/85925
+       * rtl.h (word_register_operation_p): New predicate.
+       * combine.c (record_dead_and_set_regs_1): Only apply specific handling
+       for WORD_REGISTER_OPERATIONS targets to word_register_operation_p RTX.
+       * rtlanal.c (nonzero_bits1): Likewise.  Adjust couple of comments.
+       (num_sign_bit_copies1): Likewise.
+
 2018-11-18  Uros Bizjak  <ubizjak@gmail.com>
 
        Backport from mainline
index 8da96d23cc8d1cf8da2f0a3c63d62ecb66e9566f..bc023d2f994aa891b95a9a730a93b8fbe8a365e5 100644 (file)
@@ -13117,6 +13117,7 @@ record_dead_and_set_regs_1 (rtx dest, const_rtx setter, void *data)
               && subreg_lowpart_p (SET_DEST (setter)))
        record_value_for_reg (dest, record_dead_insn,
                              WORD_REGISTER_OPERATIONS
+                             && word_register_operation_p (SET_SRC (setter))
                              && paradoxical_subreg_p (SET_DEST (setter))
                              ? SET_SRC (setter)
                              : gen_lowpart (GET_MODE (dest),
index 93330425c00f26b19e30076cf91382418f9c49c2..05372cf8c95bcd7ba1e8c3b645f8aa8919f913ff 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -3832,6 +3832,25 @@ load_extend_op (machine_mode mode)
   return UNKNOWN;
 }
 
+/* Return true if X is an operation that always operates on the full
+   registers for WORD_REGISTER_OPERATIONS architectures.  */
+
+inline bool
+word_register_operation_p (const_rtx x)
+{
+  switch (GET_CODE (x))
+    {
+    case ROTATE:
+    case ROTATERT:
+    case SIGN_EXTRACT:
+    case ZERO_EXTRACT:
+      return false;
+    
+    default:
+      return true;
+    }
+}
+    
 /* gtype-desc.c.  */
 extern void gt_ggc_mx (rtx &);
 extern void gt_pch_nx (rtx &);
index 772a6a993bb05cbbdbb456626fae7860be6ac206..5df0e5d6fdd0f64d73d01f93514c470114b8129d 100644 (file)
@@ -4339,14 +4339,14 @@ nonzero_bits1 (const_rtx x, machine_mode mode, const_rtx known_x,
      might be nonzero in its own mode, taking into account the fact that, on
      CISC machines, accessing an object in a wider mode generally causes the
      high-order bits to become undefined, so they are not known to be zero.
-     We extend this reasoning to RISC machines for rotate operations since the
-     semantics of the operations in the larger mode is not well defined.  */
+     We extend this reasoning to RISC machines for operations that might not
+     operate on the full registers.  */
   if (GET_MODE (x) != VOIDmode
       && GET_MODE (x) != mode
       && GET_MODE_PRECISION (GET_MODE (x)) <= BITS_PER_WORD
       && GET_MODE_PRECISION (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
       && GET_MODE_PRECISION (mode) > GET_MODE_PRECISION (GET_MODE (x))
-      && (!WORD_REGISTER_OPERATIONS || code == ROTATE))
+      && !(WORD_REGISTER_OPERATIONS && word_register_operation_p (x)))
     {
       nonzero &= cached_nonzero_bits (x, GET_MODE (x),
                                      known_x, known_mode, known_ret);
@@ -4623,13 +4623,16 @@ nonzero_bits1 (const_rtx x, machine_mode mode, const_rtx known_x,
          nonzero &= cached_nonzero_bits (SUBREG_REG (x), mode,
                                          known_x, known_mode, known_ret);
 
-          /* On many CISC machines, accessing an object in a wider mode
+          /* On a typical CISC machine, accessing an object in a wider mode
             causes the high-order bits to become undefined.  So they are
-            not known to be zero.  */
+            not known to be zero.
+
+            On a typical RISC machine, we only have to worry about the way
+            loads are extended.  Otherwise, if we get a reload for the inner
+            part, it may be loaded from the stack, and then we may lose all
+            the zero bits that existed before the store to the stack.  */
          rtx_code extend_op;
          if ((!WORD_REGISTER_OPERATIONS
-              /* If this is a typical RISC machine, we only have to worry
-                 about the way loads are extended.  */
               || ((extend_op = load_extend_op (inner_mode)) == SIGN_EXTEND
                   ? val_signbit_known_set_p (inner_mode, nonzero)
                   : extend_op != ZERO_EXTEND)
@@ -4872,10 +4875,9 @@ num_sign_bit_copies1 (const_rtx x, machine_mode mode, const_rtx known_x,
     {
       /* If this machine does not do all register operations on the entire
         register and MODE is wider than the mode of X, we can say nothing
-        at all about the high-order bits.  We extend this reasoning to every
-        machine for rotate operations since the semantics of the operations
-        in the larger mode is not well defined.  */
-      if (!WORD_REGISTER_OPERATIONS || code == ROTATE || code == ROTATERT)
+        at all about the high-order bits.  We extend this reasoning to RISC
+        machines for operations that might not operate on full registers.  */
+      if (!(WORD_REGISTER_OPERATIONS && word_register_operation_p (x)))
        return 1;
 
       /* Likewise on machines that do, if the mode of the object is smaller
@@ -4965,10 +4967,10 @@ num_sign_bit_copies1 (const_rtx x, machine_mode mode, const_rtx known_x,
 
       /* For paradoxical SUBREGs on machines where all register operations
         affect the entire register, just look inside.  Note that we are
-        passing MODE to the recursive call, so the number of sign bit copies
-        will remain relative to that mode, not the inner mode.  */
+        passing MODE to the recursive call, so the number of sign bit
+        copies will remain relative to that mode, not the inner mode.
 
-      /* This works only if loads sign extend.  Otherwise, if we get a
+         This works only if loads sign extend.  Otherwise, if we get a
         reload for the inner part, it may be loaded from the stack, and
         then we lose all sign bit copies that existed before the store
         to the stack.  */
index 37ef7160cc192e66d4ba31b35aa60e4c3fa81749..c8dabcce523b7870f77a1ea8ff9792cf6daf61e4 100644 (file)
@@ -1,3 +1,7 @@
+2018-11-20  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc.c-torture/execute/20181120-1.c: New test.
+
 2018-11-18  Uros Bizjak  <ubizjak@gmail.com>
 
        Backport from mainline
diff --git a/gcc/testsuite/gcc.c-torture/execute/20181120-1.c b/gcc/testsuite/gcc.c-torture/execute/20181120-1.c
new file mode 100644 (file)
index 0000000..21e5f7a
--- /dev/null
@@ -0,0 +1,26 @@
+/* PR rtl-optimization/85925 */
+/* Testcase by <sudi@gcc.gnu.org> */
+
+int a, c, d;
+volatile int b;
+int *e = &d;
+
+union U1 {
+  unsigned f0;
+  unsigned f1 : 15;
+};
+
+int main (void)
+{
+  for (c = 0; c <= 1; c++) {
+    union U1 f = {0x10101};
+    if (c == 1)
+      b;
+    *e = f.f1;
+  }
+
+  if (d != 0x101)
+    __builtin_abort ();
+
+  return 0;
+}