diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-10-15 18:46:02 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-10-15 18:46:02 +0000 |
commit | e16e12bfb75dede27f339b1646abd19c6a66aa19 (patch) | |
tree | 6d8669aea59b7a3885fe9277ffce84a5f64aa031 /gcc/optabs.c | |
parent | f2540a7efd1bdbe34a762ebc27016c159898e382 (diff) |
* optabs.c (expand_parity): Fix mode mismatch, add final conversion
and keep looping on failure.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@241202 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r-- | gcc/optabs.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c index c5e9b4f8e13..f78d9989f05 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -2382,18 +2382,26 @@ expand_parity (machine_mode mode, rtx op0, rtx target) last = get_last_insn (); - if (target == 0) - target = gen_reg_rtx (mode); + if (target == 0 || GET_MODE (target) != wider_mode) + target = gen_reg_rtx (wider_mode); + xop0 = widen_operand (op0, wider_mode, mode, true, false); temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX, true); if (temp != 0) temp = expand_binop (wider_mode, and_optab, temp, const1_rtx, target, true, OPTAB_DIRECT); - if (temp == 0) - delete_insns_since (last); - return temp; + if (temp) + { + if (mclass != MODE_INT + || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode)) + return convert_to_mode (mode, temp, 0); + else + return gen_lowpart (mode, temp); + } + else + delete_insns_since (last); } } } |