This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug rtl-optimization/78952] New: Combine does not convert 8-bit sign-extract to a zero-extract for QImode operations
- From: "ubizjak at gmail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 29 Dec 2016 22:12:26 +0000
- Subject: [Bug rtl-optimization/78952] New: Combine does not convert 8-bit sign-extract to a zero-extract for QImode operations
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78952
Bug ID: 78952
Summary: Combine does not convert 8-bit sign-extract to a
zero-extract for QImode operations
Product: gcc
Version: 7.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: ---
Following testcase:
--cut here--
struct S1
{
char pad1;
char val;
short pad2;
};
struct S1 test_add (struct S1 a, struct S1 b)
{
a.val += b.val;
return a;
}
--cut here--
genereates unoptimal code on x86_64, since combine doesn't convert sign-extract
in
Trying 7, 9 -> 10:
Failed to match this instruction:
(set (zero_extract:SI (reg/v:SI 95 [ a ])
(const_int 8 [0x8])
(const_int 8 [0x8]))
(subreg:SI (plus:QI (subreg:QI (sign_extract:SI (reg/v:SI 95 [ a ])
(const_int 8 [0x8])
(const_int 8 [0x8])) 0)
(reg:QI 98)) 0))
to a zero-extract, as is the case in a similar testcase:
--cut here--
typedef __SIZE_TYPE__ size_t;
struct S1
{
char pad1;
char val;
short pad2;
};
extern char t[256];
void foo (struct S1 a, size_t i)
{
t[i] = a.val;
}
--cut here--
where:
(insn 8 4 9 2 (set (reg:SI 91)
(sign_extract:SI (reg/v:SI 88 [ a ])
(const_int 8 [0x8])
(const_int 8 [0x8]))) "pr78904-6.c":18 102 {*extvsi}
(expr_list:REG_DEAD (reg/v:SI 88 [ a ])
(nil)))
(insn 9 8 0 2 (set (mem/j:QI (plus:DI (reg/v:DI 89 [ i ])
(symbol_ref:DI ("t") [flags 0x40] <var_decl 0x7f9e35cd4e10
t>)) [0 t S1 A8])
(subreg:QI (reg:SI 91) 0)) "pr78904-6.c":18 84 {*movqi_internal}
(expr_list:REG_DEAD (reg:SI 91)
(expr_list:REG_DEAD (reg/v:DI 89 [ i ])
(nil))))
gets simplified to:
Trying 8 -> 9:
Successfully matched this instruction:
(set (mem/j:QI (plus:DI (reg/v:DI 89 [ i ])
(symbol_ref:DI ("t") [flags 0x40] <var_decl 0x7f9e35cd4e10 t>)) [0
t S1 A8])
(subreg:QI (zero_extract:SI (reg/v:SI 88 [ a ])
(const_int 8 [0x8])
(const_int 8 [0x8])) 0))
Please note that in both cases, we have QImode operation with 8-bit (QImode)
extracted value. Sign-extracts to a QImode value are nonsensical in both cases,
but only in the former case are converted to a zero-extract.