From 32ff70d299868259273da1199ff7025b3df8f9d1 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 2 Apr 2001 10:17:15 +0200 Subject: [PATCH] ifcvt.c (noce_emit_move_insn): New. * ifcvt.c (noce_emit_move_insn): New. (noce_try_store_flag, noce_try_store_flag_constants, noce_try_store_flag_inc, noce_try_store_flag_mask, noce_try_cmove, noce_try_cmove_arith, noce_try_minmax, noce_try_abs): Use it. (noce_process_if_block): Likewise. For STRICT_LOW_PART, take mode from its SUBREG. * gcc.c-torture/compile/20010329-1.c: New test. From-SVN: r41001 --- gcc/ChangeLog | 10 ++++ gcc/ifcvt.c | 52 +++++++++++++++---- gcc/testsuite/ChangeLog | 4 ++ .../gcc.c-torture/compile/20010329-1.c | 17 ++++++ 4 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/20010329-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 81bd6e7f63b..89fa7cdcd2d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2001-04-02 Jakub Jelinek + + * ifcvt.c (noce_emit_move_insn): New. + (noce_try_store_flag, noce_try_store_flag_constants, + noce_try_store_flag_inc, noce_try_store_flag_mask, + noce_try_cmove, noce_try_cmove_arith, noce_try_minmax, + noce_try_abs): Use it. + (noce_process_if_block): Likewise. + For STRICT_LOW_PART, take mode from its SUBREG. + 2001-04-02 Jakub Jelinek * fold-const.c (fold): Before optimizing unsigned comparison with diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 32971074939..f0df3da0371 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -96,6 +96,7 @@ static int find_if_case_2 PARAMS ((basic_block, edge, edge)); static int find_memory PARAMS ((rtx *, void *)); static int dead_or_predicable PARAMS ((basic_block, basic_block, basic_block, rtx, int)); +static void noce_emit_move_insn PARAMS ((rtx, rtx)); /* Abuse the basic_block AUX field to store the original block index, as well as a flag indicating that the block should be rescaned for @@ -537,6 +538,34 @@ noce_emit_store_flag (if_info, x, reversep, normalize) || code == GEU || code == GTU), normalize); } +/* Emit instruction to move a rtx into STRICT_LOW_PART. */ +static void +noce_emit_move_insn (x, y) + rtx x, y; +{ + enum machine_mode outmode, inmode; + rtx outer, inner; + int bitpos; + + if (GET_CODE (x) != STRICT_LOW_PART) + { + emit_move_insn (x, y); + return; + } + + outer = XEXP (x, 0); + inner = XEXP (outer, 0); + outmode = GET_MODE (outer); + inmode = GET_MODE (inner); + bitpos = SUBREG_WORD (outer) * BITS_PER_WORD; + if (BYTES_BIG_ENDIAN) + bitpos += (GET_MODE_BITSIZE (inmode) - GET_MODE_BITSIZE (outmode)) + % BITS_PER_WORD; + store_bit_field (inner, GET_MODE_BITSIZE (outmode), + bitpos, outmode, y, GET_MODE_BITSIZE (inmode), + GET_MODE_BITSIZE (inmode)); +} + /* Convert "if (test) x = 1; else x = 0". Only try 0 and STORE_FLAG_VALUE here. Other combinations will be @@ -569,7 +598,7 @@ noce_try_store_flag (if_info) if (target) { if (target != if_info->x) - emit_move_insn (if_info->x, target); + noce_emit_move_insn (if_info->x, target); seq = get_insns (); end_sequence (); @@ -692,7 +721,7 @@ noce_try_store_flag_constants (if_info) } if (target != if_info->x) - emit_move_insn (if_info->x, target); + noce_emit_move_insn (if_info->x, target); seq = get_insns (); end_sequence (); @@ -751,7 +780,7 @@ noce_try_store_flag_inc (if_info) if (target) { if (target != if_info->x) - emit_move_insn (if_info->x, target); + noce_emit_move_insn (if_info->x, target); seq = get_insns (); end_sequence (); @@ -803,7 +832,7 @@ noce_try_store_flag_mask (if_info) if (target) { if (target != if_info->x) - emit_move_insn (if_info->x, target); + noce_emit_move_insn (if_info->x, target); seq = get_insns (); end_sequence (); @@ -902,7 +931,7 @@ noce_try_cmove (if_info) if (target) { if (target != if_info->x) - emit_move_insn (if_info->x, target); + noce_emit_move_insn (if_info->x, target); seq = get_insns (); end_sequence (); @@ -1059,10 +1088,10 @@ noce_try_cmove_arith (if_info) if (MEM_ALIAS_SET (if_info->a) == MEM_ALIAS_SET (if_info->b)) MEM_ALIAS_SET (tmp) = MEM_ALIAS_SET (if_info->a); - emit_move_insn (if_info->x, tmp); + noce_emit_move_insn (if_info->x, tmp); } else if (target != x) - emit_move_insn (x, target); + noce_emit_move_insn (x, target); tmp = get_insns (); end_sequence (); @@ -1209,7 +1238,7 @@ noce_try_minmax (if_info) return FALSE; } if (target != if_info->x) - emit_move_insn (if_info->x, target); + noce_emit_move_insn (if_info->x, target); seq = get_insns (); end_sequence (); @@ -1327,7 +1356,7 @@ noce_try_abs (if_info) } if (target != if_info->x) - emit_move_insn (if_info->x, target); + noce_emit_move_insn (if_info->x, target); seq = get_insns (); end_sequence (); @@ -1532,7 +1561,8 @@ noce_process_if_block (test_bb, then_bb, else_bb, join_bb) { if (no_new_pseudos) return FALSE; - x = gen_reg_rtx (GET_MODE (x)); + x = gen_reg_rtx (GET_MODE (GET_CODE (x) == STRICT_LOW_PART + ? XEXP (x, 0) : x)); } /* Don't operate on sources that may trap or are volatile. */ @@ -1638,7 +1668,7 @@ noce_process_if_block (test_bb, then_bb, else_bb, join_bb) if (orig_x != x) { start_sequence (); - emit_move_insn (orig_x, x); + noce_emit_move_insn (orig_x, x); insn_b = gen_sequence (); end_sequence (); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 61ee72e23fb..8a7dcb60bbf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2001-04-02 Jakub Jelinek + + * gcc.c-torture/compile/20010329-1.c: New test. + 2001-04-02 Jakub Jelinek * gcc.c-torture/execute/20010329-1.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/compile/20010329-1.c b/gcc/testsuite/gcc.c-torture/compile/20010329-1.c new file mode 100644 index 00000000000..4d495e1afc8 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20010329-1.c @@ -0,0 +1,17 @@ +union u { + unsigned char a; + double b; +}; + +int a; + +union u foo (void) +{ + union u b; + + if (a) + b.a = 1; + else + b.a = 0; + return b; +} -- 2.30.2