[4.4] Backport fixes to PR45070 and PR44328 and a test

Ian Bolton ian.bolton@arm.com
Tue Sep 7 09:12:00 GMT 2010


Hi all,

OK to commit this backport to 4.4 branch?

It passes gcc,g++,gfortran regression tests.
 
Cheers,
Ian


2010-09-07  Ian Bolton  <ian.bolton@arm.com>

	Backport from mainline
	2010-09-01  Ian Bolton  <ian.bolton@arm.com>

	* Makefile.in (tree-switch-conversion.o): Update dependencies.
	
	2010-08-19  Ian Bolton  <ian.bolton@arm.com>
	
	PR target/45070
	* config/arm/arm.c (arm_output_epilogue): Ensure that return
	value of size 1-3 is handled correctly.

	* gcc.c-torture/execute/pr45070.c: New.

	2010-08-19  Ian Bolton  <ian.bolton@arm.com>

	* tree-switch-conversion.c (gen_inbound_check): Ensure that the
	type for the conditional has wide enough range.

	* g++.dg/pr44328.C: New test.

	2010-08-07  Marcus Shawcroft  <marcus.shawcroft@arm.com>
	
	* config/arm/linux-atomic.c (SUBWORD_VAL_CAS): Instantiate with
	'unsigned short' and 'unsigned char' instead of 'short' and 'char'.
	(SUBWORD_BOOL_CAS): Likewise.
	(SUBWORD_SYNC_OP): Likewise.
	(SUBWORD_TEST_AND_SET): Likewise.
	(FETCH_AND_OP_WORD): Parenthesise INF_OP
	(SUBWORD_SYNC_OP): Likewise.
	(OP_AND_FETCH_WORD): Likewise.

	* lib/target-supports.exp: (check_effective_target_sync_int_long):
	Add arm*-*-linux-gnueabi.
	(check_effective_target_sync_char_short): Likewise.


