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.