This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PR 28403: Arguments not popped after some doubleword shifts
- From: Richard Sandiford <richard at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 17 Jul 2006 13:58:41 +0100
- Subject: PR 28403: Arguments not popped after some doubleword shifts
This patch fixes 28403, which, like 28402, is an SH regression
introduced by:
2004-09-04 Richard Sandiford <rsandifo@redhat.com>
* doc/md.texi (shift patterns): New anchor. Add reference to
TARGET_SHIFT_TRUNCATION_MASK.
* doc/tm.texi (TARGET_SHIFT_TRUNCATION_MASK): Document.
* target.h (shift_truncation_mask): New target hook.
* targhook.h (default_shift_truncation_mask): Declare.
* targhook.c (default_shift_truncation_mask): Define.
* target-def.h (TARGET_SHIFT_TRUNCATION_MASK): Define.
(TARGET_INITIALIZER): Include it.
* simplify-rtx.c (simplify_binary_operation): Combine ASHIFT, ASHIFTRT
and LSHIFTRT cases. Truncate arg1 if SHIFT_COUNT_TRUNCATED, otherwise
reject all out-of-range values. Fix sign-extension code for modes
whose width is smaller than HOST_BITS_PER_WIDE_INT.
* optabs.c (simplify_expand_binop, force_expand_binop): New functions.
(expand_superword_shift, expand_subword_shift): Likewise.
(expand_doubleword_shift_condmove, expand_doubleword_shift): Likewise.
(expand_binop): Use them to implement double-word shifts.
* config/arm/arm.c (arm_shift_truncation_mask): New function.
(TARGET_SHIFT_TRUNCATION_MASK): Define.
In the testcase:
ull
bar (ull x)
{
foo (1, 2, 1, 3, 1, 4, 1, 5);
return x >> global;
}
we first try to use expand_binop() to synthesise the shift using
OPTAB_DIRECT, only falling back on more relaxed methods if this first
attempt fails. The problem is that the OPTAB_DIRECT attempt includes
a call to do_compare_rtx_and_jump, and this function in turn pops the
arguments from the call to foo(). The sequence with the pop is
discarded when the later OPTAB_DIRECT word_mode shift expansions fail.
The fix is obvious; defer popping for this call. Bootstrapped &
regression-tested on x86_64-linux-gnu. Also regression-tested on
sh-elf. OK for trunk? This is a 4.x regression from 3.4, so OK
for the branches too, once tested there?
Richard
gcc/
PR middle-end/28403
* optabs.c (expand_doubleword_shift): Wrap the call to
do_compare_rtx_and_jump with NO_DEFER_POP and OK_DEFER_POP.
gcc/testsuite/
PR middle-end/28403
* gcc.c-torture/execute/pr28403.c: New test.
Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c (revision 115438)
+++ gcc/optabs.c (working copy)
@@ -959,8 +959,10 @@ expand_doubleword_shift (enum machine_mo
subword_label = gen_label_rtx ();
done_label = gen_label_rtx ();
+ NO_DEFER_POP;
do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
0, 0, subword_label);
+ OK_DEFER_POP;
if (!expand_superword_shift (binoptab, outof_input, superword_op1,
outof_target, into_target,
Index: gcc/testsuite/gcc.c-torture/execute/pr28403.c
===================================================================
--- gcc/testsuite/gcc.c-torture/execute/pr28403.c (revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr28403.c (revision 0)
@@ -0,0 +1,23 @@
+typedef unsigned long long ull;
+int global;
+
+int __attribute__((noinline))
+foo (int x1, int x2, int x3, int x4, int x5, int x6, int x7, int x8)
+{
+ global = x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8;
+}
+
+ull __attribute__((noinline))
+bar (ull x)
+{
+ foo (1, 2, 1, 3, 1, 4, 1, 5);
+ return x >> global;
+}
+
+int
+main (void)
+{
+ if (bar (0x123456789abcdefULL) != (0x123456789abcdefULL >> 18))
+ abort ();
+ exit (0);
+}