From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 72546 invoked by alias); 4 Jun 2015 14:19:11 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 72530 invoked by uid 89); 4 Jun 2015 14:19:10 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL,BAYES_00,SPF_PASS autolearn=ham version=3.3.2 X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (207.82.80.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 04 Jun 2015 14:19:09 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by uk-mta-32.uk.mimecast.lan; Thu, 04 Jun 2015 15:19:06 +0100 Received: from e106375-lin.cambridge.arm.com ([10.1.2.79]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Thu, 4 Jun 2015 15:19:06 +0100 From: James Greenhalgh To: gcc-patches@gcc.gnu.org Cc: rth@redhat.com, ebotcazou@libertysurf.fr Subject: [Patch] The comparison in a compare exchange should not take place in VOIDmode Date: Thu, 04 Jun 2015 14:25:00 -0000 Message-Id: <1433427542-22278-1-git-send-email-james.greenhalgh@arm.com> MIME-Version: 1.0 X-MC-Unique: jpChDw1PRKOOULxex5vdjg-1 Content-Type: multipart/mixed; boundary="------------2.2.0" X-IsSubscribed: yes X-SW-Source: 2015-06/txt/msg00413.txt.bz2 This is a multi-part message in MIME format. --------------2.2.0 Content-Type: text/plain; charset=UTF-8; format=fixed Content-Transfer-Encoding: quoted-printable Content-length: 1735 Hi, I was playing with some changes to costs for some immediate values in AArch64, and ended up tripping an ICE in some builtin expansion code. The ICE looked like this (some pruning of the boring bits...) format.c: In function '_gfortran_caf_atomic_cas': format.c:13:3: internal compiler error: in int_mode_for_mode, at stor-layou= t.c:443 (void)__atomic_compare_exchange_n(atom, (uint32_t *)old, *(uint32_t *)ne= w_val, ^ 0xa5e2b0 int_mode_for_mode(machine_mode) /work/gcc-dev/src/gcc/gcc/stor-layout.c:443 0x74cd78 emit_move_via_integer /work/gcc-dev/src/gcc/gcc/expr.c:3174 ... 0x73e5cf force_reg(machine_mode, rtx_def*) /work/gcc-dev/src/gcc/gcc/explow.c:643 0x997458 prepare_cmp_insn /work/gcc-dev/src/gcc/gcc/optabs.c:4076 ... 0x63e4cf expand_builtin_atomic_compare_exchange /work/gcc-dev/src/gcc/gcc/builtins.c:5479 ... The final symptom can be seen in force_reg, where it is asked to provide (set:VOID (reg:SI) (const_int 0)) And gives up. We end up here, as prepare_cmp_insn tries to force "expensive" constants to a register, using the mode provided to it from further up the call stack... Which takes us to expand_builtin_atomic_compare_exchange, which explicitly uses a VOIDmode for the comparison. This looks wrong to me, is a VOIDmode comparison ever valid? This patch fixes the issue by performing the comparison in the mode of the cmp-exchange target. It seems sensible to me, but may be nonsense, so I defer to others' opinions. Bootstrapped on AArch64/x86_64. OK? Thanks, James --- 2015-06-04 James Greenhalgh * builtins.c (expand_builtin_atomic_compare_exchange): Call emit_cmp_and_jump_insns with the mode of target. --------------2.2.0 Content-Type: text/x-patch; name=0001-Patch-The-comparison-in-a-compare-exchange-should-no.patch Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0001-Patch-The-comparison-in-a-compare-exchange-should-no.patch" Content-length: 610 diff --git a/gcc/builtins.c b/gcc/builtins.c index ec31e0e..9f9b735 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -5476,7 +5476,8 @@ expand_builtin_atomic_compare_exchange (machine_mode = mode, tree exp, the normal case where EXPECT is totally private, i.e. a register. At which point the store can be unconditional. */ label =3D gen_label_rtx (); - emit_cmp_and_jump_insns (target, const0_rtx, NE, NULL, VOIDmode, 1, labe= l); + emit_cmp_and_jump_insns (target, const0_rtx, NE, NULL, + GET_MODE (target), 1, label); emit_move_insn (expect, oldval); emit_label (label); =20 --------------2.2.0--