From patchwork Thu Dec 12 15:16:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 1208558 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-515803-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="gxpKtcV/"; 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 47YcpR1cc3z9sPh for ; Fri, 13 Dec 2019 02:16:45 +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:from :to:cc:subject:date:message-id:mime-version:content-type; q=dns; s=default; b=wHkuS6gCuphl8e4ZEuTd6KMsm86VGi8eLKbt9MGEuagqouDfUz 0xseWEpalNydMEkTVMNk7hQYKt60WP2nwmKjYVWbewpgIF8CZGHFA80cqMFRXPWI RedUiEBwGgz+L2bO29A/PlPzyg9zFjcnPK8Hdcz5N6HLFnH2pMHswJyjU= 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:from :to:cc:subject:date:message-id:mime-version:content-type; s= default; bh=cZoeENmwciqEQp7RBKBcHzqNnwI=; b=gxpKtcV/G8O5+pYf0xyS ZNFSgnnwaAD2yeg/eZ0iQKXh7/I3lX8ZZ936HVwrSQrYzgLgumQBMrulT+PfdJRq t6/LgKlvyfmUjNZ0lSEc3K+0E9IjUWlRtsqBZw5FO9fTpNC75KcwbEmftj2QXtir jzK4Hgg0xiVPgk6bo9GjHYE= Received: (qmail 9745 invoked by alias); 12 Dec 2019 15:16:38 -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 9737 invoked by uid 89); 12 Dec 2019 15:16:38 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-9.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_SHORT, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 spammy=harmless X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.110.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 12 Dec 2019 15:16:35 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 66EA830E; Thu, 12 Dec 2019 07:16:34 -0800 (PST) Received: from localhost (e121540-lin.manchester.arm.com [10.32.98.126]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id CA3633F6CF; Thu, 12 Dec 2019 07:16:33 -0800 (PST) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, jason@redhat.com, nathan@acm.org, richard.sandiford@arm.com Cc: jason@redhat.com, nathan@acm.org Subject: [C++ PATCH] Make same_type_p return false for gnu_vector_type_p differences (PR 92789) Date: Thu, 12 Dec 2019 15:16:32 +0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) MIME-Version: 1.0 X-IsSubscribed: yes As Jason pointed out in the review of the C++ gnu_vector_type_p patch: https://gcc.gnu.org/ml/gcc-patches/2019-12/msg00173.html the real fix for the XFAILs in acle/general-c++/gnu_vectors_*.C is to make same_type_p return false for two types if one is gnu_vector_type_p and the other isn't. This patch does that and fixes the fallout in the way Jason suggested above. I'd said at the time that some of the tests require: /* If the constructor already has the array type, it's been through digest_init, so we shouldn't try to do anything more. */ bool digested = same_type_p (atype, TREE_TYPE (init)); (build_vec_init) to be true for gnu vectors built from non-gnu vectors. I can no longer reproduce that, maybe because my original same_type_p change was bogus or because something in the later sizeless type support made it moot (or something else :-)). This means that sve-sizeless-2.C (the length-specific test) now reports some errors for comparisons and pointer differences that sve-sizeless-1.C (the length-agnostic test) already had. I think requiring a cast is OK for those cases, since there's no reason to mix GNU and non-GNU versions of the same vector in the same object. Even -flax-vector-conversions would require a cast for different vector types here, for both C and C++. same_type_p had: else if (strict == COMPARE_STRUCTURAL) return structural_comptypes (t1, t2, COMPARE_STRICT); else return structural_comptypes (t1, t2, strict); Since structural_comptypes ignored the COMPARE_STRUCTURAL bit of "strict" before the patch, the "else if" was harmless but AFAICT unnecessary. Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install? Richard 2019-12-12 Richard Sandiford gcc/c-family/ PR c++/92789 * c-common.c (vector_targets_convertible_p): Handle types that differ in gnu_vector_type_p but are otherwise identical. gcc/cp/ PR c++/92789 * typeck.c (structural_comptypes): For strict checking, make sure that two vector types agree on gnu_vector_type_p. (comptypes): Pass the original strictness argument to structural_comptypes. (similar_type_p): Use a structural comparision for vectors. gcc/testsuite/ PR c++/92789 * g++.dg/ext/sve-sizeless-2.C (statements): Expect pointer difference and comparisons between GNU and non-GNU types to be rejected. Expect __is_same to be false for such pairs. * g++.target/aarch64/sve/acle/general-c++/gnu_vectors_1.C: Remove XFAILs. * g++.target/aarch64/sve/acle/general-c++/gnu_vectors_2.C: Likewise. Index: gcc/c-family/c-common.c =================================================================== --- gcc/c-family/c-common.c 2019-12-06 10:31:11.286433308 +0000 +++ gcc/c-family/c-common.c 2019-12-12 15:13:55.789913884 +0000 @@ -923,11 +923,18 @@ bool_promoted_to_int_p (tree t) bool vector_targets_convertible_p (const_tree t1, const_tree t2) { - if (VECTOR_TYPE_P (t1) && VECTOR_TYPE_P (t2) - && (TYPE_VECTOR_OPAQUE (t1) || TYPE_VECTOR_OPAQUE (t2)) + if (!VECTOR_TYPE_P (t1) || !VECTOR_TYPE_P (t2)) + return false; + + if ((TYPE_VECTOR_OPAQUE (t1) || TYPE_VECTOR_OPAQUE (t2)) && tree_int_cst_equal (TYPE_SIZE (t1), TYPE_SIZE (t2))) return true; + if (gnu_vector_type_p (t1) != gnu_vector_type_p (t2) + && known_eq (TYPE_VECTOR_SUBPARTS (t1), TYPE_VECTOR_SUBPARTS (t2)) + && lang_hooks.types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2))) + return true; + return false; } Index: gcc/cp/typeck.c =================================================================== --- gcc/cp/typeck.c 2019-12-10 09:17:17.668010318 +0000 +++ gcc/cp/typeck.c 2019-12-12 15:13:55.789913884 +0000 @@ -1429,6 +1429,9 @@ structural_comptypes (tree t1, tree t2, if (maybe_ne (TYPE_VECTOR_SUBPARTS (t1), TYPE_VECTOR_SUBPARTS (t2)) || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))) return false; + if (strict == COMPARE_STRICT + && gnu_vector_type_p (t1) != gnu_vector_type_p (t2)) + return false; break; case TYPE_PACK_EXPANSION: @@ -1526,8 +1529,6 @@ comptypes (tree t1, tree t2, int strict) else return structural_comptypes (t1, t2, strict); } - else if (strict == COMPARE_STRUCTURAL) - return structural_comptypes (t1, t2, COMPARE_STRICT); else return structural_comptypes (t1, t2, strict); } @@ -1556,6 +1557,9 @@ similar_type_p (tree type1, tree type2) if (type1 == error_mark_node || type2 == error_mark_node) return false; + if (type1 == type2) + return true; + /* Informally, two types are similar if, ignoring top-level cv-qualification: * they are the same type; or * they are both pointers, and the pointed-to types are similar; or @@ -1564,8 +1568,18 @@ similar_type_p (tree type1, tree type2) * they are both arrays of the same size or both arrays of unknown bound, and the array element types are similar. */ - if (same_type_ignoring_top_level_qualifiers_p (type1, type2)) - return true; + tree unqual_type1 = cp_build_qualified_type (type1, TYPE_UNQUALIFIED); + tree unqual_type2 = cp_build_qualified_type (type2, TYPE_UNQUALIFIED); + if (VECTOR_TYPE_P (unqual_type1) && VECTOR_TYPE_P (unqual_type2)) + { + if (comptypes (unqual_type1, unqual_type2, COMPARE_STRUCTURAL)) + return true; + } + else + { + if (same_type_p (unqual_type1, unqual_type2)) + return true; + } if ((TYPE_PTR_P (type1) && TYPE_PTR_P (type2)) || (TYPE_PTRDATAMEM_P (type1) && TYPE_PTRDATAMEM_P (type2)) Index: gcc/testsuite/g++.dg/ext/sve-sizeless-2.C =================================================================== --- gcc/testsuite/g++.dg/ext/sve-sizeless-2.C 2019-12-06 18:22:12.084859448 +0000 +++ gcc/testsuite/g++.dg/ext/sve-sizeless-2.C 2019-12-12 15:13:55.793913855 +0000 @@ -197,8 +197,8 @@ statements (int n) sve_sc_ptr -= 0; // { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } sve_sc_ptr -= 1; // { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } sve_sc_ptr - sve_sc_ptr; // { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } - gnu_sc_ptr - sve_sc_ptr; // { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } - sve_sc_ptr - gnu_sc_ptr; // { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } + gnu_sc_ptr - sve_sc_ptr; // { dg-error {invalid operands of types 'int8x32_t\*'[^\n]* and 'svint8_t\*' to binary 'operator-'} } + sve_sc_ptr - gnu_sc_ptr; // { dg-error {invalid operands of types 'svint8_t\*' and 'int8x32_t\*'[^\n]* to binary 'operator-'} } sve_sc1 = sve_sc_ptr[0]; // { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } sve_sc1 = sve_sc_ptr[1]; // { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } @@ -210,18 +210,18 @@ statements (int n) sve_sc_ptr <= &sve_sc1; sve_sc_ptr > &sve_sc1; sve_sc_ptr >= &sve_sc1; - gnu_sc_ptr == sve_sc_ptr; - gnu_sc_ptr != sve_sc_ptr; - gnu_sc_ptr < sve_sc_ptr; - gnu_sc_ptr <= sve_sc_ptr; - gnu_sc_ptr > sve_sc_ptr; - gnu_sc_ptr >= sve_sc_ptr; - sve_sc_ptr == gnu_sc_ptr; - sve_sc_ptr != gnu_sc_ptr; - sve_sc_ptr < gnu_sc_ptr; - sve_sc_ptr <= gnu_sc_ptr; - sve_sc_ptr > gnu_sc_ptr; - sve_sc_ptr >= gnu_sc_ptr; + gnu_sc_ptr == sve_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + gnu_sc_ptr != sve_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + gnu_sc_ptr < sve_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + gnu_sc_ptr <= sve_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + gnu_sc_ptr > sve_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + gnu_sc_ptr >= sve_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + sve_sc_ptr == gnu_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + sve_sc_ptr != gnu_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + sve_sc_ptr < gnu_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + sve_sc_ptr <= gnu_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + sve_sc_ptr > gnu_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + sve_sc_ptr >= gnu_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } // New and delete. @@ -243,8 +243,8 @@ statements (int n) 0 ? 0 : sve_sc1; // { dg-error {different types 'int' and 'svint8_t'} } 0 ? sve_sc1 : sve_sc1; 0 ? sve_sc_ptr : sve_sc_ptr; - 0 ? sve_sc_ptr : gnu_sc_ptr; - 0 ? gnu_sc_ptr : sve_sc_ptr; + 0 ? sve_sc_ptr : gnu_sc_ptr; // { dg-error {conditional expression between distinct pointer types [^\n]*lacks a cast} } + 0 ? gnu_sc_ptr : sve_sc_ptr; // { dg-error {conditional expression between distinct pointer types [^\n]*lacks a cast} } // Function arguments. @@ -321,11 +321,11 @@ statements (int n) { typedef int f[__is_pod (svint8_t) ? 1 : -1]; } { typedef int f[!__is_polymorphic (svint8_t) ? 1 : -1]; } { typedef int f[__is_same_as (svint8_t, svint8_t) ? 1 : -1]; } - { typedef int f[__is_same_as (svint8_t, int8x32_t) ? 1 : -1]; } - { typedef int f[__is_same_as (int8x32_t, svint8_t) ? 1 : -1]; } + { typedef int f[!__is_same_as (svint8_t, int8x32_t) ? 1 : -1]; } + { typedef int f[!__is_same_as (int8x32_t, svint8_t) ? 1 : -1]; } { typedef int f[__is_same_as (svint8_t *, svint8_t *) ? 1 : -1]; } - { typedef int f[__is_same_as (svint8_t *, int8x32_t *) ? 1 : -1]; } - { typedef int f[__is_same_as (int8x32_t *, svint8_t *) ? 1 : -1]; } + { typedef int f[!__is_same_as (svint8_t *, int8x32_t *) ? 1 : -1]; } + { typedef int f[!__is_same_as (int8x32_t *, svint8_t *) ? 1 : -1]; } { typedef int f[!__is_same_as (svint8_t, int) ? 1 : -1]; } { typedef int f[!__is_same_as (svint8_t, svint16_t) ? 1 : -1]; } { typedef int f[__is_trivial (svint8_t) ? 1 : -1]; } Index: gcc/testsuite/g++.target/aarch64/sve/acle/general-c++/gnu_vectors_1.C =================================================================== --- gcc/testsuite/g++.target/aarch64/sve/acle/general-c++/gnu_vectors_1.C 2019-12-04 09:17:59.654022577 +0000 +++ gcc/testsuite/g++.target/aarch64/sve/acle/general-c++/gnu_vectors_1.C 2019-12-12 15:13:55.793913855 +0000 @@ -434,8 +434,8 @@ f (svuint8_t sve_u1, svint8_t sve_s1, // Conditional expressions. uc ? sve_u1 : sve_u1; - uc ? gnu_u1 : sve_u1; // { dg-error {operands to '\?:' have different types 'gnu_uint8_t'[^\n]* and 'svuint8_t'} "" { xfail *-*-* } } - uc ? sve_u1 : gnu_u1; // { dg-error {operands to '\?:' have different types 'svuint8_t' and 'gnu_uint8_t'} "" { xfail *-*-* } } + uc ? gnu_u1 : sve_u1; // { dg-error {operands to '\?:' have different types 'gnu_uint8_t'[^\n]* and 'svuint8_t'} } + uc ? sve_u1 : gnu_u1; // { dg-error {operands to '\?:' have different types 'svuint8_t' and 'gnu_uint8_t'} } uc ? gnu_u1 : gnu_u1; sve_u1 ? sve_u1 : sve_u1; // { dg-error {could not convert 'sve_u1' from 'svuint8_t' to 'bool'} } Index: gcc/testsuite/g++.target/aarch64/sve/acle/general-c++/gnu_vectors_2.C =================================================================== --- gcc/testsuite/g++.target/aarch64/sve/acle/general-c++/gnu_vectors_2.C 2019-12-04 09:17:59.654022577 +0000 +++ gcc/testsuite/g++.target/aarch64/sve/acle/general-c++/gnu_vectors_2.C 2019-12-12 15:13:55.793913855 +0000 @@ -434,8 +434,8 @@ f (svuint8_t sve_u1, svint8_t sve_s1, // Conditional expressions. uc ? sve_u1 : sve_u1; - uc ? gnu_u1 : sve_u1; // { dg-error {operands to '\?:' have different types 'gnu_uint8_t'[^\n]* and 'svuint8_t'} "" { xfail *-*-* } } - uc ? sve_u1 : gnu_u1; // { dg-error {operands to '\?:' have different types 'svuint8_t' and 'gnu_uint8_t'} "" { xfail *-*-* } } + uc ? gnu_u1 : sve_u1; // { dg-error {operands to '\?:' have different types 'gnu_uint8_t'[^\n]* and 'svuint8_t'} } + uc ? sve_u1 : gnu_u1; // { dg-error {operands to '\?:' have different types 'svuint8_t' and 'gnu_uint8_t'} } uc ? gnu_u1 : gnu_u1; sve_u1 ? sve_u1 : sve_u1; // { dg-error {could not convert 'sve_u1' from 'svuint8_t' to 'bool'} }