[Bug rtl-optimization/67382] New: RTL combiner is too eager to combine (plus (reg 92) (reg 92)) to (ashift (reg 92) (const_int 1))
ubizjak at gmail dot com
gcc-bugzilla@gcc.gnu.org
Fri Aug 28 12:27:00 GMT 2015
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67382
Bug ID: 67382
Summary: RTL combiner is too eager to combine (plus (reg 92)
(reg 92)) to (ashift (reg 92) (const_int 1))
Product: gcc
Version: 6.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: ubizjak at gmail dot com
Target Milestone: ---
Target: x86_64
Following testcase:
--cut here--
extern void abort (void);
void test (void)
{
unsigned char c = 0;
unsigned int x = 0xFFFFFFFF;
unsigned int y = 0xFFFFFFFF;
unsigned int sum_ref = 0xFFFFFFFE;
/* X = 0xFFFFFFFF, Y = 0xFFFFFFFF, C = 0. */
c = __builtin_ia32_addcarryx_u32 (c, x, y, &x);
/* X = 0xFFFFFFFE, Y = 0xFFFFFFFF, C = 1. */
c = __builtin_ia32_addcarryx_u32 (c, x, y, &x);
/* X = 0xFFFFFFFE, Y = 0xFFFFFFFF, C = 1. */
if (x != sum_ref)
abort ();
}
--cut here--
compiles to unoptimized code on x86_64-linux-gnu with -O2:
movl $-1, %edx
movl $-4, %eax
subq $24, %rsp
addl %edx, %eax
adcl %edx, %eax
cmpl $-2, %eax
movl %eax, 12(%rsp)
jne .L5
addq $24, %rsp
ret
.L5:
call abort
The problem is with combine pass, which tries to combine:
(insn 10 7 11 2 (parallel [
(set (reg:CCC 17 flags)
(compare:CCC (plus:QI (reg:QI 91)
(const_int -1 [0xffffffffffffffff]))
(reg:QI 91)))
(clobber (scratch:QI))
]) carry.c:11 292 {*addqi3_cconly_overflow}
(expr_list:REG_DEAD (reg:QI 91)
(expr_list:REG_EQUAL (compare:CCC (const_int -1 [0xffffffffffffffff])
(const_int 0 [0]))
(nil))))
(insn 11 10 12 2 (parallel [
(set (reg:CCC 17 flags)
(compare:CCC (plus:SI (plus:SI (ltu:SI (reg:CCC 17 flags)
(const_int 0 [0]))
(reg:SI 92))
(reg:SI 92))
(reg:SI 92)))
(set (reg:SI 95)
(plus:SI (plus:SI (ltu:SI (reg:CCC 17 flags)
(const_int 0 [0]))
(reg:SI 92))
(reg:SI 92)))
]) carry.c:11 283 {addcarrysi}
(nil))
to:
Trying 10 -> 11:
Failed to match this instruction:
(parallel [
(set (reg:CC 17 flags)
(compare:CC (ashift:SI (reg:SI 92)
(const_int 1 [0x1]))
(reg:SI 92)))
(set (reg:SI 95)
(ashift:SI (reg:SI 92)
(const_int 1 [0x1])))
])
Failed to match this instruction:
(parallel [
(set (reg:CC 17 flags)
(compare:CC (ashift:SI (reg:SI 92)
(const_int 1 [0x1]))
(reg:SI 92)))
(set (reg:SI 95)
(ashift:SI (reg:SI 92)
(const_int 1 [0x1])))
])
Please note that combine pass converts
(plus (reg 92) (reg 92))
to
(ashift (reg 92) (const_int 1)
and combined pattern fails.
BTW: The duplicate pattern is copied verbatim from the dump. It looks like
combine is trying to do something with unrecognized pattern to re-recognize it.
When we change e.g.:
unsigned int x = 0xFFFFFFFF;
to
unsigned int x = 0xFFFFFFFC;
we get the expected pattern:
Trying 10 -> 11:
Successfully matched this instruction:
(parallel [
(set (reg:CCC 17 flags)
(compare:CCC (plus:SI (reg:SI 92)
(reg:SI 93))
(reg:SI 92)))
(set (reg:SI 95)
(plus:SI (reg:SI 92)
(reg:SI 93)))
])
More information about the Gcc-bugs
mailing list