aboutsummaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-08-23 17:51:45 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2011-08-23 17:51:45 +0200
commite2f008377225f76538d728cb16772e29091feb0f (patch)
tree62fb2f1d429ec029087fc74ce2fd3609e593cd39 /gcc/optabs.c
parente70e0b60724694c40064580368e5b93aae951842 (diff)
downloadgcc-e2f008377225f76538d728cb16772e29091feb0f.zip
gcc-e2f008377225f76538d728cb16772e29091feb0f.tar.gz
gcc-e2f008377225f76538d728cb16772e29091feb0f.tar.bz2
re PR middle-end/50161 (wrong code with -fno-tree-ter and __builtin_popcountl)
PR middle-end/50161 * simplify-rtx.c (simplify_const_unary_operation): If op is CONST_INT, don't look at op_mode, but use instead mode. * optabs.c (add_equal_note): For FFS, CLZ, CTZ, CLRSB, POPCOUNT, PARITY and BSWAP use operand mode for operation and TRUNCATE/ZERO_EXTEND if needed. * doc/rtl.texi (ffs, clrsb, clz, ctz, popcount, parity, bswap): Document that operand mode must be same as operation mode, or VOIDmode. * config/avr/avr.md (paritysi2, *parityqihi2.libgcc, *paritysihi2.libgcc, popcountsi2, *popcountsi2.libgcc, *popcountqihi2.libgcc, clzsi2, *clzsihi2.libgcc, ctzsi2, *ctzsihi2.libgcc, ffssi2, *ffssihi2.libgcc): For unary ops use the mode of operand for the operation and add truncate or zero_extend around if needed. * config/c6x/c6x.md (ctzdi2): Likewise. * config/bfin/bfin.md (clrsbsi2, signbitssi2): Likewise. * gcc.dg/pr50161.c: New test. From-SVN: r177991
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r--gcc/optabs.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c
index a70119a..886b259 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -216,7 +216,32 @@ add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
}
if (GET_RTX_CLASS (code) == RTX_UNARY)
- note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
+ switch (code)
+ {
+ case FFS:
+ case CLZ:
+ case CTZ:
+ case CLRSB:
+ case POPCOUNT:
+ case PARITY:
+ case BSWAP:
+ if (GET_MODE (op0) != VOIDmode && GET_MODE (target) != GET_MODE (op0))
+ {
+ note = gen_rtx_fmt_e (code, GET_MODE (op0), copy_rtx (op0));
+ if (GET_MODE_SIZE (GET_MODE (op0))
+ > GET_MODE_SIZE (GET_MODE (target)))
+ note = simplify_gen_unary (TRUNCATE, GET_MODE (target),
+ note, GET_MODE (op0));
+ else
+ note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target),
+ note, GET_MODE (op0));
+ break;
+ }
+ /* FALLTHRU */
+ default:
+ note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
+ break;
+ }
else
note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));