aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2017-10-22 18:05:17 +0000
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2017-10-22 18:05:17 +0000
commit7c43ee1e6714f697ce05a09784cd87a01eb02999 (patch)
tree28116b37107e98d67df1d6b2658b08b08dab6377
parente4d85e25e798a8c7d4c31a8931f97650215d341d (diff)
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@253985 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/config/i386/i386.c26
-rw-r--r--gcc/config/i386/i386.md22
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/i386/pr82628.c34
4 files changed, 70 insertions, 18 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index fb0b7e71469..5abd4d8ab25 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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);
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index fcb3edddf82..1fc4a38b82c 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -1273,6 +1273,26 @@
(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>")
@@ -6891,7 +6911,7 @@
(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")
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a69c8518c36..493b361c8bf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..d7135220485
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr82628.c
@@ -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;
+}