Index: gcc/testsuite/gcc.c-torture/execute/pr45070.c
===================================================================
--- gcc/testsuite/gcc.c-torture/execute/pr45070.c	(revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr45070.c	(revision 163774)
@@ -0,0 +1,52 @@
+/* PR45070 */
+extern void abort(void);
+
+struct packed_ushort {
+    unsigned short ucs;
+} __attribute__((packed));
+
+struct source {
+    int pos, length;
+    int flag;
+};
+
+static void __attribute__((noinline)) fetch(struct source *p)
+{
+    p->length = 128;
+}
+    
+static struct packed_ushort __attribute__((noinline)) next(struct source
*p)
+{
+    struct packed_ushort rv;
+
+    if (p->pos >= p->length) {
+	if (p->flag) {
+	    p->flag = 0;
+	    fetch(p);
+	    return next(p);
+	}
+	p->flag = 1;
+	rv.ucs = 0xffff;
+	return rv;
+    }
+    rv.ucs = 0;
+    return rv;
+}
+
+int main(void)
+{
+    struct source s;
+    int i;
+
+    s.pos = 0;
+    s.length = 0;
+    s.flag = 0;
+
+    for (i = 0; i < 16; i++) {
+	struct packed_ushort rv = next(&s);
+	if ((i == 0 && rv.ucs != 0xffff)
+	    || (i > 0 && rv.ucs != 0))
+	    abort();
+    }
+    return 0;
+}
Index: gcc/testsuite/g++.dg/pr44328.C
===================================================================
--- gcc/testsuite/g++.dg/pr44328.C	(revision 0)
+++ gcc/testsuite/g++.dg/pr44328.C	(revision 163774)
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-c -O2 -Wextra" } */
+#define O_RDONLY     (1<<0)
+#define O_WRONLY     (1<<1)
+#define O_RDWR       (O_RDONLY|O_WRONLY)
+#define O_CREAT      (1<<3)
+#define O_TRUNC      (1<<6)
+
+typedef enum {
+    OM_READ = 0,
+    OM_WRITE,
+    OM_READWRITE_NOCREATE,
+    OM_READWRITE_CREATE
+} OpenMode;
+
+extern int open(const char *name, int mode);
+
+void open_file(const char *filename, const OpenMode rw)
+{
+    int mode = 0;
+
+    switch( rw )
+    {
+    case OM_WRITE:
+        mode = O_WRONLY|O_CREAT|O_TRUNC;
+        break;
+    case OM_READ:
+        mode = O_RDONLY;
+        break;
+    case OM_READWRITE_NOCREATE:
+        mode = O_RDWR;
+        break;
+    case OM_READWRITE_CREATE:
+        mode = O_RDWR|O_CREAT|O_TRUNC;
+        break;
+    }
+
+    open( filename, mode );
+}
Index: gcc/testsuite/lib/target-supports.exp
===================================================================
--- gcc/testsuite/lib/target-supports.exp	(revision 163773)
+++ gcc/testsuite/lib/target-supports.exp	(revision 163774)
@@ -2816,6 +2816,7 @@ proc check_effective_target_sync_int_lon
 	     || [istarget i?86-*-*]
 	     || [istarget x86_64-*-*]
 	     || [istarget alpha*-*-*] 
+	     || [istarget arm*-*-linux-gnueabi] 
 	     || [istarget bfin*-*linux*]
 	     || [istarget s390*-*-*] 
 	     || [istarget powerpc*-*-*]
@@ -2845,6 +2846,7 @@ proc check_effective_target_sync_char_sh
 	     || [istarget i?86-*-*]
 	     || [istarget x86_64-*-*]
 	     || [istarget alpha*-*-*] 
+	     || [istarget arm*-*-linux-gnueabi] 
 	     || [istarget s390*-*-*] 
 	     || [istarget powerpc*-*-*]
 	     || [istarget sparc64-*-*]
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	(revision 163773)
+++ gcc/Makefile.in	(revision 163774)
@@ -3005,7 +3005,7 @@ tree-switch-conversion.o : tree-switch-c
     $(TREE_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \
     $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(GIMPLE_H) \
     $(TREE_PASS_H) $(FLAGS_H) $(EXPR_H) $(BASIC_BLOCK_H) output.h \
-    $(GGC_H) $(OBSTACK_H) $(PARAMS_H) $(CPPLIB_H) $(PARAMS_H)
+    $(GGC_H) $(OBSTACK_H) $(PARAMS_H) $(CPPLIB_H) $(PARAMS_H) langhooks.h
 tree-complex.o : tree-complex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h
$(TREE_H) \
     $(TM_H) $(RTL_H) $(REAL_H) $(FLAGS_H) $(TREE_FLOW_H) $(GIMPLE_H) \
     tree-iterator.h $(TREE_PASS_H) tree-ssa-propagate.h $(DIAGNOSTIC_H)
Index: gcc/tree-switch-conversion.c
===================================================================
--- gcc/tree-switch-conversion.c	(revision 163773)
+++ gcc/tree-switch-conversion.c	(revision 163774)
@@ -96,6 +96,7 @@ eight) times the number of the actual sw
 #include "diagnostic.h"
 #include "tree-dump.h"
 #include "timevar.h"
+#include "langhooks.h"
 
 /* The main structure of the pass.  */
 struct switch_conv_info
@@ -693,9 +694,11 @@ gen_inbound_check (gimple swtch)
 
   /* Make sure we do not generate arithmetics in a subrange.  */
   if (TREE_TYPE (TREE_TYPE (info.index_expr)))
-    utype = unsigned_type_for (TREE_TYPE (TREE_TYPE (info.index_expr)));
+    utype = lang_hooks.types.type_for_mode
+      (TYPE_MODE (TREE_TYPE (TREE_TYPE (info.index_expr))), 1);
   else
-    utype = unsigned_type_for (TREE_TYPE (info.index_expr));
+    utype = lang_hooks.types.type_for_mode
+      (TYPE_MODE (TREE_TYPE (info.index_expr)), 1);
 
   /* (end of) block 0 */
   gsi = gsi_for_stmt (info.arr_ref_first);
Index: gcc/config/arm/linux-atomic.c
===================================================================
--- gcc/config/arm/linux-atomic.c	(revision 163773)
+++ gcc/config/arm/linux-atomic.c	(revision 163774)
@@ -56,7 +56,7 @@ typedef void (__kernel_dmb_t) (void);
 									\
     do {								\
       tmp = *ptr;							\
-      failure = __kernel_cmpxchg (tmp, PFX_OP tmp INF_OP val, ptr);	\
+      failure = __kernel_cmpxchg (tmp, PFX_OP (tmp INF_OP val), ptr);	\
     } while (failure != 0);						\
 									\
     return tmp;
\
@@ -88,8 +88,8 @@ FETCH_AND_OP_WORD (nand, ~, &)
 									\
     do {								\
       oldval = *wordptr;						\
-      newval = ((PFX_OP ((oldval & mask) >> shift)			\
-                 INF_OP (unsigned int) val) << shift) & mask;		\
+      newval = ((PFX_OP (((oldval & mask) >> shift)			\
+			 INF_OP (unsigned int) val)) << shift) & mask;	\
       newval |= oldval & ~mask;
\
       failure = __kernel_cmpxchg (oldval, newval, wordptr);		\
     } while (failure != 0);						\
@@ -97,19 +97,19 @@ FETCH_AND_OP_WORD (nand, ~, &)
     return (RETURN & mask) >> shift;					\
   }
 
