re PR rtl-optimization/82628 (wrong code at -Os on x86_64-linux-gnu in the 32-bit...
authorUros Bizjak <ubizjak@gmail.com>
Sun, 22 Oct 2017 18:05:17 +0000 (20:05 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Sun, 22 Oct 2017 18:05:17 +0000 (20:05 +0200)
PR target/82628
* config/i386/i386.md (cmp<dwi>_doubleword): New pattern.
* config/i386/i386.c (ix86_expand_branch) <case E_TImode>:
Expand with cmp<dwi>_doubleword.

testsuite/ChangeLog:

PR target/82628
* gcc.dg/torture/pr82628.c: New test.

Co-Authored-By: Jakub Jelinek <jakub@redhat.com>
From-SVN: r253985

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

index fb0b7e7..5abd4d8 100644 (file)
@@ -22357,33 +22357,25 @@ ix86_expand_branch (enum rtx_code code, rtx op0, rtx op1, rtx label)
        switch (code)
          {
          case LE: case LEU: case GT: case GTU:
-           std::swap (lo[0], lo[1]);
-           std::swap (hi[0], hi[1]);
+           std::swap (op0, op1);
            code = swap_condition (code);
            /* FALLTHRU */
 
          case LT: case LTU: case GE: case GEU:
            {
-             rtx (*cmp_insn) (rtx, rtx);
-             rtx (*sbb_insn) (rtx, rtx, rtx);
+             rtx (*cmp_insn) (rtx, rtx, rtx);
 
              if (TARGET_64BIT)
-               cmp_insn = gen_cmpdi_1, sbb_insn = gen_subdi3_carry_ccgz;
+               cmp_insn = gen_cmpti_doubleword;
              else
-               cmp_insn = gen_cmpsi_1, sbb_insn = gen_subsi3_carry_ccgz;
-
-             if (!nonimmediate_operand (lo[0], submode))
-               lo[0] = force_reg (submode, lo[0]);
-             if (!x86_64_general_operand (lo[1], submode))
-               lo[1] = force_reg (submode, lo[1]);
+               cmp_insn = gen_cmpdi_doubleword;
 
-             if (!register_operand (hi[0], submode))
-               hi[0] = force_reg (submode, hi[0]);
-             if (!x86_64_general_operand (hi[1], submode))
-               hi[1] = force_reg (submode, hi[1]);
+             if (!register_operand (op0, mode))
+               op0 = force_reg (mode, op0);
+             if (!x86_64_hilo_general_operand (op1, mode))
+               op1 = force_reg (mode, op1);
 
-             emit_insn (cmp_insn (lo[0], lo[1]));
-             emit_insn (sbb_insn (gen_rtx_SCRATCH (submode), hi[0], hi[1]));
+             emit_insn (cmp_insn (gen_rtx_SCRATCH (mode), op0, op1));
 
              tmp = gen_rtx_REG (CCGZmode, FLAGS_REG);
 
index fcb3edd..1fc4a38 100644 (file)
        (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
                    (match_operand:SWI48 1 "<general_operand>")))])
 
+(define_insn_and_split "cmp<dwi>_doubleword"
+  [(set (reg:CCGZ FLAGS_REG)
+       (compare:CCGZ
+         (match_operand:<DWI> 1 "register_operand" "0")
+         (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "ro<di>")))
+   (clobber (match_scratch:<DWI> 0 "=r"))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (reg:CC FLAGS_REG)
+       (compare:CC (match_dup 1) (match_dup 2)))
+   (parallel [(set (reg:CCGZ FLAGS_REG)
+                  (compare: CCGZ
+                    (match_dup 4)
+                    (plus:DWIH
+                      (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
+                      (match_dup 5))))
+             (clobber (match_dup 3))])]
+  "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
+
 (define_insn "*cmp<mode>_ccno_1"
   [(set (reg FLAGS_REG)
        (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "SI")])
 
-(define_insn "sub<mode>3_carry_ccgz"
+(define_insn "*sub<mode>3_carry_ccgz"
   [(set (reg:CCGZ FLAGS_REG)
        (compare:CCGZ
          (match_operand:DWIH 1 "register_operand" "0")
index a69c851..493b361 100644 (file)
@@ -1,3 +1,9 @@
+2017-10-22  Uros Bizjak  <ubizjak@gmail.com>
+           Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/82628
+       * gcc.dg/torture/pr82628.c: New test.
+
 2017-10-22  Igor Tsimbalist  <igor.v.tsimbalist@intel.com>
 
        * c-c++-common/attr-nocf-check-1a.c: Remove test.
diff --git a/gcc/testsuite/gcc.target/i386/pr82628.c b/gcc/testsuite/gcc.target/i386/pr82628.c
new file mode 100644 (file)
index 0000000..d713522
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do run { target ia32 } } */
+/* { dg-options "-Os" } */
+
+void
+__attribute__ ((noipa))
+foo (const char *x)
+{
+  asm volatile ("" : "+g" (x) : : "memory");
+  if (x)
+    __builtin_abort ();
+}
+
+int a, b = 1;
+
+int
+main ()
+{
+  while (1)
+    {
+      unsigned long long d = 18446744073709551615UL;
+      while (1)
+       {
+         int e = b;
+         while (d < 2)
+           foo ("0");
+         if (a)
+           d++;
+         if (b)
+           break;
+       }
+      break;
+    }
+  return 0;
+}