diff mbox

[i386] Fix PR64882, ICE on valid code at -O3 with -g enabled in simplify_subreg, at simplify-rtx.c:5681

Message ID CAFULd4YsRp0F4Eyz54odVU6MR08sBrq8cbutMLJ0uMnNd5+-bQ@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak Jan. 31, 2015, 3:44 p.m. UTC
Hello!

Attached patch fixes PR64882, where special predicate
address_no_seg_operand allowed operands in DImode, as well as SImode.
This resulted in invalid RTX, produced by *lea<mode>:

(insn 60 59 61 3 (set (reg:SI 2 cx [orig:103 D.1909 ] [103])
        (plus:DI (reg:DI 0 ax [106])
            (reg:DI 1 dx [orig:104 D.1912 ] [104]))) pr64882.c:27 213 {*leasi}
     (nil))

The patch tightens the predicate to account for non-VOID modes, while
still allowing VOIDmode CONST_INTs.

Additionally, the patch clears a mess around the mode of the
address_operand (luckily, x86 ignores this mode, see
ix86_legitimate_address_p) and changes all uses to explicitly pass
VOIDmode. Please note that the mode of address_operand predicate means
the mode at the pointed location, not the mode of the operand itself.

2015-01-31  Uros Bizjak  <ubizjak@gmail.com>

        PR target/64882
    * config/i386/predicates.md (address_no_seg_operand): Reject
    non-CONST_INT_P operands in invalid mode.

2015-01-31  Uros Bizjak  <ubizjak@gmail.com>

    * config/i386/i386.md (*prefetch_prefetchw1): Remove mode of
    address_operand 0.  Rename from *prefetch_prefetchwt1_<mode>.
    * config/i386/predicates.md (address_no_seg_operand): Call
    address_operand with VOIDmode.
    (vsib_address_operand): Ditto.
    (address_mpx_no_base_operand): Ditto.
    (address_mpx_no_index_operand): Ditto.

testsuite/ChangeLog:

2015-01-31  Uros Bizjak  <ubizjak@gmail.com>

        PR target/64882
    * gcc.dg/torture/pr64882.c: New test.

Patch was bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Patch was committed to mainline SVN, and will be backported to other
release branches.

Uros.
diff mbox

Patch

Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 220302)
+++ config/i386/i386.md	(working copy)
@@ -18117,8 +18117,8 @@ 
 	(symbol_ref "memory_address_length (operands[0], false)"))
    (set_attr "memory" "none")])
 
-(define_insn "*prefetch_prefetchwt1_<mode>"
-  [(prefetch (match_operand:P 0 "address_operand" "p")
+(define_insn "*prefetch_prefetchwt1"
+  [(prefetch (match_operand 0 "address_operand" "p")
 	     (const_int 1)
 	     (const_int 2))]
   "TARGET_PREFETCHWT1"
Index: config/i386/predicates.md
===================================================================
--- config/i386/predicates.md	(revision 220302)
+++ config/i386/predicates.md	(working copy)
@@ -966,11 +966,16 @@ 
 ;; a segment override.  Defined as a special predicate to allow
 ;; mode-less const_int operands pass to address_operand.
 (define_special_predicate "address_no_seg_operand"
-  (match_operand 0 "address_operand")
+  (match_test "address_operand (op, VOIDmode)")
 {
   struct ix86_address parts;
   int ok;
 
+  if (!CONST_INT_P (op)
+      && mode != VOIDmode
+      && GET_MODE (op) != mode)
+    return false;
+
   ok = ix86_decompose_address (op, &parts);
   gcc_assert (ok);
   return parts.seg == SEG_DEFAULT;
@@ -979,7 +984,7 @@ 
 ;; Return true if op if a valid base register, displacement or
 ;; sum of base register and displacement for VSIB addressing.
 (define_predicate "vsib_address_operand"
-  (match_operand 0 "address_operand")
+  (match_test "address_operand (op, VOIDmode)")
 {
   struct ix86_address parts;
   int ok;
@@ -1020,7 +1025,7 @@ 
 
 ;; Return true if op is valid MPX address operand without base
 (define_predicate "address_mpx_no_base_operand"
-  (match_operand 0 "address_operand")
+  (match_test "address_operand (op, VOIDmode)")
 {
   struct ix86_address parts;
   int ok;
@@ -1052,7 +1057,7 @@ 
 
 ;; Return true if op is valid MPX address operand without index
 (define_predicate "address_mpx_no_index_operand"
-  (match_operand 0 "address_operand")
+  (match_test "address_operand (op, VOIDmode)")
 {
   struct ix86_address parts;
   int ok;
Index: testsuite/gcc.dg/torture/pr64882.c
===================================================================
--- testsuite/gcc.dg/torture/pr64882.c	(revision 0)
+++ testsuite/gcc.dg/torture/pr64882.c	(working copy)
@@ -0,0 +1,33 @@ 
+/* PR target/64882 */
+/* { dg-do compile } */
+
+int a, d, e;
+long long b;
+static long long *c = &b;
+
+void
+fn1 (short p)
+{
+}
+
+long long
+fn2 (long long p1, long long p2)
+{
+  return (p1 && p1 > 26854775807LL - p2) || p1 < -p2 ? p1 : p1 + p2;
+}
+
+void
+fn3 ()
+{
+  long long f;
+  int g = 3;
+  int *h = &a;
+  for (e = 0; e < 2; e++)
+    {
+      int *i = &g;
+      if (!fn2 (*c, 7 < d % (*i)--))
+	f = fn2 ((*h <= 0) | b, 5278350700LL);
+      *h = f;
+      fn1 (*h);
+    }
+}