re PR rtl-optimization/82628 (wrong code at -Os on x86_64-linux-gnu in the 32-bit mode)

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
This commit is contained in:
Uros Bizjak 2017-10-22 20:05:17 +02:00 committed by Uros Bizjak
parent 00c378a954
commit 8cc857f949
4 changed files with 70 additions and 18 deletions

View 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;
cmp_insn = gen_cmpdi_doubleword;
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]);
if (!register_operand (op0, mode))
op0 = force_reg (mode, op0);
if (!x86_64_hilo_general_operand (op1, mode))
op1 = force_reg (mode, op1);
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]);
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);

View File

@ -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")

View 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.

View File

@ -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;
}