Hi, on S/390 atomic operands need to be naturally aligned. Otherwise the instruction throws an specification exception. With the patch the expanders reject operands not being properly aligned.
This only works if the expander code actually allows atomic expanders to fail. This did not seem to be case for the compare and swap code. Fixed with a separate patch. I'll commit the patch after the optab fix is in. This fixes 45 atomic fails in the testsuite on s390x. Bye, -Andreas- 2014-02-07 Andreas Krebbel <andreas.kreb...@de.ibm.com> * config/s390/s390.md ("atomic_load<mode>", "atomic_store<mode>") ("atomic_compare_and_swap<mode>", "atomic_fetch_<atomic><mode>"): Reject misaligned operands. commit 9431dff0d0dcf8771689c1df49e0bea50ac96d5a Author: Andreas Krebbel <kreb...@linux.vnet.ibm.com> Date: Fri Feb 7 12:51:17 2014 +0100 S/390: Prevent 128bit atomic ops from being used on misaligned memory operands. diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index bccc159..3f86304 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -9108,6 +9108,9 @@ (match_operand:SI 2 "const_int_operand")] ;; model "" { + if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1]))) + FAIL; + if (<MODE>mode == TImode) emit_insn (gen_atomic_loadti_1 (operands[0], operands[1])); else if (<MODE>mode == DImode && !TARGET_ZARCH) @@ -9149,6 +9152,9 @@ { enum memmodel model = (enum memmodel) INTVAL (operands[2]); + if (MEM_ALIGN (operands[0]) < GET_MODE_BITSIZE (GET_MODE (operands[0]))) + FAIL; + if (<MODE>mode == TImode) emit_insn (gen_atomic_storeti_1 (operands[0], operands[1])); else if (<MODE>mode == DImode && !TARGET_ZARCH) @@ -9203,6 +9209,9 @@ if (!register_operand (output, <MODE>mode)) output = gen_reg_rtx (<MODE>mode); + if (MEM_ALIGN (operands[2]) < GET_MODE_BITSIZE (GET_MODE (operands[2]))) + FAIL; + emit_insn (gen_atomic_compare_and_swap<mode>_internal (output, operands[2], operands[3], operands[4])); @@ -9319,6 +9328,9 @@ (match_operand:SI 3 "const_int_operand")] ;; model "TARGET_Z196" { + if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1]))) + FAIL; + emit_insn (gen_atomic_fetch_<atomic><mode>_iaf (operands[0], operands[1], operands[2])); DONE;