re PR target/28924 (x86 sync builtins fail for char and short memory operands)
authorJakub Jelinek <jakub@redhat.com>
Fri, 6 Oct 2006 16:54:43 +0000 (18:54 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 6 Oct 2006 16:54:43 +0000 (18:54 +0200)
PR target/28924
* builtins.c (expand_builtin_sync_operation,
expand_builtin_compare_and_swap, expand_builtin_lock_test_and_set):
Use convert_to_mode to handle promoted arguments.

* gcc.c-torture/compile/20061005-1.c: New test.

From-SVN: r117508

gcc/ChangeLog
gcc/builtins.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/20061005-1.c [new file with mode: 0644]

index 7625c494df01d4745e67bd4423e2fdbe9fc43799..17765ab88f799e1565984bd0f802e2940de7839c 100644 (file)
@@ -1,3 +1,10 @@
+2006-10-06  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/28924
+       * builtins.c (expand_builtin_sync_operation,
+       expand_builtin_compare_and_swap, expand_builtin_lock_test_and_set):
+       Use convert_to_mode to handle promoted arguments.
+
 2006-10-06  J"orn Rennecke  <joern.rennecke@st.com>
 
        * print-tree.c (print_node_brief, print_node): Print sign of Inf.
index 2c81983f3d31572d7cbd89e2ce08a473fc4933e3..29974622ea19c24bd767bdef352661927e8cda4c 100644 (file)
@@ -5494,6 +5494,8 @@ expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
 
   arglist = TREE_CHAIN (arglist);
   val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
+  /* If VAL is promoted to a wider mode, convert it back to MODE.  */
+  val = convert_to_mode (mode, val, 1);
 
   if (ignore)
     return expand_sync_operation (mem, val, code);
@@ -5517,9 +5519,13 @@ expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
 
   arglist = TREE_CHAIN (arglist);
   old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
+  /* If OLD_VAL is promoted to a wider mode, convert it back to MODE.  */
+  old_val = convert_to_mode (mode, old_val, 1);
 
   arglist = TREE_CHAIN (arglist);
   new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
+  /* If NEW_VAL is promoted to a wider mode, convert it back to MODE.  */
+  new_val = convert_to_mode (mode, new_val, 1);
 
   if (is_bool)
     return expand_bool_compare_and_swap (mem, old_val, new_val, target);
@@ -5544,6 +5550,8 @@ expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
 
   arglist = TREE_CHAIN (arglist);
   val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
+  /* If VAL is promoted to a wider mode, convert it back to MODE.  */
+  val = convert_to_mode (mode, val, 1);
 
   return expand_sync_lock_test_and_set (mem, val, target);
 }
index 43988d7250e2c07aafb90b842542bde6964616a6..9e16cecd218f44ea5e04e4ec32008f78661000da 100644 (file)
@@ -1,3 +1,8 @@
+2006-10-06  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/28924
+       * gcc.c-torture/compile/20061005-1.c: New test.
+
 2006-10-06  Olivier Hainque  <hainque@adacore.com>
        
        * gcc.dg/typename-vla-1.c: New case.
diff --git a/gcc/testsuite/gcc.c-torture/compile/20061005-1.c b/gcc/testsuite/gcc.c-torture/compile/20061005-1.c
new file mode 100644 (file)
index 0000000..a433509
--- /dev/null
@@ -0,0 +1,23 @@
+/* PR target/28924 */
+
+char c;
+
+void
+testc (void)
+{
+  (void) __sync_fetch_and_add (&c, -1);
+}
+
+short s;
+
+void
+tests (void)
+{
+  (void) __sync_fetch_and_add (&s, -1);
+}
+
+void
+testc2 (void)
+{
+  (void) __sync_val_compare_and_swap (&c, -1, -3);
+}