This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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);
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]