From patchwork Tue Feb 15 09:58:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 1593015 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=Q6I8D9dg; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Jyc4L2GQWz9s07 for ; Tue, 15 Feb 2022 20:58:56 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 16F913858031 for ; Tue, 15 Feb 2022 09:58:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 16F913858031 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1644919134; bh=isXxFx+IMXBNn9QExljFngvMJuZ3vsehBYOHww1ETj4=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=Q6I8D9dgZllBgCVmrTmucY2tHffG51KFZfzIe4b+bhCA/Sp29XCT/fUSLjtXko3IT ACNzyY+Rj0u1pq2lGR6cJDszWP3iwqiWgfUTCBJohb+zGjWK0CVh6ucNzxJWY66L4G aUXgF/xLJmw+oR4cjtRC4ICz3oBlvmbbRNs2m2TQ= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 21ADF3858D20 for ; Tue, 15 Feb 2022 09:58:13 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 21ADF3858D20 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-147-JU1hC6CWPZ6Ce3FSrR1AMA-1; Tue, 15 Feb 2022 04:58:10 -0500 X-MC-Unique: JU1hC6CWPZ6Ce3FSrR1AMA-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7307E1006AA0; Tue, 15 Feb 2022 09:58:09 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.192.125]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E6CBB6C336; Tue, 15 Feb 2022 09:58:08 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.16.1/8.16.1) with ESMTPS id 21F9w5Ox1943516 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 15 Feb 2022 10:58:06 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.16.1/8.16.1/Submit) id 21F9w4gK1943515; Tue, 15 Feb 2022 10:58:04 +0100 Date: Tue, 15 Feb 2022 10:58:04 +0100 To: Richard Biener , Qing Zhao Subject: [PATCH] fold, simplify-rtx: Punt on non-representable floating point constants [PR104522] Message-ID: <20220215095804.GL2646553@tucnak> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-5.2 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jakub Jelinek via Gcc-patches From: Jakub Jelinek Reply-To: Jakub Jelinek Cc: gcc-patches@gcc.gnu.org Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" Hi! For IBM double double I've added in PR95450 and PR99648 verification that when we at the tree/GIMPLE or RTL level interpret target bytes as a REAL_CST or CONST_DOUBLE constant, we try to encode it back to target bytes and verify it is the same. This is because our real.c support isn't able to represent all valid values of IBM double double which has variable precision. In PR104522, it has been noted that we have similar problem with the Intel/Motorola extended XFmode formats, our internal representation isn't able to record pseudo denormals, pseudo infinities, pseudo NaNs and unnormal values. So, the following patch is an attempt to extend that verification to all floats. Unfortunately, it wasn't that straightforward, because the __builtin_clear_padding code exactly for the XFmode long doubles needs to discover what bits are padding and does that by interpreting memory of all 1s. That is actually a valid supported value, a qNaN with negative sign with all mantissa bits set, but the verification includes also the padding bits (exactly what __builtin_clear_padding wants to figure out) and so fails the comparison check and so we ICE. The patch fixes that case by moving that verification from native_interpret_real to its caller, so that clear_padding_type can call native_interpret_real and avoid that extra check. With this, the only thing that regresses in the testsuite is +FAIL: gcc.target/i386/auto-init-4.c scan-assembler-times long\\t-16843010 5 because it decides to use a pattern that has non-zero bits in the padding bits of the long double, so the simplify-rtx.cc change prevents folding a SUBREG into a constant. We emit (the testcase is -O0 but we emit worse code at all opt levels) something like: movabsq $-72340172838076674, %rax movabsq $-72340172838076674, %rdx movq %rax, -48(%rbp) movq %rdx, -40(%rbp) fldt -48(%rbp) fstpt -32(%rbp) instead of fldt .LC2(%rip) fstpt -32(%rbp) ... .LC2: .long -16843010 .long -16843010 .long 65278 .long 0 Note, neither of those sequences actually stores the padding bits, fstpt simply doesn't touch them. For vars with clear_padding_real_needs_padding_p types that are allocated to memory at expansion time, I'd say much better would be to do the stores using integral modes rather than XFmode, so do that: movabsq $-72340172838076674, %rax movq %rax, -32(%rbp) movq %rax, -24(%rbp) directly. That is the only way to ensure the padding bits are initialized (or expand __builtin_clear_padding, but then you initialize separately the value bits and padding bits). Bootstrapped/regtested on x86_64-linux and i686-linux, though as mentioned above, the gcc.target/i386/auto-init-4.c case is unresolved. 2022-02-15 Jakub Jelinek PR middle-end/104522 * fold-const.h (native_interpret_real): Declare. * fold-const.cc (native_interpret_real): No longer static. Don't perform MODE_COMPOSITE_P verification here. (native_interpret_expr) : But perform it here instead for all modes. * gimple-fold.cc (clear_padding_type): Call native_interpret_real instead of native_interpret_expr. * simplify-rtx.cc (simplify_immed_subreg): Perform the native_encode_rtx and comparison verification for all FLOAT_MODE_P modes, not just MODE_COMPOSITE_P. * gcc.dg/pr104522.c: New test. Jakub --- gcc/fold-const.h.jj 2022-02-07 21:26:50.717616208 +0100 +++ gcc/fold-const.h 2022-02-15 01:16:14.509617954 +0100 @@ -36,6 +36,7 @@ extern int native_encode_expr (const_tre extern int native_encode_initializer (tree, unsigned char *, int, int off = -1, unsigned char * = nullptr); extern tree native_interpret_expr (tree, const unsigned char *, int); +extern tree native_interpret_real (tree, const unsigned char *, int); extern bool can_native_interpret_type_p (tree); extern tree native_interpret_aggregate (tree, const unsigned char *, int, int); extern tree find_bitfield_repr_type (int, int); --- gcc/fold-const.cc.jj 2022-02-09 22:15:31.805466094 +0100 +++ gcc/fold-const.cc 2022-02-15 01:36:11.988496438 +0100 @@ -8643,7 +8643,7 @@ native_interpret_fixed (tree type, const the buffer PTR of length LEN as a REAL_CST of type TYPE. If the buffer cannot be interpreted, return NULL_TREE. */ -static tree +tree native_interpret_real (tree type, const unsigned char *ptr, int len) { scalar_float_mode mode = SCALAR_FLOAT_TYPE_MODE (type); @@ -8694,19 +8694,7 @@ native_interpret_real (tree type, const } real_from_target (&r, tmp, mode); - tree ret = build_real (type, r); - if (MODE_COMPOSITE_P (mode)) - { - /* For floating point values in composite modes, punt if this folding - doesn't preserve bit representation. As the mode doesn't have fixed - precision while GCC pretends it does, there could be valid values that - GCC can't really represent accurately. See PR95450. */ - unsigned char buf[24]; - if (native_encode_expr (ret, buf, total_bytes, 0) != total_bytes - || memcmp (ptr, buf, total_bytes) != 0) - ret = NULL_TREE; - } - return ret; + return build_real (type, r); } @@ -8824,7 +8812,23 @@ native_interpret_expr (tree type, const return native_interpret_int (type, ptr, len); case REAL_TYPE: - return native_interpret_real (type, ptr, len); + if (tree ret = native_interpret_real (type, ptr, len)) + { + /* For floating point values in composite modes, punt if this + folding doesn't preserve bit representation. As the mode doesn't + have fixed precision while GCC pretends it does, there could be + valid values that GCC can't really represent accurately. + See PR95450. Even for other modes, e.g. x86 XFmode can have some + bit combinationations which GCC doesn't preserve. */ + unsigned char buf[24]; + scalar_float_mode mode = SCALAR_FLOAT_TYPE_MODE (type); + int total_bytes = GET_MODE_SIZE (mode); + if (native_encode_expr (ret, buf, total_bytes, 0) != total_bytes + || memcmp (ptr, buf, total_bytes) != 0) + return NULL_TREE; + return ret; + } + return NULL_TREE; case FIXED_POINT_TYPE: return native_interpret_fixed (type, ptr, len); --- gcc/gimple-fold.cc.jj 2022-02-11 21:59:57.177698154 +0100 +++ gcc/gimple-fold.cc 2022-02-15 01:21:08.706649224 +0100 @@ -4807,10 +4807,10 @@ clear_padding_type (clear_padding_struct clear_padding_flush (buf, false); if (clear_padding_real_needs_padding_p (type)) { - /* Use native_interpret_expr + native_encode_expr to figure out + /* Use native_interpret_real + native_encode_expr to figure out which bits are padding. */ memset (buf->buf + buf->size, ~0, sz); - tree cst = native_interpret_expr (type, buf->buf + buf->size, sz); + tree cst = native_interpret_real (type, buf->buf + buf->size, sz); gcc_assert (cst && TREE_CODE (cst) == REAL_CST); int len = native_encode_expr (cst, buf->buf + buf->size, sz); gcc_assert (len > 0 && (size_t) len == (size_t) sz); --- gcc/simplify-rtx.cc.jj 2022-01-20 21:24:40.611955521 +0100 +++ gcc/simplify-rtx.cc 2022-02-14 22:14:29.258718212 +0100 @@ -7302,7 +7302,7 @@ simplify_immed_subreg (fixed_size_mode o else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes)) return NULL_RTX; rtx ret = native_decode_rtx (outermode, buffer, 0); - if (ret && MODE_COMPOSITE_P (outermode)) + if (ret && FLOAT_MODE_P (outermode)) { auto_vec buffer2 (buffer_bytes); if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes)) --- gcc/testsuite/gcc.dg/pr104522.c.jj 2022-02-14 22:14:29.258718212 +0100 +++ gcc/testsuite/gcc.dg/pr104522.c 2022-02-14 22:14:29.258718212 +0100 @@ -0,0 +1,14 @@ +/* PR middle-end/104522 */ +/* { dg-do compile } */ +/* { dg-options "-O -fcompare-debug -dP" } */ + +typedef short __attribute__((__vector_size__(16))) V; +long double x; + +void +foo (void) +{ + V t = { 512, 0, 0, 0, 16384 }; + long double u = *(long double *) &t; + x /= u; +}