From patchwork Thu Dec 12 23:50:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 1208905 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-515837-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="PW7qByLe"; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="aQE3XGCB"; 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 47YrFH5SrFz9sPL for ; Fri, 13 Dec 2019 10:52:13 +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:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type:content-transfer-encoding; q=dns; s=default; b=hRz hvBv0WOQ1bI4YnfXDTbo8NgVFGuaW2VvUWSV//6xX1dJhF3qT+ZtpoK8nbXZCiql /FWk5dIO6QIxCP2LnPk7KB2+LnQ0iDzLolFhAvlXFWNlGotpjm7rzPIF3hYcon3b yMtZpOzb6lEJ4zfc5+ie7tsPfIWz0c8C3KqUJ16U= 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:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type:content-transfer-encoding; s=default; bh=yTLIKCyuw IJjYiVoo7t9pDqzqEY=; b=PW7qByLeVHZ/RgTxMi291tPDKf8pZr4KnkHg1ftCu 2Unp9aSHjFQh071ho/3AwDsubUCJTAx2jaTp59Ua/iCdowDX+FW8dPNcPDfr0xAn Xyzh0hRajVihtZmctDNcpSd9rK5s48c3noo8V8PAezjPQ1upPcCp7cL36OpanMw0 0k= Received: (qmail 105408 invoked by alias); 12 Dec 2019 23:50:56 -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 105359 invoked by uid 89); 12 Dec 2019 23:50:56 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-7.8 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3 autolearn=ham version=3.3.1 spammy=vf, v.f, uf, ub X-HELO: us-smtp-1.mimecast.com Received: from us-smtp-delivery-1.mimecast.com (HELO us-smtp-1.mimecast.com) (207.211.31.120) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 12 Dec 2019 23:50:52 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1576194650; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=y2QxoZKyc0lL2fXnKH4Mq2dS7K21FcdDud4QhrFLTWQ=; b=aQE3XGCBwWYWn0zP22t4FWrCXRAAsfmoAA9YwT6yImiC+PffCFFKZRn4/0p38qGPggzvl/ h1VbXpnPE5hWYmpdvb8N2LLmlx8JQChDznTwuoOP5qCE9jWzhWM/IDayfPWvIp5Z1gmv7B N5IkqameC8Aoeyc7q6kfKIq4ENSkG1s= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-403-jKYnlw1mPHejT9YjYyMSkQ-1; Thu, 12 Dec 2019 18:50:47 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 51812800D41; Thu, 12 Dec 2019 23:50:46 +0000 (UTC) Received: from tucnak.zalov.cz (ovpn-117-59.ams2.redhat.com [10.36.117.59]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8025410013A1; Thu, 12 Dec 2019 23:50:45 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id xBCNogO8029533; Fri, 13 Dec 2019 00:50:43 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id xBCNodpl029532; Fri, 13 Dec 2019 00:50:39 +0100 Date: Fri, 13 Dec 2019 00:50:39 +0100 From: Jakub Jelinek To: Uros Bizjak , Jan Hubicka , Michael Matz Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix x86_64 va_arg (ap, __int128) handling (PR target/92904) Message-ID: <20191212235039.GN10088@tucnak> Reply-To: Jakub Jelinek MIME-Version: 1.0 User-Agent: Mutt/1.11.3 (2019-02-01) X-Mimecast-Spam-Score: 0 Content-Disposition: inline X-IsSubscribed: yes Hi! As the following testcase shows, for va_arg (ap, __int128) or va_arg (ap, X) where X is __attribute__((aligned (16))) 16 byte struct containing just integral fields we sometimes emit incorrect read. While on the stack (i.e. the overflow area) both of these are 16-byte aligned, when __int128 or 16-byte aligned e.g. { long a, b; } struct are passed in registers, there is no alignment of it being only passed in even registers or something similar (correct, the ABI says that), but in the end this means that when we spill those GPRs into the gpr save area, the __int128 or aligned struct might be only 8-byte aligned there rather than 16-byte aligned. In the testcase, e.g. for f1 that isn't a problem, we just load the two registers separately as 64-bit loads, but in f4 or f6 as it is a copy from memory to memory, we actually optimize it using an aligned SSE load into an SSE register and store from there back to memory (again, aligned SSE load, that one is correct). The current va_arg expanded code just computes the address from which the __int128 etc. should be loaded, in two different branches and the load is then done in the joiner bb. So, what we could do is either move the loads from the joiner bb into the two predecessors of that bb, have the one for the case of read from gpr save area use 8-byte only aligned load and the one reading from overflow area with 16-byte alignment, but I'd say that would result in unnecessarily longer sequence, or we can as the patch just lower the alignment of the MEM_REF in the joiner bb, which will for the cases we used vmovdqa etc. just use vmovdqu instead, but will not grow code size and on contemporary CPUs if the address is actually aligned, it shouldn't be really slower. In most cases the __int128 is used anyway directly and in those cases likely will be loaded into two GRPs. The patch does this only for the needed_intregs case and !need_temp, when need_temp, this kind of problem doesn't exist, the value is copied either using memcpy or just 64-bit loads + stores into the aligned temporary, and for needed_sseregs the slots in the fp save area are 16-byte aligned already, and 32-byte aligned structures just would have 32-byte size and thus would be passed in memory for ... args, no matter if they contain __mm256 or __mm512 or something else. Bootstrapped/regtested on x86_64-linux and i686-linux and after a while release branches? 2019-12-12 Jakub Jelinek PR target/92904 * config/i386/i386.c (ix86_gimplify_va_arg): If need_intregs and not need_temp, decrease alignment of the read because the GPR save area only guarantees 8-byte alignment. * gcc.c-torture/execute/pr92904.c: New test. Jakub --- gcc/config/i386/i386.c.jj 2019-12-10 10:01:08.384171578 +0100 +++ gcc/config/i386/i386.c 2019-12-12 13:57:38.584461843 +0100 @@ -4277,6 +4277,7 @@ ix86_gimplify_va_arg (tree valist, tree tree ptrtype; machine_mode nat_mode; unsigned int arg_boundary; + unsigned int type_align; /* Only 64bit target needs something special. */ if (is_va_list_char_pointer (TREE_TYPE (valist))) @@ -4334,6 +4335,7 @@ ix86_gimplify_va_arg (tree valist, tree /* Pull the value out of the saved registers. */ addr = create_tmp_var (ptr_type_node, "addr"); + type_align = TYPE_ALIGN (type); if (container) { @@ -4504,6 +4506,9 @@ ix86_gimplify_va_arg (tree valist, tree t = build2 (PLUS_EXPR, TREE_TYPE (gpr), gpr, build_int_cst (TREE_TYPE (gpr), needed_intregs * 8)); gimplify_assign (gpr, t, pre_p); + /* The GPR save area guarantees only 8-byte alignment. */ + if (!need_temp) + type_align = MIN (type_align, 64); } if (needed_sseregs) @@ -4548,6 +4556,7 @@ ix86_gimplify_va_arg (tree valist, tree if (container) gimple_seq_add_stmt (pre_p, gimple_build_label (lab_over)); + type = build_aligned_type (type, type_align); ptrtype = build_pointer_type_for_mode (type, ptr_mode, true); addr = fold_convert (ptrtype, addr); --- gcc/testsuite/gcc.c-torture/execute/pr92904.c.jj 2019-12-12 15:04:59.203302591 +0100 +++ gcc/testsuite/gcc.c-torture/execute/pr92904.c 2019-12-12 15:08:05.190449143 +0100 @@ -0,0 +1,395 @@ +/* PR target/92904 */ + +#include + +struct S { long long a, b; }; +struct __attribute__((aligned (16))) T { long long a, b; }; +struct U { double a, b, c, d; }; +struct __attribute__((aligned (32))) V { double a, b, c, d; }; +struct W { double a; long long b; }; +struct __attribute__((aligned (16))) X { double a; long long b; }; +#if __SIZEOF_INT128__ == 2 * __SIZEOF_LONG_LONG__ +__int128 b; +#endif +struct S c; +struct T d; +struct U e; +struct V f; +struct W g; +struct X h; + +#if __SIZEOF_INT128__ == 2 * __SIZEOF_LONG_LONG__ +__attribute__((noipa)) __int128 +f1 (int x, ...) +{ + __int128 r; + va_list ap; + va_start (ap, x); + while (x--) + va_arg (ap, int); + r = va_arg (ap, __int128); + va_end (ap); + return r; +} +#endif + +__attribute__((noipa)) struct S +f2 (int x, ...) +{ + struct S r; + va_list ap; + va_start (ap, x); + while (x--) + va_arg (ap, int); + r = va_arg (ap, struct S); + va_end (ap); + return r; +} + +__attribute__((noipa)) struct T +f3 (int x, ...) +{ + struct T r; + va_list ap; + va_start (ap, x); + while (x--) + va_arg (ap, int); + r = va_arg (ap, struct T); + va_end (ap); + return r; +} + +#if __SIZEOF_INT128__ == 2 * __SIZEOF_LONG_LONG__ +__attribute__((noipa)) void +f4 (int x, ...) +{ + va_list ap; + va_start (ap, x); + while (x--) + va_arg (ap, int); + b = va_arg (ap, __int128); + va_end (ap); +} +#endif + +__attribute__((noipa)) void +f5 (int x, ...) +{ + va_list ap; + va_start (ap, x); + while (x--) + va_arg (ap, int); + c = va_arg (ap, struct S); + va_end (ap); +} + +__attribute__((noipa)) void +f6 (int x, ...) +{ + va_list ap; + va_start (ap, x); + while (x--) + va_arg (ap, int); + d = va_arg (ap, struct T); + va_end (ap); +} + +__attribute__((noipa)) struct U +f7 (int x, ...) +{ + struct U r; + va_list ap; + va_start (ap, x); + while (x--) + va_arg (ap, double); + r = va_arg (ap, struct U); + va_end (ap); + return r; +} + +__attribute__((noipa)) struct V +f8 (int x, ...) +{ + struct V r; + va_list ap; + va_start (ap, x); + while (x--) + va_arg (ap, double); + r = va_arg (ap, struct V); + va_end (ap); + return r; +} + +__attribute__((noipa)) void +f9 (int x, ...) +{ + va_list ap; + va_start (ap, x); + while (x--) + va_arg (ap, double); + e = va_arg (ap, struct U); + va_end (ap); +} + +__attribute__((noipa)) void +f10 (int x, ...) +{ + va_list ap; + va_start (ap, x); + while (x--) + va_arg (ap, double); + f = va_arg (ap, struct V); + va_end (ap); +} + +__attribute__((noipa)) struct W +f11 (int x, ...) +{ + struct W r; + va_list ap; + va_start (ap, x); + while (x--) + { + va_arg (ap, int); + va_arg (ap, double); + } + r = va_arg (ap, struct W); + va_end (ap); + return r; +} + +__attribute__((noipa)) struct X +f12 (int x, ...) +{ + struct X r; + va_list ap; + va_start (ap, x); + while (x--) + { + va_arg (ap, int); + va_arg (ap, double); + } + r = va_arg (ap, struct X); + va_end (ap); + return r; +} + +__attribute__((noipa)) void +f13 (int x, ...) +{ + va_list ap; + va_start (ap, x); + while (x--) + { + va_arg (ap, int); + va_arg (ap, double); + } + g = va_arg (ap, struct W); + va_end (ap); +} + +__attribute__((noipa)) void +f14 (int x, ...) +{ + va_list ap; + va_start (ap, x); + while (x--) + { + va_arg (ap, int); + va_arg (ap, double); + } + h = va_arg (ap, struct X); + va_end (ap); +} + +int +main () +{ + union Y { +#if __SIZEOF_INT128__ == 2 * __SIZEOF_LONG_LONG__ + __int128 b; +#endif + struct S c; + struct T d; + struct U e; + struct V f; + struct W g; + struct X h; + } u, v; + u.c.a = 0x5555555555555555ULL; + u.c.b = 0xaaaaaaaaaaaaaaaaULL; +#define C(x) \ + do { \ + if (u.c.a != x.c.a || u.c.b != x.c.b) __builtin_abort (); \ + u.c.a++; \ + u.c.b--; \ + } while (0) +#if __SIZEOF_INT128__ == 2 * __SIZEOF_LONG_LONG__ + v.b = f1 (0, u.b); C (v); + v.b = f1 (1, 0, u.b); C (v); + v.b = f1 (2, 0, 0, u.b); C (v); + v.b = f1 (3, 0, 0, 0, u.b); C (v); + v.b = f1 (4, 0, 0, 0, 0, u.b); C (v); + v.b = f1 (5, 0, 0, 0, 0, 0, u.b); C (v); + v.b = f1 (6, 0, 0, 0, 0, 0, 0, u.b); C (v); + v.b = f1 (7, 0, 0, 0, 0, 0, 0, 0, u.b); C (v); + v.b = f1 (8, 0, 0, 0, 0, 0, 0, 0, 0, u.b); C (v); + v.b = f1 (9, 0, 0, 0, 0, 0, 0, 0, 0, 0, u.b); C (v); +#endif + v.c = f2 (0, u.c); C (v); + v.c = f2 (1, 0, u.c); C (v); + v.c = f2 (2, 0, 0, u.c); C (v); + v.c = f2 (3, 0, 0, 0, u.c); C (v); + v.c = f2 (4, 0, 0, 0, 0, u.c); C (v); + v.c = f2 (5, 0, 0, 0, 0, 0, u.c); C (v); + v.c = f2 (6, 0, 0, 0, 0, 0, 0, u.c); C (v); + v.c = f2 (7, 0, 0, 0, 0, 0, 0, 0, u.c); C (v); + v.c = f2 (8, 0, 0, 0, 0, 0, 0, 0, 0, u.c); C (v); + v.c = f2 (9, 0, 0, 0, 0, 0, 0, 0, 0, 0, u.c); C (v); + v.d = f3 (0, u.d); C (v); + v.d = f3 (1, 0, u.d); C (v); + v.d = f3 (2, 0, 0, u.d); C (v); + v.d = f3 (3, 0, 0, 0, u.d); C (v); + v.d = f3 (4, 0, 0, 0, 0, u.d); C (v); + v.d = f3 (5, 0, 0, 0, 0, 0, u.d); C (v); + v.d = f3 (6, 0, 0, 0, 0, 0, 0, u.d); C (v); + v.d = f3 (7, 0, 0, 0, 0, 0, 0, 0, u.d); C (v); + v.d = f3 (8, 0, 0, 0, 0, 0, 0, 0, 0, u.d); C (v); + v.d = f3 (9, 0, 0, 0, 0, 0, 0, 0, 0, 0, u.d); C (v); +#if __SIZEOF_INT128__ == 2 * __SIZEOF_LONG_LONG__ + f4 (0, u.b); v.b = b; C (v); + f4 (1, 0, u.b); v.b = b; C (v); + f4 (2, 0, 0, u.b); v.b = b; C (v); + f4 (3, 0, 0, 0, u.b); v.b = b; C (v); + f4 (4, 0, 0, 0, 0, u.b); v.b = b; C (v); + f4 (5, 0, 0, 0, 0, 0, u.b); v.b = b; C (v); + f4 (6, 0, 0, 0, 0, 0, 0, u.b); v.b = b; C (v); + f4 (7, 0, 0, 0, 0, 0, 0, 0, u.b); v.b = b; C (v); + f4 (8, 0, 0, 0, 0, 0, 0, 0, 0, u.b); v.b = b; C (v); + f4 (9, 0, 0, 0, 0, 0, 0, 0, 0, 0, u.b); v.b = b; C (v); +#endif + f5 (0, u.c); v.c = c; C (v); + f5 (1, 0, u.c); v.c = c; C (v); + f5 (2, 0, 0, u.c); v.c = c; C (v); + f5 (3, 0, 0, 0, u.c); v.c = c; C (v); + f5 (4, 0, 0, 0, 0, u.c); v.c = c; C (v); + f5 (5, 0, 0, 0, 0, 0, u.c); v.c = c; C (v); + f5 (6, 0, 0, 0, 0, 0, 0, u.c); v.c = c; C (v); + f5 (7, 0, 0, 0, 0, 0, 0, 0, u.c); v.c = c; C (v); + f5 (8, 0, 0, 0, 0, 0, 0, 0, 0, u.c); v.c = c; C (v); + f5 (9, 0, 0, 0, 0, 0, 0, 0, 0, 0, u.c); v.c = c; C (v); + f6 (0, u.d); v.d = d; C (v); + f6 (1, 0, u.d); v.d = d; C (v); + f6 (2, 0, 0, u.d); v.d = d; C (v); + f6 (3, 0, 0, 0, u.d); v.d = d; C (v); + f6 (4, 0, 0, 0, 0, u.d); v.d = d; C (v); + f6 (5, 0, 0, 0, 0, 0, u.d); v.d = d; C (v); + f6 (6, 0, 0, 0, 0, 0, 0, u.d); v.d = d; C (v); + f6 (7, 0, 0, 0, 0, 0, 0, 0, u.d); v.d = d; C (v); + f6 (8, 0, 0, 0, 0, 0, 0, 0, 0, u.d); v.d = d; C (v); + f6 (9, 0, 0, 0, 0, 0, 0, 0, 0, 0, u.d); v.d = d; C (v); + u.e.a = 1.25; + u.e.b = 2.75; + u.e.c = -3.5; + u.e.d = -2.0; +#undef C +#define C(x) \ + do { \ + if (u.e.a != x.e.a || u.e.b != x.e.b \ + || u.e.c != x.e.c || u.e.d != x.e.d) __builtin_abort ();\ + u.e.a++; \ + u.e.b--; \ + u.e.c++; \ + u.e.d--; \ + } while (0) + v.e = f7 (0, u.e); C (v); + v.e = f7 (1, 0.0, u.e); C (v); + v.e = f7 (2, 0.0, 0.0, u.e); C (v); + v.e = f7 (3, 0.0, 0.0, 0.0, u.e); C (v); + v.e = f7 (4, 0.0, 0.0, 0.0, 0.0, u.e); C (v); + v.e = f7 (5, 0.0, 0.0, 0.0, 0.0, 0.0, u.e); C (v); + v.e = f7 (6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, u.e); C (v); + v.e = f7 (7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, u.e); C (v); + v.e = f7 (8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, u.e); C (v); + v.e = f7 (9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, u.e); C (v); + v.f = f8 (0, u.f); C (v); + v.f = f8 (1, 0.0, u.f); C (v); + v.f = f8 (2, 0.0, 0.0, u.f); C (v); + v.f = f8 (3, 0.0, 0.0, 0.0, u.f); C (v); + v.f = f8 (4, 0.0, 0.0, 0.0, 0.0, u.f); C (v); + v.f = f8 (5, 0.0, 0.0, 0.0, 0.0, 0.0, u.f); C (v); + v.f = f8 (6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, u.f); C (v); + v.f = f8 (7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, u.f); C (v); + v.f = f8 (8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, u.f); C (v); + v.f = f8 (9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, u.f); C (v); + f9 (0, u.e); v.e = e; C (v); + f9 (1, 0.0, u.e); v.e = e; C (v); + f9 (2, 0.0, 0.0, u.e); v.e = e; C (v); + f9 (3, 0.0, 0.0, 0.0, u.e); v.e = e; C (v); + f9 (4, 0.0, 0.0, 0.0, 0.0, u.e); v.e = e; C (v); + f9 (5, 0.0, 0.0, 0.0, 0.0, 0.0, u.e); v.e = e; C (v); + f9 (6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, u.e); v.e = e; C (v); + f9 (7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, u.e); v.e = e; C (v); + f9 (8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, u.e); v.e = e; C (v); + f9 (9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, u.e); v.e = e; C (v); + f10 (0, u.f); v.f = f; C (v); + f10 (1, 0.0, u.f); v.f = f; C (v); + f10 (2, 0.0, 0.0, u.f); v.f = f; C (v); + f10 (3, 0.0, 0.0, 0.0, u.f); v.f = f; C (v); + f10 (4, 0.0, 0.0, 0.0, 0.0, u.f); v.f = f; C (v); + f10 (5, 0.0, 0.0, 0.0, 0.0, 0.0, u.f); v.f = f; C (v); + f10 (6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, u.f); v.f = f; C (v); + f10 (7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, u.f); v.f = f; C (v); + f10 (8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, u.f); v.f = f; C (v); + f10 (9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, u.f); v.f = f; C (v); + u.g.a = 9.5; + u.g.b = 0x5555555555555555ULL; +#undef C +#define C(x) \ + do { \ + if (u.e.a != x.e.a || u.e.b != x.e.b) __builtin_abort (); \ + u.e.a++; \ + u.e.b--; \ + } while (0) + v.g = f11 (0, u.g); C (v); + v.g = f11 (1, 0, 0.0, u.g); C (v); + v.g = f11 (2, 0, 0.0, 0, 0.0, u.g); C (v); + v.g = f11 (3, 0, 0.0, 0, 0.0, 0, 0.0, u.g); C (v); + v.g = f11 (4, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.g); C (v); + v.g = f11 (5, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.g); C (v); + v.g = f11 (6, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.g); C (v); + v.g = f11 (7, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.g); C (v); + v.g = f11 (8, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.g); C (v); + v.g = f11 (9, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.g); C (v); + v.h = f12 (0, u.h); C (v); + v.h = f12 (1, 0, 0.0, u.h); C (v); + v.h = f12 (2, 0, 0.0, 0, 0.0, u.h); C (v); + v.h = f12 (3, 0, 0.0, 0, 0.0, 0, 0.0, u.h); C (v); + v.h = f12 (4, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.h); C (v); + v.h = f12 (5, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.h); C (v); + v.h = f12 (6, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.h); C (v); + v.h = f12 (7, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.h); C (v); + v.h = f12 (8, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.h); C (v); + v.h = f12 (9, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.h); C (v); + f13 (0, u.g); v.g = g; C (v); + f13 (1, 0, 0.0, u.g); v.g = g; C (v); + f13 (2, 0, 0.0, 0, 0.0, u.g); v.g = g; C (v); + f13 (3, 0, 0.0, 0, 0.0, 0, 0.0, u.g); v.g = g; C (v); + f13 (4, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.g); v.g = g; C (v); + f13 (5, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.g); v.g = g; C (v); + f13 (6, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.g); v.g = g; C (v); + f13 (7, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.g); v.g = g; C (v); + f13 (8, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.g); v.g = g; C (v); + f13 (9, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.g); v.g = g; C (v); + f14 (0, u.h); v.h = h; C (v); + f14 (1, 0, 0.0, u.h); v.h = h; C (v); + f14 (2, 0, 0.0, 0, 0.0, u.h); v.h = h; C (v); + f14 (3, 0, 0.0, 0, 0.0, 0, 0.0, u.h); v.h = h; C (v); + f14 (4, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.h); v.h = h; C (v); + f14 (5, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.h); v.h = h; C (v); + f14 (6, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.h); v.h = h; C (v); + f14 (7, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.h); v.h = h; C (v); + f14 (8, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.h); v.h = h; C (v); + f14 (9, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, u.h); v.h = h; C (v); + return 0; +}