From patchwork Tue Aug 4 13:29:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 1340867 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=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=suse.de Received: from sourceware.org (server2.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 ozlabs.org (Postfix) with ESMTPS id 4BLbFP0Dlgz9sRR for ; Tue, 4 Aug 2020 23:29:13 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 14BBC3857C53; Tue, 4 Aug 2020 13:29:11 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by sourceware.org (Postfix) with ESMTPS id B52ED3857C49 for ; Tue, 4 Aug 2020 13:29:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org B52ED3857C49 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=rguenther@suse.de X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 8A41DB5FB for ; Tue, 4 Aug 2020 13:29:22 +0000 (UTC) Date: Tue, 4 Aug 2020 15:29:06 +0200 (CEST) From: Richard Biener To: gcc-patches@gcc.gnu.org Subject: [PATCH] tree-optimization/88240 - stopgap for floating point code-hoisting issues Message-ID: User-Agent: Alpine 2.21 (LSU 202 2017-01-01) MIME-Version: 1.0 X-Spam-Status: No, score=-10.2 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" This adds a stopgap measure to avoid performing code-hoisting on mixed type loads when the load we'd insert in the hoisting position would be a floating point one. This is because certain targets (hello x87) cannot perform floating point loads without possibly altering the bit representation and thus cannot be used in place of integral loads. Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed to trunk sofar. Richard. 2020-08-04 Richard Biener PR tree-optimization/88240 * tree-ssa-sccvn.h (vn_reference_s::punned): New flag. * tree-ssa-sccvn.c (vn_reference_insert): Initialize punned. (vn_reference_insert_pieces): Likewise. (visit_reference_op_call): Likewise. (visit_reference_op_load): Track whether a ref was punned. * tree-ssa-pre.c (do_hoist_insertion): Refuse to perform hoist insertion on punned floating point loads. * gcc.target/i386/pr88240.c: New testcase. --- gcc/testsuite/gcc.target/i386/pr88240.c | 26 +++++++++++++++++++++++++ gcc/tree-ssa-pre.c | 10 ++++++++++ gcc/tree-ssa-sccvn.c | 13 ++++++++++++- gcc/tree-ssa-sccvn.h | 1 + 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr88240.c diff --git a/gcc/testsuite/gcc.target/i386/pr88240.c b/gcc/testsuite/gcc.target/i386/pr88240.c new file mode 100644 index 00000000000..5ee02f3193c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr88240.c @@ -0,0 +1,26 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -mno-sse" } */ + +int flag; +union { double f; unsigned long long i; } u; +void __attribute__((noinline)) +init () +{ + flag = 1; + u.i = 18442936822990639076ULL; +} +unsigned long long __attribute__((noinline)) +test () +{ + if (flag) + return u.i; + else + return u.f; +} +int main() +{ + init (); + if (test () != 18442936822990639076ULL) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 0c1654f3580..7d67305bf4b 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -3571,6 +3571,16 @@ do_hoist_insertion (basic_block block) continue; } + /* If we end up with a punned expression representation and this + happens to be a float typed one give up - we can't know for + sure whether all paths perform the floating-point load we are + about to insert and on some targets this can cause correctness + issues. See PR88240. */ + if (expr->kind == REFERENCE + && PRE_EXPR_REFERENCE (expr)->punned + && FLOAT_TYPE_P (get_expr_type (expr))) + continue; + /* OK, we should hoist this value. Perform the transformation. */ pre_stats.hoist_insert++; if (dump_file && (dump_flags & TDF_DETAILS)) diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 2e925a1afbf..934ae40670d 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -3601,6 +3601,7 @@ vn_reference_insert (tree op, tree result, tree vuse, tree vdef) vr1->vuse = vuse_ssa_val (vuse); vr1->operands = valueize_shared_reference_ops_from_ref (op, &tem).copy (); vr1->type = TREE_TYPE (op); + vr1->punned = 0; ao_ref op_ref; ao_ref_init (&op_ref, op); vr1->set = ao_ref_alias_set (&op_ref); @@ -3660,6 +3661,7 @@ vn_reference_insert_pieces (tree vuse, alias_set_type set, vr1->vuse = vuse_ssa_val (vuse); vr1->operands = valueize_refs (operands); vr1->type = type; + vr1->punned = 0; vr1->set = set; vr1->base_set = base_set; vr1->hashcode = vn_reference_compute_hash (vr1); @@ -4892,6 +4894,7 @@ visit_reference_op_call (tree lhs, gcall *stmt) them here. */ vr2->operands = vr1.operands.copy (); vr2->type = vr1.type; + vr2->punned = vr1.punned; vr2->set = vr1.set; vr2->base_set = vr1.base_set; vr2->hashcode = vr1.hashcode; @@ -4918,10 +4921,11 @@ visit_reference_op_load (tree lhs, tree op, gimple *stmt) bool changed = false; tree last_vuse; tree result; + vn_reference_t res; last_vuse = gimple_vuse (stmt); result = vn_reference_lookup (op, gimple_vuse (stmt), - default_vn_walk_kind, NULL, true, &last_vuse); + default_vn_walk_kind, &res, true, &last_vuse); /* We handle type-punning through unions by value-numbering based on offset and size of the access. Be prepared to handle a @@ -4943,6 +4947,13 @@ visit_reference_op_load (tree lhs, tree op, gimple *stmt) gimple_match_op res_op (gimple_match_cond::UNCOND, VIEW_CONVERT_EXPR, TREE_TYPE (op), result); result = vn_nary_build_or_lookup (&res_op); + if (result + && TREE_CODE (result) == SSA_NAME + && VN_INFO (result)->needs_insertion) + /* Track whether this is the canonical expression for different + typed loads. We use that as a stopgap measure for code + hoisting when dealing with floating point loads. */ + res->punned = true; } /* When building the conversion fails avoid inserting the reference diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h index d68e7c0ffa3..48701c32544 100644 --- a/gcc/tree-ssa-sccvn.h +++ b/gcc/tree-ssa-sccvn.h @@ -145,6 +145,7 @@ typedef struct vn_reference_s alias_set_type set; alias_set_type base_set; tree type; + unsigned punned : 1; vec operands; tree result; tree result_vdef;