https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82089
Bug ID: 82089 Summary: emit_cstore sign-extends BImode result for STORE_FLAG_VALUE == 1 Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: vries at gcc dot gnu.org Target Milestone: --- Say that in bfin.md, we redefine cstoresi4 in the following way: ... (define_expand "cstoresi4" [(set (match_operand:BI 0 "") (match_operator:BI 1 "ordered_comparison_operator" [(match_operand:SI 2 "register_operand" "") (match_operand:SI 3 "reg_or_const_int_operand" "")]))] "" {}) ... Then for a test-case: ... int foo (int a, int b) { return a == b; } ... compiled like this: ... $ gcc test.c -S -O2 -fdump-rtl-all-all ... we expand into this: ... (insn 7 6 8 (set (reg:BI 62) (ne:BI (reg/v:SI 58 [ aD.1438 ]) (reg/v:SI 59 [ bD.1439 ]))) "test.c":4 -1 (nil)) (insn 8 7 9 (set (reg:SI 61) (ashift:SI (subreg:SI (reg:BI 62) 0) (const_int 31 [0x1f]))) "test.c":4 -1 (nil)) (insn 9 8 10 (set (reg:SI 61) (ashiftrt:SI (reg:SI 61) (const_int 31 [0x1f]))) "test.c":4 -1 (nil)) (insn 10 9 11 (set (reg:SI 57 [ <retval> ]) (reg:SI 61)) "test.c":4 -1 (nil)) ... before ICE-ing in vregs because insn 7 does not match any insn. Note that we sign-extend the BImode result of insn 7, using insn 8 and 9. The sign-extend is generated here in emit_cstore: ... /* If we are converting to a wider mode, first convert to INT_TARGET_MODE, then normalize. This produces better combining opportunities on machines that have a SIGN_EXTRACT when we are testing a single bit. This mostly benefits the 68k. If STORE_FLAG_VALUE does not have the sign bit set when interpreted in MODE, we can do this conversion as unsigned, which is usually more efficient. */ if (GET_MODE_SIZE (int_target_mode) > GET_MODE_SIZE (result_mode)) { convert_move (target, subtarget, val_signbit_known_clear_p (result_mode, STORE_FLAG_VALUE)); op0 = target; result_mode = int_target_mode; } ... We call val_signbit_known_clear_p (mode == BImode, val == 1) which returns false, so then we call convert_move (to == reg:SI 61, from == reg:BI 62, unsignedp == false) which generates the sign-extend because unsignedp == false. Disregarding other STORE_FLAG_VALUES for the moment, the idea of the code is to sign-extend if STORE_FLAG_VALUE is -1, and to zero-extend if STORE_FLAG_VALUE is 1. However, 1 and -1 are indistinguishable in BImode, so this happens to go the sign-extend way. [ The comment mentions 68k, which has STORE_FLAG_VALUE -1, so that might be reason it choose the sign-extend in this case. ]