The sign bit of a sign-extending load cannot be known until runtime,
so don't attempt to simplify it in the combiner.

2024-02-22  Greg McGary  <g...@rivosinc.com>

        PR rtl-optimization/113010
        * combine.cc (simplify_comparison): Don't simplify high part
        of paradoxical-SUBREG-of-MEM on machines that sign-extend loads

        * gcc.c-torture/execute/pr113010.c: New test.
---
 gcc/combine.cc                                 | 10 ++++++++--
 gcc/testsuite/gcc.c-torture/execute/pr113010.c |  9 +++++++++
 2 files changed, 17 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr113010.c

diff --git a/gcc/combine.cc b/gcc/combine.cc
index 812553c091e..736206242e1 100644
--- a/gcc/combine.cc
+++ b/gcc/combine.cc
@@ -12550,9 +12550,15 @@ simplify_comparison (enum rtx_code code, rtx *pop0, 
rtx *pop1)
            }
 
          /* If the inner mode is narrower and we are extracting the low part,
-            we can treat the SUBREG as if it were a ZERO_EXTEND.  */
+            we can treat the SUBREG as if it were a ZERO_EXTEND ...  */
          if (paradoxical_subreg_p (op0))
-           ;
+           {
+             /* ... except we can't treat as ZERO_EXTEND when a machine
+                automatically sign-extends loads. */
+             if (MEM_P (SUBREG_REG (op0)) && WORD_REGISTER_OPERATIONS
+                 && load_extend_op (inner_mode) == SIGN_EXTEND)
+               break;
+           }
          else if (subreg_lowpart_p (op0)
                   && GET_MODE_CLASS (mode) == MODE_INT
                   && is_int_mode (GET_MODE (SUBREG_REG (op0)), &inner_mode)
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr113010.c 
b/gcc/testsuite/gcc.c-torture/execute/pr113010.c
new file mode 100644
index 00000000000..a95c613c1df
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr113010.c
@@ -0,0 +1,9 @@
+int minus_1 = -1;
+
+int
+main ()
+{
+  if ((0, 0xfffffffful) >= minus_1)
+    __builtin_abort ();
+  return 0;
+}
-- 
2.34.1

Reply via email to