143 lines
4.5 KiB
Diff
143 lines
4.5 KiB
Diff
|
2019-01-21 Jakub Jelinek <jakub@redhat.com>
|
|||
|
|
|||
|
PR target/88905
|
|||
|
* optabs.c (add_equal_note): Add op0_mode argument, use it instead of
|
|||
|
GET_MODE (op0).
|
|||
|
(expand_binop_directly, expand_doubleword_clz,
|
|||
|
expand_doubleword_popcount, expand_ctz, expand_ffs,
|
|||
|
expand_unop_direct, maybe_emit_unop_insn): Adjust callers.
|
|||
|
|
|||
|
* gcc.dg/pr88905.c: New test.
|
|||
|
|
|||
|
--- gcc/optabs.c.jj 2019-01-01 12:37:17.711965861 +0100
|
|||
|
+++ gcc/optabs.c 2019-01-21 13:56:18.263446049 +0100
|
|||
|
@@ -55,7 +55,7 @@ void debug_optab_libfuncs (void);
|
|||
|
|
|||
|
/* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
|
|||
|
the result of operation CODE applied to OP0 (and OP1 if it is a binary
|
|||
|
- operation).
|
|||
|
+ operation). OP0_MODE is OP0's mode.
|
|||
|
|
|||
|
If the last insn does not set TARGET, don't do anything, but return 1.
|
|||
|
|
|||
|
@@ -64,7 +64,8 @@ void debug_optab_libfuncs (void);
|
|||
|
try again, ensuring that TARGET is not one of the operands. */
|
|||
|
|
|||
|
static int
|
|||
|
-add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
|
|||
|
+add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0,
|
|||
|
+ rtx op1, machine_mode op0_mode)
|
|||
|
{
|
|||
|
rtx_insn *last_insn;
|
|||
|
rtx set;
|
|||
|
@@ -136,16 +137,16 @@ add_equal_note (rtx_insn *insns, rtx tar
|
|||
|
case POPCOUNT:
|
|||
|
case PARITY:
|
|||
|
case BSWAP:
|
|||
|
- if (GET_MODE (op0) != VOIDmode && GET_MODE (target) != GET_MODE (op0))
|
|||
|
+ if (op0_mode != VOIDmode && GET_MODE (target) != op0_mode)
|
|||
|
{
|
|||
|
- note = gen_rtx_fmt_e (code, GET_MODE (op0), copy_rtx (op0));
|
|||
|
- if (GET_MODE_UNIT_SIZE (GET_MODE (op0))
|
|||
|
+ note = gen_rtx_fmt_e (code, op0_mode, copy_rtx (op0));
|
|||
|
+ if (GET_MODE_UNIT_SIZE (op0_mode)
|
|||
|
> GET_MODE_UNIT_SIZE (GET_MODE (target)))
|
|||
|
note = simplify_gen_unary (TRUNCATE, GET_MODE (target),
|
|||
|
- note, GET_MODE (op0));
|
|||
|
+ note, op0_mode);
|
|||
|
else
|
|||
|
note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target),
|
|||
|
- note, GET_MODE (op0));
|
|||
|
+ note, op0_mode);
|
|||
|
break;
|
|||
|
}
|
|||
|
/* FALLTHRU */
|
|||
|
@@ -1127,7 +1128,7 @@ expand_binop_directly (enum insn_code ic
|
|||
|
if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
|
|||
|
&& ! add_equal_note (pat, ops[0].value,
|
|||
|
optab_to_code (binoptab),
|
|||
|
- ops[1].value, ops[2].value))
|
|||
|
+ ops[1].value, ops[2].value, mode0))
|
|||
|
{
|
|||
|
delete_insns_since (last);
|
|||
|
return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
|
|||
|
@@ -2298,7 +2299,7 @@ expand_doubleword_clz (scalar_int_mode m
|
|||
|
seq = get_insns ();
|
|||
|
end_sequence ();
|
|||
|
|
|||
|
- add_equal_note (seq, target, CLZ, xop0, 0);
|
|||
|
+ add_equal_note (seq, target, CLZ, xop0, NULL_RTX, mode);
|
|||
|
emit_insn (seq);
|
|||
|
return target;
|
|||
|
|
|||
|
@@ -2340,7 +2341,7 @@ expand_doubleword_popcount (scalar_int_m
|
|||
|
seq = get_insns ();
|
|||
|
end_sequence ();
|
|||
|
|
|||
|
- add_equal_note (seq, t, POPCOUNT, op0, 0);
|
|||
|
+ add_equal_note (seq, t, POPCOUNT, op0, NULL_RTX, mode);
|
|||
|
emit_insn (seq);
|
|||
|
return t;
|
|||
|
}
|
|||
|
@@ -2511,7 +2512,7 @@ expand_ctz (scalar_int_mode mode, rtx op
|
|||
|
seq = get_insns ();
|
|||
|
end_sequence ();
|
|||
|
|
|||
|
- add_equal_note (seq, temp, CTZ, op0, 0);
|
|||
|
+ add_equal_note (seq, temp, CTZ, op0, NULL_RTX, mode);
|
|||
|
emit_insn (seq);
|
|||
|
return temp;
|
|||
|
}
|
|||
|
@@ -2589,7 +2590,7 @@ expand_ffs (scalar_int_mode mode, rtx op
|
|||
|
seq = get_insns ();
|
|||
|
end_sequence ();
|
|||
|
|
|||
|
- add_equal_note (seq, temp, FFS, op0, 0);
|
|||
|
+ add_equal_note (seq, temp, FFS, op0, NULL_RTX, mode);
|
|||
|
emit_insn (seq);
|
|||
|
return temp;
|
|||
|
|
|||
|
@@ -2736,7 +2737,7 @@ expand_unop_direct (machine_mode mode, o
|
|||
|
if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
|
|||
|
&& ! add_equal_note (pat, ops[0].value,
|
|||
|
optab_to_code (unoptab),
|
|||
|
- ops[1].value, NULL_RTX))
|
|||
|
+ ops[1].value, NULL_RTX, mode))
|
|||
|
{
|
|||
|
delete_insns_since (last);
|
|||
|
return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
|
|||
|
@@ -3588,7 +3589,8 @@ maybe_emit_unop_insn (enum insn_code ico
|
|||
|
|
|||
|
if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
|
|||
|
&& code != UNKNOWN)
|
|||
|
- add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX);
|
|||
|
+ add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX,
|
|||
|
+ GET_MODE (op0));
|
|||
|
|
|||
|
emit_insn (pat);
|
|||
|
|
|||
|
--- gcc/testsuite/gcc.dg/pr88905.c.jj 2019-01-21 14:19:17.279746531 +0100
|
|||
|
+++ gcc/testsuite/gcc.dg/pr88905.c 2019-01-21 14:18:56.264091537 +0100
|
|||
|
@@ -0,0 +1,21 @@
|
|||
|
+/* PR target/88905 */
|
|||
|
+/* { dg-do compile } */
|
|||
|
+/* { dg-options "-Og -fno-tree-ccp" } */
|
|||
|
+/* { dg-additional-options "-mabm" { target { i?86-*-* x86_64-*-* } } } */
|
|||
|
+
|
|||
|
+int a, b, c;
|
|||
|
+extern void baz (int);
|
|||
|
+
|
|||
|
+static inline int
|
|||
|
+bar (unsigned u)
|
|||
|
+{
|
|||
|
+ int i = __builtin_popcountll (-(unsigned long long) u);
|
|||
|
+ baz (i & c);
|
|||
|
+ return a + b + c;
|
|||
|
+}
|
|||
|
+
|
|||
|
+void
|
|||
|
+foo (void)
|
|||
|
+{
|
|||
|
+ bar (2376498292ULL);
|
|||
|
+}
|