diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f6b8fe561d4..b36bdcf817a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2008-01-26 Richard Sandiford + + PR rtl-optimization/34959 + * optabs.c (expand_unop): In libcall notes, give ffs, clz, ctz, + popcount and parity rtxes the same mode as their operand. + Truncate or extend the result to the return value's mode + if necessary. + 2008-01-26 Richard Sandiford PR target/34981 diff --git a/gcc/optabs.c b/gcc/optabs.c index 089fcccc993..448b799cb09 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -3273,6 +3273,7 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target, { rtx insns; rtx value; + rtx eq_value; enum machine_mode outmode = mode; /* All of these functions return small values. Thus we choose to @@ -3292,8 +3293,12 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target, end_sequence (); target = gen_reg_rtx (outmode); - emit_libcall_block (insns, target, value, - gen_rtx_fmt_e (unoptab->code, outmode, op0)); + eq_value = gen_rtx_fmt_e (unoptab->code, mode, op0); + if (GET_MODE_SIZE (outmode) < GET_MODE_SIZE (mode)) + eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode); + else if (GET_MODE_SIZE (outmode) > GET_MODE_SIZE (mode)) + eq_value = simplify_gen_unary (ZERO_EXTEND, outmode, eq_value, mode); + emit_libcall_block (insns, target, value, eq_value); return target; }