re PR rtl-optimization/85925 (compilation of masking with 257 goes wrong in combine...
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 20 Nov 2018 08:59:30 +0000 (08:59 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 20 Nov 2018 08:59:30 +0000 (08:59 +0000)
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: r266302

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 0c357fb4bed48c812975d75c2b0d7b21895c2e97..affdfd6cdefbf41508efb4ee3dfe2354a50e783e 100644 (file)
        * dwarf2out.c (dwarf2out_early_global_decl): For
        decl_function_context recurse instead of calling dwarf2out_decl.
 
+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-19  Richard Biener  <rguenther@suse.de>
 
        PR lto/87229
index 945eca3da5acf8b950f32b132cbba69f657b9afc..ecc83f89bcef47deec236bebe16b2685aa0978ed 100644 (file)
@@ -13331,6 +13331,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 68d3ceab29fc392b59e1a9deb33ff653b59fe1fc..4114cd029918cdf8600e96ba9a35af33f622f0f5 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -4374,6 +4374,25 @@ strip_offset_and_add (rtx x, poly_int64_pod *offset)
   return x;
 }
 
+/* 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 e8b6b9c7a4288fe21362903a28b62d4a797e82c4..9220cbf33066ccdeceed9d29deb89927b7ce4fae 100644 (file)
@@ -4485,12 +4485,12 @@ nonzero_bits1 (const_rtx x, scalar_int_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 (mode_width > xmode_width
       && xmode_width <= BITS_PER_WORD
       && xmode_width <= HOST_BITS_PER_WIDE_INT
-      && (!WORD_REGISTER_OPERATIONS || code == ROTATE || code == ROTATERT))
+      && !(WORD_REGISTER_OPERATIONS && word_register_operation_p (x)))
     {
       nonzero &= cached_nonzero_bits (x, xmode,
                                      known_x, known_mode, known_ret);
@@ -4758,13 +4758,16 @@ nonzero_bits1 (const_rtx x, scalar_int_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)
@@ -5025,10 +5028,9 @@ num_sign_bit_copies1 (const_rtx x, scalar_int_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
@@ -5107,13 +5109,12 @@ num_sign_bit_copies1 (const_rtx x, scalar_int_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.  */
+            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.  */
-
          if (WORD_REGISTER_OPERATIONS
              && load_extend_op (inner_mode) == SIGN_EXTEND
              && paradoxical_subreg_p (x)
index 4284ce25dab8c438329e75548d2341082d29033f..e3780472a3d93301ad5d2993f307e62539e75ffa 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-20  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/88087
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;
+}