public inbox for gcc-bugs@sourceware.org help / color / mirror / Atom feed
* [Bug target/59533] New: [SH] Missed cmp/pz opportunity @ 2013-12-16 21:59 olegendo at gcc dot gnu.org 2013-12-17 0:32 ` [Bug target/59533] " olegendo at gcc dot gnu.org ` (6 more replies) 0 siblings, 7 replies; 8+ messages in thread From: olegendo at gcc dot gnu.org @ 2013-12-16 21:59 UTC (permalink / raw) To: gcc-bugs http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59533 Bug ID: 59533 Summary: [SH] Missed cmp/pz opportunity Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: olegendo at gcc dot gnu.org Target: sh*-*-* In some cases RTL such as (insn 7 6 8 2 (set (reg:SI 169) (not:SI (reg:SI 168))) sh_tmp.cpp:31 -1 (nil)) (insn 8 7 9 2 (parallel [ (set (reg:SI 167 [ D.1462+-3 ]) (lshiftrt:SI (reg:SI 169) (const_int 31 [0x1f]))) (clobber (reg:SI 147 t)) ]) sh_tmp.cpp:31 -1 (nil)) is expanded to refer to the MSB of a word. In most cases combine can catch such a sequence and generate a cmp/pz insn (set (reg:SI T_REG) (ge:SI (...) (const_int 0))). However, in cases where the extracted MSB is not stored in the T bit, it fails to do so. Here are a few test functions, compiled with -O2 -m4: int test0_OK (unsigned char* a) { return a[0] < 128; /* mov.b @r4,r1 cmp/pz r1 rts movt r0 */ } int test1_NG (unsigned char* a, unsigned char* b) { return a[0] + (a[0] < 128); /* mov.b @r4,r1 extu.b r1,r0 exts.b r1,r1 // the redundant sign extension is another issue not r1,r1 shll r1 // could use 'cmp/pz r1' here. mov #0,r1 rts addc r1,r0 */ } int test2_NG (unsigned char* a, unsigned char* b) { return a[0] + ((a[0] & 0x80) == 0); /* mov.b @r4,r1 extu.b r1,r0 exts.b r1,r1 // the redundant sign extension is another issue not r1,r1 shll r1 // could use 'cmp/pz r1' here. mov #0,r1 rts addc r1,r0 */ } int test3_OK (unsigned char* a, unsigned char* b) { return a[0] + (a[0] > 127); /* mov.b @r4,r1 extu.b r1,r0 exts.b r1,r1 shll r1 mov #0,r1 rts addc r1,r0 */ } int test4_OK (unsigned char* a, unsigned char* b) { return a[0] + ((a[0] & 0x80) != 0); /* mov.b @r4,r1 extu.b r1,r0 exts.b r1,r1 shll r1 mov #0,r1 rts addc r1,r0 */ } int test5_OK (unsigned char* a, int b, int c) { if (a[0] < 128) return c; else return b + 50; /* mov.b @r4,r1 cmp/pz r1 bt .L9 mov r5,r6 add #50,r6 .L9: rts mov r6,r0 */ } unsigned int test6_OK (unsigned int a) { return ~a >> 31; /* cmp/pz r4 rts movt r0 */ } The following patch fixes the issue: Index: gcc/config/sh/sh.md =================================================================== --- gcc/config/sh/sh.md (revision 205971) +++ gcc/config/sh/sh.md (working copy) @@ -4707,13 +4707,28 @@ DONE; }) -(define_insn "shll" +(define_insn_and_split "shll" [(set (match_operand:SI 0 "arith_reg_dest" "=r") (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1))) (set (reg:SI T_REG) (lt:SI (match_dup 1) (const_int 0)))] "TARGET_SH1" "shll %0" + "&& can_create_pseudo_p ()" + [(set (reg:SI T_REG) (ge:SI (match_dup 2) (const_int 0))) + (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 1)))] +{ + rtx i = curr_insn; + rtx s = find_last_value (operands[1], &i, curr_insn, true); + + if (s == operands[1] || i == curr_insn) + FAIL; + + if (GET_CODE (s) == NOT && REG_P (XEXP (s, 0))) + operands[2] = XEXP (s, 0); + else + FAIL; +} [(set_attr "type" "arith")]) (define_insn "*ashlsi_c_void" ^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug target/59533] [SH] Missed cmp/pz opportunity 2013-12-16 21:59 [Bug target/59533] New: [SH] Missed cmp/pz opportunity olegendo at gcc dot gnu.org @ 2013-12-17 0:32 ` olegendo at gcc dot gnu.org 2013-12-17 1:43 ` olegendo at gcc dot gnu.org ` (5 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: olegendo at gcc dot gnu.org @ 2013-12-17 0:32 UTC (permalink / raw) To: gcc-bugs http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59533 --- Comment #1 from Oleg Endo <olegendo at gcc dot gnu.org> --- The shll trick above will not work properly in the following case: int test_00 (unsigned char* a, int b) { return a[0] - (a[0] < 128); } results in: mov.b @r4,r1 extu.b r1,r0 exts.b r1,r1 cmp/pz r1 movt r1 rts sub r1,r0 It is initially expanded as (insn 10 9 11 2 (set (reg:SI 173) (not:SI (reg:SI 172))) sh_tmp.cpp:188 -1 (nil)) (insn 11 10 12 2 (parallel [ (set (reg:SI 171 [ D.1381+-3 ]) (lshiftrt:SI (reg:SI 173) (const_int 31 [0x1f]))) (clobber (reg:SI 147 t)) ]) sh_tmp.cpp:188 -1 (nil)) (insn 12 11 13 2 (set (reg:SI 170 [ D.1379 ]) (minus:SI (reg:SI 160 [ D.1378+-3 ]) (reg:SI 171 [ D.1381+-3 ]))) sh_tmp.cpp:188 -1 (nil)) and then combine will not try to integrate the not insn and only try: Failed to match this instruction: (set (reg:SI 170 [ D.1379 ]) (minus:SI (zero_extend:SI (reg:QI 169 [ *a_2(D) ])) (lshiftrt:SI (reg:SI 173) (const_int 31 [0x1f])))) The cmp/pz insn will be split out after combine and thus it will not be combined into a subc insn. One problem is that the function emit_store_flag_1 in expmed.c always expands the not-shift because the assumption there is that it's cheaper. This is not true for SH and ideally it should check insn costs during expansion. On the other hand, there are other cases such as unsigned int test_00 (unsigned int a) { return (a >> 31) ^ 1; } which currently results in: shll r4 movt r0 rts xor #1,r0 and can be done simpler as: cmp/pz r4 rts movt r0 In this case combine will try to merge the shift and the xor into: Failed to match this instruction: (set (reg:SI 164 [ D.1394 ]) (ge:SI (reg:SI 4 r4 [ a ]) (const_int 0 [0]))) Adding such a pattern will also result in cmp/pz being used for all the other cases above (without the shll trick), but it will fail to combine with any other insn that takes the result as an operand in the T_REG, such as addc, subc or rotcl/rotcr. In order to get that working all the insns that can take T_REG as an operand would require insn_and_split variants to include (ge:SI (reg:SI (const_int 0)), which will be quite a lot of patterns. Maybe it would be better to do a kind of SH specific like RTL pass that performs insn pre-combination before the generic combine pass and catches such special cases. It could also probably be used to address issues mentioned in PR 59291. Alternatively the combine pass could be ran twice on SH, although it seems to cause some problems. If it worked, I'm afraid it would probably have a negative impact on compilation time ^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug target/59533] [SH] Missed cmp/pz opportunity 2013-12-16 21:59 [Bug target/59533] New: [SH] Missed cmp/pz opportunity olegendo at gcc dot gnu.org 2013-12-17 0:32 ` [Bug target/59533] " olegendo at gcc dot gnu.org @ 2013-12-17 1:43 ` olegendo at gcc dot gnu.org 2013-12-17 21:07 ` olegendo at gcc dot gnu.org ` (4 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: olegendo at gcc dot gnu.org @ 2013-12-17 1:43 UTC (permalink / raw) To: gcc-bugs http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59533 --- Comment #2 from Oleg Endo <olegendo at gcc dot gnu.org> --- I have quickly tried adding a peephole pass shortly after initial RTL expansion: Index: gcc/config/sh/sh.c =================================================================== --- gcc/config/sh/sh.c (revision 205971) +++ gcc/config/sh/sh.c (working copy) @@ -735,6 +735,10 @@ if (!TARGET_SH1) return; + opt_pass* pre_combine = make_pass_peephole2 (g); + pre_combine->name = "pre_peephole"; + register_pass (pre_combine, PASS_POS_INSERT_AFTER, "dfinit", 1); + /* Running the sh_treg_combine pass after ce1 generates better code when comparisons are combined and reg-reg moves are introduced, because reg-reg moves will be eliminated afterwards. However, there are quite and adding the following peepholes (the existing define_peephole2 patterns need a && reload_completed condition) Index: gcc/config/sh/sh.md =================================================================== --- gcc/config/sh/sh.md (revision 205971) +++ gcc/config/sh/sh.md (working copy) @@ -821,6 +821,29 @@ cmp/ge %1,%0" [(set_attr "type" "mt_group")]) +;; This peephole will be done after RTL expansion before combine. +(define_peephole2 + [(parallel [(set (match_operand:SI 0 "arith_reg_dest") + (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand") + (const_int 31))) + (clobber (reg:SI T_REG))]) + (set (match_operand:SI 2 "arith_reg_dest") + (xor:SI (match_dup 0) (const_int 1)))] + "TARGET_SH1 && can_create_pseudo_p ()" + [(set (reg:SI T_REG) (ge:SI (match_dup 1) (const_int 0))) + (set (match_dup 2) (reg:SI T_REG))]) + +(define_peephole2 + [(set (match_operand:SI 0 "arith_reg_dest") + (not:SI (match_operand:SI 1 "arith_reg_operand"))) + (parallel [(set (match_operand:SI 2 "arith_reg_dest") + (lshiftrt:SI (match_dup 0) (const_int 31))) + (clobber (reg:SI T_REG))])] + "TARGET_SH1 && can_create_pseudo_p ()" + [(set (reg:SI T_REG) (ge:SI (match_dup 1) (const_int 0))) + (set (match_dup 2) (reg:SI T_REG)) + (set (match_dup 0) (not:SI (match_dup 1)))]) + This allows generating the cmp/pz insn before combine and thus it will be able to combine it with other insns that use T_REG as an operand: unsigned int test_011 (unsigned int a, unsigned int b) { return (a << 1) | ((a >> 31) ^ 1); } will compile to: cmp/pz r4 mov r4,r0 rts rotcl r0 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug target/59533] [SH] Missed cmp/pz opportunity 2013-12-16 21:59 [Bug target/59533] New: [SH] Missed cmp/pz opportunity olegendo at gcc dot gnu.org 2013-12-17 0:32 ` [Bug target/59533] " olegendo at gcc dot gnu.org 2013-12-17 1:43 ` olegendo at gcc dot gnu.org @ 2013-12-17 21:07 ` olegendo at gcc dot gnu.org 2015-01-24 13:05 ` olegendo at gcc dot gnu.org ` (3 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: olegendo at gcc dot gnu.org @ 2013-12-17 21:07 UTC (permalink / raw) To: gcc-bugs http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59533 --- Comment #3 from Oleg Endo <olegendo at gcc dot gnu.org> --- This is basically the same issue as PR 54685. ^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug target/59533] [SH] Missed cmp/pz opportunity 2013-12-16 21:59 [Bug target/59533] New: [SH] Missed cmp/pz opportunity olegendo at gcc dot gnu.org ` (2 preceding siblings ...) 2013-12-17 21:07 ` olegendo at gcc dot gnu.org @ 2015-01-24 13:05 ` olegendo at gcc dot gnu.org 2015-01-25 17:08 ` olegendo at gcc dot gnu.org ` (2 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: olegendo at gcc dot gnu.org @ 2015-01-24 13:05 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59533 --- Comment #4 from Oleg Endo <olegendo at gcc dot gnu.org> --- Author: olegendo Date: Sat Jan 24 13:04:53 2015 New Revision: 220081 URL: https://gcc.gnu.org/viewcvs?rev=220081&root=gcc&view=rev Log: gcc/ PR target/49263 PR target/53987 PR target/64345 PR target/59533 PR target/52933 PR target/54236 PR target/51244 * config/sh/sh-protos.h (sh_extending_set_of_reg::can_use_as_unextended_reg, sh_extending_set_of_reg::use_as_unextended_reg, sh_is_nott_insn, sh_movt_set_dest, sh_movrt_set_dest, sh_is_movt_insn, sh_is_movrt_insn, sh_insn_operands_modified_between_p, sh_reg_dead_or_unused_after_insn, sh_in_recog_treg_set_expr, sh_recog_treg_set_expr, sh_split_treg_set_expr): New functions. (sh_treg_insns): New class. * config/sh/sh.c (TARGET_LEGITIMATE_COMBINED_INSN): Define target hook. (scope_counter): New class. (sh_legitimate_combined_insn, sh_is_nott_insn, sh_movt_set_dest, sh_movrt_set_dest, sh_reg_dead_or_unused_after_insn, sh_extending_set_of_reg::can_use_as_unextended_reg, sh_extending_set_of_reg::use_as_unextended_reg, sh_recog_treg_set_expr, sh_in_recog_treg_set_expr, sh_try_split_insn_simple, sh_split_treg_set_expr): New functions. (addsubcosts): Handle treg_set_expr. (sh_rtx_costs): Handle IF_THEN_ELSE and ZERO_EXTRACT. (sh_rtx_costs): Use arith_reg_operand in SIGN_EXTEND and ZERO_EXTEND. (sh_rtx_costs): Handle additional bit test patterns in EQ and AND cases. (sh_insn_operands_modified_between_p): Make non-static. * config/sh/predicates.md (zero_extend_movu_operand): Allow simple_mem_operand in addition to displacement_mem_operand. (zero_extend_operand): Don't allow zero_extend_movu_operand. (treg_set_expr, treg_set_expr_not_const01, arith_reg_or_treg_set_expr): New predicates. * config/sh/sh.md (tstsi_t): Use arith_reg_operand and arith_or_int_operand instead of logical_operand. Convert to insn_and_split. Try to optimize constant operand in splitter. (tsthi_t, tstqi_t): Fold into *tst<mode>_t. Convert to insn_and_split. (*tstqi_t_zero): Delete. (*tst<mode>_t_subregs): Add !sh_in_recog_treg_set_expr split condition. (tstsi_t_and_not): Delete. (tst<mode>_t_zero_extract_eq): Rename to *tst<mode>_t_zero_extract. Convert to insn_and_split. (unnamed split, tstsi_t_zero_extract_xor, tstsi_t_zero_extract_subreg_xor_little, tstsi_t_zero_extract_subreg_xor_big): Delete. (*tstsi_t_shift_mask): New insn_and_split. (cmpeqsi_t, cmpgesi_t): Add new split for const_int 0 operands and try to recombine with surrounding insns when splitting. (*negtstsi): Add !sh_in_recog_treg_set_expr condition. (cmp_div0s_0, cmp_div0s_1, *cmp_div0s_0, *cmp_div0s_1): Rewrite as ... (cmp_div0s, *cmp_div0s_1, *cmp_div0s_2, *cmp_div0s_3, *cmp_div0s_4, *cmp_div0s_5, *cmp_div0s_6): ... these new insn_and_split patterns. (*cbranch_div0s: Delete. (*addc): Convert to insn_and_split. Use treg_set_expr as 3rd operand. Try to recombine with surrounding insns when splitting. Add operand order variants. (*addc_t_r, *addc_r_t): Use treg_set_expr_not_const01. (*addc_r_r_1, *addc_r_lsb, *addc_r_r_lsb, *addc_r_lsb_r, *addc_r_msb, *addc_r_r_msb, *addc_2r_msb): Delete. (*addc_2r_lsb): Rename to *addc_2r_t. Use treg_set_expr. Add operand order variant. (*addc_negreg_t): New insn_and_split. (*subc): Convert to insn_and_split. Use treg_set_expr as 3rd operand. Try to recombine with surrounding insns when splitting. Add operand order variants. (*subc_negt_reg, *subc_negreg_t, *reg_lsb_t, *reg_msb_t): New insn_and_split patterns. (*rotcr): Use arith_reg_or_treg_set_expr. Try to recombine with surrounding insns when splitting. (unnamed rotcr split): Use arith_reg_or_treg_set_expr. (*rotcl): Likewise. Add zero_extract variant. (*ashrsi2_31): New insn_and_split. (*negc): Convert to insn_and_split. Use treg_set_expr. (*zero_extend<mode>si2_disp_mem): Update comment. (movrt_negc, *movrt_negc, nott): Add !sh_in_recog_treg_set_expr split condition. (*mov_t_msb_neg, mov_neg_si_t): Use treg_set_expr. Try to recombine with surrounding insns when splitting. (any_treg_expr_to_reg): New insn_and_split. (*neg_zero_extract_0, *neg_zero_extract_1, *neg_zero_extract_2, *neg_zero_extract_3, *neg_zero_extract_4, *neg_zero_extract_5, *neg_zero_extract_6, *zero_extract_0, *zero_extract_1, *zero_extract_2): New single bit zero extract patterns. (bld_reg, *bld_regqi): Fold into bld<mode>_reg. (*get_thread_pointersi, store_gbr, *mov<mode>_gbr_load, *mov<mode>_gbr_load, *mov<mode>_gbr_load, *mov<mode>_gbr_load, *movdi_gbr_load): Use arith_reg_dest instead of register_operand for set destination. (set_thread_pointersi, load_gbr): Use arith_reg_operand instead of register_operand for set source. gcc/testsuite/ PR target/49263 PR target/53987 PR target/64345 PR target/59533 PR target/52933 PR target/54236 PR target/51244 * gcc.target/sh/pr64345-1.c: New. * gcc.target/sh/pr64345-2.c: New. * gcc.target/sh/pr59533-1.c: New. * gcc.target/sh/pr49263.c: Adjust matching of expected insns. * gcc.target/sh/pr52933-2.c: Likewise. * gcc.target/sh/pr54089-1.c: Likewise. * gcc.target/sh/pr54236-1.c: Likewise. * gcc.target/sh/pr51244-20-sh2a.c: Likewise. * gcc.target/sh/pr49263-1.c: Remove xfails. * gcc.target/sh/pr49263-2.c: Likewise. * gcc.target/sh/pr49263-3.c: Likewise. * gcc.target/sh/pr53987-1.c: Likewise. * gcc.target/sh/pr52933-1.c: Adjust matching of expected insns. (test_24, test_25, test_26, test_27, test_28, test_29, test_30): New. * gcc.target/sh/pr51244-12.c: Adjust matching of expected insns. (test05, test06, test07, test08, test09, test10, test11, test12): New. * gcc.target/sh/pr54236-3.c: Adjust matching of expected insns. (test_002, test_003, test_004, test_005, test_006, test_007, test_008, test_009): New. * gcc.target/sh/pr51244-4.c: Adjust matching of expected insns. (test_02): New. Added: trunk/gcc/testsuite/gcc.target/sh/pr59533-1.c trunk/gcc/testsuite/gcc.target/sh/pr64345-1.c trunk/gcc/testsuite/gcc.target/sh/pr64345-2.c Modified: trunk/gcc/ChangeLog trunk/gcc/config/sh/predicates.md trunk/gcc/config/sh/sh-protos.h trunk/gcc/config/sh/sh.c trunk/gcc/config/sh/sh.md trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gcc.target/sh/pr49263-1.c trunk/gcc/testsuite/gcc.target/sh/pr49263-2.c trunk/gcc/testsuite/gcc.target/sh/pr49263-3.c trunk/gcc/testsuite/gcc.target/sh/pr49263.c trunk/gcc/testsuite/gcc.target/sh/pr51244-12.c trunk/gcc/testsuite/gcc.target/sh/pr51244-20-sh2a.c trunk/gcc/testsuite/gcc.target/sh/pr51244-4.c trunk/gcc/testsuite/gcc.target/sh/pr52933-1.c trunk/gcc/testsuite/gcc.target/sh/pr52933-2.c trunk/gcc/testsuite/gcc.target/sh/pr53987-1.c trunk/gcc/testsuite/gcc.target/sh/pr54089-1.c trunk/gcc/testsuite/gcc.target/sh/pr54236-1.c trunk/gcc/testsuite/gcc.target/sh/pr54236-3.c ^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug target/59533] [SH] Missed cmp/pz opportunity 2013-12-16 21:59 [Bug target/59533] New: [SH] Missed cmp/pz opportunity olegendo at gcc dot gnu.org ` (3 preceding siblings ...) 2015-01-24 13:05 ` olegendo at gcc dot gnu.org @ 2015-01-25 17:08 ` olegendo at gcc dot gnu.org 2015-01-25 17:25 ` olegendo at gcc dot gnu.org 2015-01-25 17:42 ` olegendo at gcc dot gnu.org 6 siblings, 0 replies; 8+ messages in thread From: olegendo at gcc dot gnu.org @ 2015-01-25 17:08 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59533 --- Comment #5 from Oleg Endo <olegendo at gcc dot gnu.org> --- The issues mentioned above have been fixed by the treg_set_expr patch (r220081). There is one more thing, though: int test2 (int x) { return x < 0; } It's effectively a lshiftrt 31 and compiles to: shll r4 rts movt r0 On SH2A the same can be done as: cmp/pz r4 rts movrt r0 which avoids mutating the input operand of the comparison. On non-SH2A this would end up as: cmp/pz r4 mov #-1,r0 rts negc r0,r0 which could be better than shll-movt in cases where the input operand is not dead after the insn and even better if the -1 constant can be shared. ^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug target/59533] [SH] Missed cmp/pz opportunity 2013-12-16 21:59 [Bug target/59533] New: [SH] Missed cmp/pz opportunity olegendo at gcc dot gnu.org ` (4 preceding siblings ...) 2015-01-25 17:08 ` olegendo at gcc dot gnu.org @ 2015-01-25 17:25 ` olegendo at gcc dot gnu.org 2015-01-25 17:42 ` olegendo at gcc dot gnu.org 6 siblings, 0 replies; 8+ messages in thread From: olegendo at gcc dot gnu.org @ 2015-01-25 17:25 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59533 --- Comment #6 from Oleg Endo <olegendo at gcc dot gnu.org> --- (In reply to Oleg Endo from comment #5) The same would apply to: int test (unsigned char* x, int y, int z) { return ((*x >> 7) ^ 0) & 1; } which compiles to mov.b @r4,r1 shll r1 rts movt r0 on non-SH2A. The insn selection goes like this: zero_extract -> tstsi_t -> cmp/pz -> shll-movt ^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug target/59533] [SH] Missed cmp/pz opportunity 2013-12-16 21:59 [Bug target/59533] New: [SH] Missed cmp/pz opportunity olegendo at gcc dot gnu.org ` (5 preceding siblings ...) 2015-01-25 17:25 ` olegendo at gcc dot gnu.org @ 2015-01-25 17:42 ` olegendo at gcc dot gnu.org 6 siblings, 0 replies; 8+ messages in thread From: olegendo at gcc dot gnu.org @ 2015-01-25 17:42 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59533 --- Comment #7 from Oleg Endo <olegendo at gcc dot gnu.org> --- If a shll is followed by a cbranch: unsigned int test_09_0 (int x, unsigned int y, unsigned int z) { return ~(x >> 31) ? y : z; } shll r4 bf .L4 mov r6,r5 .L4: rts mov r5,r0 it's better to use cmp/pz and invert the branch condition. Combine is looking for the following pattern: Failed to match this instruction: (set (pc) (if_then_else (ge (reg:SI 4 r4 [ x ]) (const_int 0 [0])) (label_ref:SI 17) (pc))) One option could be adding a pattern like: (define_insn_and_split "*cbranch" [(set (pc) (if_then_else (match_operand 0 "treg_set_expr") (label_ref (match_operand 1)) (pc))) (clobber (reg:SI T_REG))] ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2015-01-25 17:42 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2013-12-16 21:59 [Bug target/59533] New: [SH] Missed cmp/pz opportunity olegendo at gcc dot gnu.org 2013-12-17 0:32 ` [Bug target/59533] " olegendo at gcc dot gnu.org 2013-12-17 1:43 ` olegendo at gcc dot gnu.org 2013-12-17 21:07 ` olegendo at gcc dot gnu.org 2015-01-24 13:05 ` olegendo at gcc dot gnu.org 2015-01-25 17:08 ` olegendo at gcc dot gnu.org 2015-01-25 17:25 ` olegendo at gcc dot gnu.org 2015-01-25 17:42 ` olegendo at gcc dot gnu.org
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).