From patchwork Fri Nov 30 20:33:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Edelsohn X-Patchwork-Id: 1006178 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-491396-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="pSBiCBvc"; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="dwYN3BUQ"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4365hz3NRQz9s9G for ; Sat, 1 Dec 2018 07:34:26 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:cc:content-type; q=dns; s=default; b=F2QVY8fyaFwHPXDmKKm4biBKd6h76zXW1B3zQ1zAMvH bwOkJXEXt5SRbTOjkCzf17GsIysFU3aLEITEZm4NR5T44/Ot/rRg7O/AbJx9XdOq VbER9oh1ysPRhCYfLgSQd69r0GkJBYezyd/ASJSiA4XipfgoYMgMmIrdao5oiJ8U = DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:cc:content-type; s=default; bh=ofEW5bo4LspX0ElUYU/Unao0jJs=; b=pSBiCBvc53ffXc4V0 6tsaYWlrk7Ik4gTlBcgLo95/0oJk/0gCjgz1cNixRRiDT5DueMq54YRWeJbIu4Bq pWiYg2SJSWjWzL7E0LkaA9ruXGa3XWAhvQlAI8eKjKCuG7rq93h8iJfNJwewZJ67 uUYNWG5FGBffbAKaYe3R9MBH3s= Received: (qmail 21227 invoked by alias); 30 Nov 2018 20:34:18 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 21215 invoked by uid 89); 30 Nov 2018 20:34:17 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-11.9 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=elfv1, ELFv1, padded, commonly X-HELO: mail-wm1-f68.google.com Received: from mail-wm1-f68.google.com (HELO mail-wm1-f68.google.com) (209.85.128.68) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 30 Nov 2018 20:34:15 +0000 Received: by mail-wm1-f68.google.com with SMTP id y185so2444584wmd.1 for ; Fri, 30 Nov 2018 12:34:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to:cc; bh=xEDqAW/jhWjDNLJ+wkMl/GdtyJeFotPqVtElb3sfDOg=; b=dwYN3BUQ2R1bMYP6Px7O4wdVWpjes8Jws8MxEkgf+snCvpX9KbQ4WOO27Gemg1bqE3 SH7lXQAHGDNII54Pzm88OovP0Mqcv25lt78YEaMMXGsHqIOO0cQatOLB6GMO4lj1i1nA rFWq9S/VyB2BUwbM9OWv9fhoNeCDi2uoz/K/o7Kc8PAPwIgQ+J00Ja5fhnBmPRD6Qz7H Pvmry8YWWgxkNtHiqrqWlrvcom9nKpUhrcjev4xsw5Vsfdhz+zCPkF/alyHos1IzNK/c I4eJa2p1XJwfCElBCSFZtakA0jQ+NB3h2qYUpzVM6+X+R7tig0nx8G68uRYMRC+iQXho O9hQ== MIME-Version: 1.0 From: David Edelsohn Date: Fri, 30 Nov 2018 15:33:58 -0500 Message-ID: Subject: [PATCH,RFC] PR target/61976 PowerPC & AIX parameter passing To: Segher Boessenkool , Ulrich Weigand , Jeffrey Law , Jakub Jelinek Cc: GCC Patches This patch corrects the manner in which single element structures are passed. The implementation always has been wrong and did not match the AIX ABI. The AIX ABI specifies that aggregates are passed by values in GPRs, but GCC passes small floating point aggregates in FPRs. The PPC64 BE ELFv1 Linux ABI was updated in the past to match the behavior of GCC. For AIX, the implementation can produce wrong code for the case of a single precision floating point value (SFmode) argument in 64 bit mode. The rs6000 backend parameter passing code chose the location for arguments based on the MODE of the argument. For small aggregates, GCC packs the aggregate into a scalar mode and the function arg machinery is presented with an argument mode of the scalar mode, as opposed to BLKmode. On AIX, this meant that a single element floating point aggregate (float or double) is represented as SFmode or DFmode. The current rs6000 function arg machinery passes the arguments in FPRs. On AIX, argument are padded upwards in the register, as if the arguments are strings, not numerical values. In 64 bit mode, GCC dutifully shifts a 32 bit SFmode value so that it is loaded into the upper 32 bits of the FPR. Power FPRs always are 64 bit double precision format, regardless of the precision, so the value loaded is garbage, in addition to being passed in the wrong location. In 32 bit mode (still the default for AIX), GCC didn't try to shift the value, so it accidentally worked -- self consistently passing the value in an FPR that GCC interpreted as word mode size. This patch adds a test for the argument TYPE to override the floating point argument passing for aggregates only for AIX. Yes, this will break the ABI for GCC on AIX. GCC was not following the AIX ABI. No one really noticed. It only produced wrong code in 64 bit mode. Single element aggregates are rare. The change sucks, but it doesn't make sense to have GCC produce code that is incompatible with the AIX ABI. I am using AGGREGATE_TYPE_P() to test the type. I believe that macro captures all GCC cases of interest. Please let me know if this seems like the wrong choice. The macro includes ARRAY_TYPE, but arrays commonly are passed by reference or pointer, not by value, so I don't believe that this will affect single element vectors, but please correct me if I'm wrong. Another option is RECORD_OR_UNION_TYPE_P(). I believe that this change will correct GCC's conformance with the AIX ABI. I realize that most people don't know enough or care enough about AIX and the ABI to determine if the conformance is correct. I am interested in any feedback about the mechanism (AGGREGATE_TYPE_P) used to select the behavior. Bootstrapped on powerpc-ibm-aix7.2.0.0 Thanks, David * config/rs6000/rs6000.c (rs6000_function_arg): Don't pass aggregates in FPRs on AIX. (rs6000_arg_partial_bytes): Same. Index: rs6000.c =================================================================== --- rs6000.c (revision 266671) +++ rs6000.c (working copy) @@ -11989,7 +11989,8 @@ rs6000_function_arg (cumulative_args_t cum_v, mach if (elt_mode == TDmode && (cum->fregno % 2) == 1) cum->fregno++; - if (USE_FP_FOR_ARG_P (cum, elt_mode)) + if (USE_FP_FOR_ARG_P (cum, elt_mode) + && !(TARGET_AIX && AGGREGATE_TYPE_P (type))) { rtx rvec[GP_ARG_NUM_REG + AGGR_ARG_NUM_REG + 1]; rtx r, off; @@ -12125,7 +12126,8 @@ rs6000_arg_partial_bytes (cumulative_args_t cum_v, align_words = rs6000_parm_start (mode, type, cum->words); - if (USE_FP_FOR_ARG_P (cum, elt_mode)) + if (USE_FP_FOR_ARG_P (cum, elt_mode) + && !(TARGET_AIX && AGGREGATE_TYPE_P (type))) { unsigned long n_fpreg = (GET_MODE_SIZE (elt_mode) + 7) >> 3;