i386: Fix up *testqi_ext_3 insn&split for the *testdi_1 changes [PR94088]
authorJakub Jelinek <jakub@redhat.com>
Tue, 10 Mar 2020 08:26:44 +0000 (09:26 +0100)
committerJakub Jelinek <jakub@redhat.com>
Tue, 10 Mar 2020 08:26:44 +0000 (09:26 +0100)
In r10-1938-g460bf043c8266dd080308f4783137aee0d0f862c *testdi_1 has been
changed, so that if the mask has upper 32-bits 0 and then at least one bit
set, it requires CCZmode rather than CCNOmode, because in that case it uses
testl instruction rather than testq and so the SF flag wouldn't respect the
state of the 64-bit result.
The *testqi_ext_3 define_insn_and_split needs to match that though,
otherwise it can create an RTL pattern that used to match *testdi_1 but
doesn't anymore and we'd ICE due to an unrecognizable insn.

2020-03-10  Jakub Jelinek  <jakub@redhat.com>

PR target/94088
* config/i386/i386.md (*testqi_ext_3): Call ix86_match_ccmode with
CCZmode instead of CCNOmode if operands[2] has DImode and pos + len
is 32.

* gcc.target/i386/pr94088.c: New test.

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr94088.c [new file with mode: 0644]

index 085ef66a207264ffadce68e554ce7b208a4dc34f..5d5bbf4fed5616a2ec3ff2d7f40eacc8d99a4b04 100644 (file)
@@ -1,3 +1,10 @@
+2020-03-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/94088
+       * config/i386/i386.md (*testqi_ext_3): Call ix86_match_ccmode with
+       CCZmode instead of CCNOmode if operands[2] has DImode and pos + len
+       is 32.
+
 2020-03-09  Jason Merrill  <jason@redhat.com>
 
        * gdbinit.in (pgs): Fix typo in documentation.
index a4ee549567d913c4d06756388ca9f37c4b1728a8..8b5ae34ee1178c6642fceb6e36c71b555c4a3020 100644 (file)
             (match_operand 3 "const_int_operand" "n")
             (match_operand 4 "const_int_operand" "n"))
           (const_int 0)]))]
-  "ix86_match_ccmode (insn, CCNOmode)
-   && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
-       || GET_MODE (operands[2]) == SImode
-       || GET_MODE (operands[2]) == HImode
-       || GET_MODE (operands[2]) == QImode)
+  "((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
+    || GET_MODE (operands[2]) == SImode
+    || GET_MODE (operands[2]) == HImode
+    || GET_MODE (operands[2]) == QImode)
    /* Ensure that resulting mask is zero or sign extended operand.  */
    && INTVAL (operands[4]) >= 0
    && ((INTVAL (operands[3]) > 0
        && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
        || (<MODE>mode == DImode
           && INTVAL (operands[3]) > 32
-          && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
+          && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
+   && ix86_match_ccmode (insn,
+                        /* *testdi_1 requires CCZmode if the mask has bit
+                           31 set and all bits above it clear.  */
+                        GET_MODE (operands[2]) == DImode
+                        && INTVAL (operands[3]) + INTVAL (operands[4]) == 32
+                        ? CCZmode : CCNOmode)"
   "#"
   "&& 1"
   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
index f91af78a302461df05c33e9b1675f8af2dc0c68e..5ed497dc44c2e2b0ec55a06bc8ed4a56f29fc42f 100644 (file)
@@ -1,3 +1,8 @@
+2020-03-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/94088
+       * gcc.target/i386/pr94088.c: New test.
+
 2020-03-09  Marek Polacek  <polacek@redhat.com>
 
        PR c++/92031 - bogus taking address of rvalue error.
diff --git a/gcc/testsuite/gcc.target/i386/pr94088.c b/gcc/testsuite/gcc.target/i386/pr94088.c
new file mode 100644 (file)
index 0000000..d8cdba5
--- /dev/null
@@ -0,0 +1,9 @@
+/* PR target/94088 */
+/* { dg-do compile } */
+/* { dg-options "-mtbm -O1 -fira-loop-pressure -fno-dce" } */
+
+double
+foo (int x)
+{
+  return x / (4294950402U % -65472 + 161);
+}