Hello!

As shown in the attached testcase, arguments of various __atomic
builtins should be converted as signed, so the immediates get properly
extended.

2013-10-08  Uros Bizjak  <ubiz...@gmail.com>

    * optabs.c (maybe_emit_atomic_exchange): Convert operands as signed.
    (maybe_emit_sync_lock_test_and_set): Ditto.
    (expand_atomic_compare_and_swap): Ditto.
    (maybe_emit_op): Ditto.

testsuite/ChangeLog:

2013-10-08  Uros Bizjak  <ubiz...@gmail.com>

    * g++.dg/ext/atomic-2.C: New test.

Patch was bootstrapped and regression tested on x86_64-pc-linux-gnu {,-m32}.

OK for mainline and release branches?

Uros.
Index: optabs.c
===================================================================
--- optabs.c    (revision 203285)
+++ optabs.c    (working copy)
@@ -7041,7 +7041,7 @@ maybe_emit_atomic_exchange (rtx target, rtx mem, r
       create_output_operand (&ops[0], target, mode);
       create_fixed_operand (&ops[1], mem);
       /* VAL may have been promoted to a wider mode.  Shrink it if so.  */
-      create_convert_operand_to (&ops[2], val, mode, true);
+      create_convert_operand_to (&ops[2], val, mode, false);
       create_integer_operand (&ops[3], model);
       if (maybe_expand_insn (icode, 4, ops))
        return ops[0].value;
@@ -7081,7 +7081,7 @@ maybe_emit_sync_lock_test_and_set (rtx target, rtx
       create_output_operand (&ops[0], target, mode);
       create_fixed_operand (&ops[1], mem);
       /* VAL may have been promoted to a wider mode.  Shrink it if so.  */
-      create_convert_operand_to (&ops[2], val, mode, true);
+      create_convert_operand_to (&ops[2], val, mode, false);
       if (maybe_expand_insn (icode, 3, ops))
        return ops[0].value;
     }
@@ -7336,8 +7336,8 @@ expand_atomic_compare_and_swap (rtx *ptarget_bool,
       create_output_operand (&ops[0], target_bool, bool_mode);
       create_output_operand (&ops[1], target_oval, mode);
       create_fixed_operand (&ops[2], mem);
-      create_convert_operand_to (&ops[3], expected, mode, true);
-      create_convert_operand_to (&ops[4], desired, mode, true);
+      create_convert_operand_to (&ops[3], expected, mode, false);
+      create_convert_operand_to (&ops[4], desired, mode, false);
       create_integer_operand (&ops[5], is_weak);
       create_integer_operand (&ops[6], succ_model);
       create_integer_operand (&ops[7], fail_model);
@@ -7358,8 +7358,8 @@ expand_atomic_compare_and_swap (rtx *ptarget_bool,
 
       create_output_operand (&ops[0], target_oval, mode);
       create_fixed_operand (&ops[1], mem);
-      create_convert_operand_to (&ops[2], expected, mode, true);
-      create_convert_operand_to (&ops[3], desired, mode, true);
+      create_convert_operand_to (&ops[2], expected, mode, false);
+      create_convert_operand_to (&ops[3], desired, mode, false);
       if (!maybe_expand_insn (icode, 4, ops))
        return false;
 
@@ -7788,7 +7788,7 @@ maybe_emit_op (const struct atomic_op_functions *o
 
   create_fixed_operand (&ops[op_counter++], mem);
   /* VAL may have been promoted to a wider mode.  Shrink it if so.  */
-  create_convert_operand_to (&ops[op_counter++], val, mode, true);
+  create_convert_operand_to (&ops[op_counter++], val, mode, false);
 
   if (maybe_expand_insn (icode, num_ops, ops))
     return (target == const0_rtx ? const0_rtx : ops[0].value);
Index: testsuite/g++.dg/ext/atomic-2.C
===================================================================
--- testsuite/g++.dg/ext/atomic-2.C     (revision 0)
+++ testsuite/g++.dg/ext/atomic-2.C     (working copy)
@@ -0,0 +1,18 @@
+// { dg-do run { target c++11 } }
+// { dg-require-effective-target sync_int_128_runtime }
+// { dg-options "-O2" }
+// { dg-additional-options "-mcx16" { target { i?86-*-* x86_64-*-* } } }
+
+#include <atomic>
+#include <cassert>
+
+int
+main (int, char **)
+{
+  std::atomic < __int128_t > i;
+
+  i = -1;
+
+  assert (int64_t (i >> 64) == -1);
+  assert (int64_t (i) == -1);
+}

Reply via email to