-SUBWORD_SYNC_OP (add,   , +, short, 2, oldval)
-SUBWORD_SYNC_OP (sub,   , -, short, 2, oldval)
-SUBWORD_SYNC_OP (or,    , |, short, 2, oldval)
-SUBWORD_SYNC_OP (and,   , &, short, 2, oldval)
-SUBWORD_SYNC_OP (xor,   , ^, short, 2, oldval)
-SUBWORD_SYNC_OP (nand, ~, &, short, 2, oldval)
-
-SUBWORD_SYNC_OP (add,   , +, char, 1, oldval)
-SUBWORD_SYNC_OP (sub,   , -, char, 1, oldval)
-SUBWORD_SYNC_OP (or,    , |, char, 1, oldval)
-SUBWORD_SYNC_OP (and,   , &, char, 1, oldval)
-SUBWORD_SYNC_OP (xor,   , ^, char, 1, oldval)
-SUBWORD_SYNC_OP (nand, ~, &, char, 1, oldval)
+SUBWORD_SYNC_OP (add,   , +, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (sub,   , -, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (or,    , |, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (and,   , &, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (xor,   , ^, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned short, 2, oldval)
+
+SUBWORD_SYNC_OP (add,   , +, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (sub,   , -, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (or,    , |, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (and,   , &, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (xor,   , ^, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned char, 1, oldval)
 
 #define OP_AND_FETCH_WORD(OP, PFX_OP, INF_OP)				\
   int HIDDEN								\
@@ -119,10 +119,10 @@ SUBWORD_SYNC_OP (nand, ~, &, char, 1, ol
 									\
     do {								\
       tmp = *ptr;							\
-      failure = __kernel_cmpxchg (tmp, PFX_OP tmp INF_OP val, ptr);	\
+      failure = __kernel_cmpxchg (tmp, PFX_OP (tmp INF_OP val), ptr);	\
     } while (failure != 0);						\
 									\
-    return PFX_OP tmp INF_OP val;					\
+    return PFX_OP (tmp INF_OP val);					\
   }
 
 OP_AND_FETCH_WORD (add,   , +)
@@ -132,19 +132,19 @@ OP_AND_FETCH_WORD (and,   , &)
 OP_AND_FETCH_WORD (xor,   , ^)
 OP_AND_FETCH_WORD (nand, ~, &)
 
-SUBWORD_SYNC_OP (add,   , +, short, 2, newval)
-SUBWORD_SYNC_OP (sub,   , -, short, 2, newval)
-SUBWORD_SYNC_OP (or,    , |, short, 2, newval)
-SUBWORD_SYNC_OP (and,   , &, short, 2, newval)
-SUBWORD_SYNC_OP (xor,   , ^, short, 2, newval)
-SUBWORD_SYNC_OP (nand, ~, &, short, 2, newval)
-
-SUBWORD_SYNC_OP (add,   , +, char, 1, newval)
-SUBWORD_SYNC_OP (sub,   , -, char, 1, newval)
-SUBWORD_SYNC_OP (or,    , |, char, 1, newval)
-SUBWORD_SYNC_OP (and,   , &, char, 1, newval)
-SUBWORD_SYNC_OP (xor,   , ^, char, 1, newval)
-SUBWORD_SYNC_OP (nand, ~, &, char, 1, newval)
+SUBWORD_SYNC_OP (add,   , +, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (sub,   , -, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (or,    , |, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (and,   , &, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (xor,   , ^, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned short, 2, newval)
+
+SUBWORD_SYNC_OP (add,   , +, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (sub,   , -, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (or,    , |, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (and,   , &, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (xor,   , ^, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned char, 1, newval)
 
 int HIDDEN
 __sync_val_compare_and_swap_4 (int *ptr, int oldval, int newval)
@@ -194,8 +194,8 @@ __sync_val_compare_and_swap_4 (int *ptr,
       }
\
   }
 
-SUBWORD_VAL_CAS (short, 2)
-SUBWORD_VAL_CAS (char,  1)
+SUBWORD_VAL_CAS (unsigned short, 2)
+SUBWORD_VAL_CAS (unsigned char,  1)
 
 typedef unsigned char bool;
 
@@ -216,8 +216,8 @@ __sync_bool_compare_and_swap_4 (int *ptr
     return (oldval == actual_oldval);					\
   }
 
-SUBWORD_BOOL_CAS (short, 2)
-SUBWORD_BOOL_CAS (char,  1)
+SUBWORD_BOOL_CAS (unsigned short, 2)
+SUBWORD_BOOL_CAS (unsigned char,  1)
 
 void HIDDEN
 __sync_synchronize (void)
@@ -259,8 +259,8 @@ __sync_lock_test_and_set_4 (int *ptr, in
     return (oldval & mask) >> shift;					\
   }
 
-SUBWORD_TEST_AND_SET (short, 2)
-SUBWORD_TEST_AND_SET (char,  1)
+SUBWORD_TEST_AND_SET (unsigned short, 2)
+SUBWORD_TEST_AND_SET (unsigned char,  1)
 
 #define SYNC_LOCK_RELEASE(TYPE, WIDTH)					\
   void HIDDEN								\
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	(revision 163773)
+++ gcc/config/arm/arm.c	(revision 163774)
@@ -13705,7 +13705,8 @@ arm_output_epilogue (rtx sibling)
 		  && !crtl->tail_call_emit)
 		{
 		  unsigned long mask;
-		  mask = (1 << (arm_size_return_regs() / 4)) - 1;
+                  /* Preserve return values, of any size.  */
+		  mask = (1 << ((arm_size_return_regs() + 3) / 4)) - 1;
 		  mask ^= 0xf;
 		  mask &= ~saved_regs_mask;
 		  reg = 0;




More information about the Gcc-patches mailing list