From patchwork Wed Nov 10 02:14:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sandra Loosemore X-Patchwork-Id: 47346 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 04C743857827 for ; Wed, 10 Nov 2021 02:14:34 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from esa2.mentor.iphmx.com (esa2.mentor.iphmx.com [68.232.141.98]) by sourceware.org (Postfix) with ESMTPS id DFF82385802A for ; Wed, 10 Nov 2021 02:14:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org DFF82385802A Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mentor.com IronPort-SDR: qZzL5AiLAynx0pmiuKqqfneBtWxh9pINRl1KAZnHFWjGtAcD0PHL+pD7enNHvg8LQeV8dF9VGo rnyc71sICaEsW8NNmp3q27Vd9TSrt9kVTtUvkomnJSb/0EbkAuq27k/1x+tS3RtvBaNo457ie7 uco7c3Me3YS+X9cyr15k3+ChtARhGuIKXpNKHDkH7Hf2ICe3O2IJl+/wgfsC4U46ztQH72zfuv SLPtk2Re+Y8dnQy28Wa42pa/tlrDs79UKxiqEPtQZwVeBLPMHSzTtRaBaZp4SVlVoZsiW7+tus oFblOmQIUJSTbmQX3GTKM7xz X-IronPort-AV: E=Sophos;i="5.87,222,1631606400"; d="scan'208";a="68281488" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa2.mentor.iphmx.com with ESMTP; 09 Nov 2021 18:14:15 -0800 IronPort-SDR: hD3Aiaimo4W0QWDiaSnuXNmm9ZjdmrmEkNMSlWrD/M7D7rhL3tRbc16yl9wuLYim+0yqn9jZvQ K/xItkAkE1v1uWKwuUEc29yzIecopp7hCUDv4gvo2WaOdzwkx0Vj8QeJebSo/BABI/H90+rdAq sivf6IaVxmr6s9/iAfcQ7y6zpyPCW1wTd3GZlKy+t1yqryZphN+pVXVHkNxWAxBg2WJE+/9nmg 8vl9prhem/Ai2eOQ9HBNxh6raxoSRG3AAO5s32i1MuZ9JYA5x6KAbGhN7gIdqGx6hzDgqAX1Pq EK4= To: "gcc-patches@gcc.gnu.org" From: Sandra Loosemore Subject: [committed] Nios2: Add TARGET_CAN_INLINE_P hook Message-ID: Date: Tue, 9 Nov 2021 19:14:11 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0 MIME-Version: 1.0 Content-Language: en-US X-ClientProxiedBy: SVR-ORW-MBX-06.mgc.mentorg.com (147.34.90.206) To svr-orw-mbx-03.mgc.mentorg.com (147.34.90.203) X-Spam-Status: No, score=-9.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, KAM_SHORT, SPF_HELO_PASS, SPF_PASS, TXREP 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: , Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" I've checked in the attached patch, which fixes 30+ FAILs across the gcc and g++ testsuites on nios2-elf target. The only target options we have to worry about in this backend are the nios2 custom instructions, and the hashing in the default hook function seemed to be confused by all the extra state being stored in the options structure. I've made it properly check that the custom instructions enabled in the callee must be a subset of those in the caller, with the same encoding in both cases. -Sandra commit df69d7ae8f9903df8a553e236c54df61633d8af2 Author: Sandra Loosemore Date: Mon Nov 8 19:10:58 2021 -0800 Nios2: Add TARGET_CAN_INLINE_P hook. 2021-11-09 Sandra Loosemore gcc/ * config/nios2/nios2.c (nios2_can_inline_p): New. (TARGET_CAN_INLINE_P): Define. gcc/testsuite/ * gcc.target/nios2/custom-fp-inline-1.c: New. * gcc.target/nios2/custom-fp-inline-2.c: New. * gcc.target/nios2/custom-fp-inline-3.c: New. * gcc.target/nios2/custom-fp-inline-4.c: New. diff --git a/gcc/config/nios2/nios2.c b/gcc/config/nios2/nios2.c index 7a613e4..f77f7e6 100644 --- a/gcc/config/nios2/nios2.c +++ b/gcc/config/nios2/nios2.c @@ -4162,6 +4162,40 @@ nios2_option_restore (struct gcc_options *opts ATTRIBUTE_UNUSED, sizeof (custom_code_index)); } +static bool +nios2_can_inline_p (tree caller, tree callee) +{ + tree callee_opts = DECL_FUNCTION_SPECIFIC_TARGET (callee); + tree caller_opts = DECL_FUNCTION_SPECIFIC_TARGET (caller); + struct cl_target_option *callee_ptr, *caller_ptr; + unsigned int i; + + if (! callee_opts) + callee_opts = target_option_default_node; + if (! caller_opts) + caller_opts = target_option_default_node; + + /* If both caller and callee have attributes, assume that if the + pointer is different, the two functions have different target + options since build_target_option_node uses a hash table for the + options. */ + if (callee_opts == caller_opts) + return true; + + /* The only target options we recognize via function attributes are + those related to custom instructions. If we failed the above test, + check that any custom instructions enabled in the callee are also + enabled with the same value in the caller. */ + callee_ptr = TREE_TARGET_OPTION (callee_opts); + caller_ptr = TREE_TARGET_OPTION (caller_opts); + for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++) + if (callee_ptr->saved_fpu_custom_code[i] != -1 + && (callee_ptr->saved_fpu_custom_code[i] + != caller_ptr->saved_fpu_custom_code[i])) + return false; + return true; +} + /* Inner function to process the attribute((target(...))), take an argument and set the current options from the argument. If we have a list, recursively go over the list. */ @@ -5554,6 +5588,9 @@ nios2_adjust_reg_alloc_order (void) #undef TARGET_OPTION_RESTORE #define TARGET_OPTION_RESTORE nios2_option_restore +#undef TARGET_CAN_INLINE_P +#define TARGET_CAN_INLINE_P nios2_can_inline_p + #undef TARGET_SET_CURRENT_FUNCTION #define TARGET_SET_CURRENT_FUNCTION nios2_set_current_function diff --git a/gcc/testsuite/gcc.target/nios2/custom-fp-inline-1.c b/gcc/testsuite/gcc.target/nios2/custom-fp-inline-1.c new file mode 100644 index 0000000..43715e5 --- /dev/null +++ b/gcc/testsuite/gcc.target/nios2/custom-fp-inline-1.c @@ -0,0 +1,33 @@ +/* Test that you can inline a function with custom insn attributes into + one with the same attributes. */ + +/* { dg-do compile } */ +/* { dg-options "-O1 -ffinite-math-only" } */ + +/* -O1 in the options is significant. Without it FP operations may not be + optimized to custom instructions. */ + +#include + +static inline +__attribute__ ((always_inline, target ("custom-fmaxs=246,custom-fmins=247"))) +void +custom_fp1 (float operand_a, float operand_b, float *result) + +{ + result[0] = fmaxf (operand_a, operand_b); + result[1] = fminf (operand_a, operand_b); +} + +extern void +custom_fp (float operand_a, float operand_b, float *result) + __attribute__ ((target ("custom-fmaxs=246,custom-fmins=247"))); + +void +custom_fp (float operand_a, float operand_b, float *result) +{ + custom_fp1 (operand_a, operand_b, result); +} + +/* { dg-final { scan-assembler "custom\\t246, .* # fmaxs .*" } } */ +/* { dg-final { scan-assembler "custom\\t247, .* # fmins .*" } } */ diff --git a/gcc/testsuite/gcc.target/nios2/custom-fp-inline-2.c b/gcc/testsuite/gcc.target/nios2/custom-fp-inline-2.c new file mode 100644 index 0000000..3e35241 --- /dev/null +++ b/gcc/testsuite/gcc.target/nios2/custom-fp-inline-2.c @@ -0,0 +1,29 @@ +/* Test that you cannot inline a function with custom insn attributes into + one without attributes. */ + +/* { dg-do compile } */ +/* { dg-options "-O1 -ffinite-math-only" } */ + +/* -O1 in the options is significant. Without it FP operations may not be + optimized to custom instructions. */ + +#include + +static inline +__attribute__ ((always_inline, target ("custom-fmaxs=246,custom-fmins=247"))) +void +custom_fp1 (float operand_a, float operand_b, float *result) /* { dg-error "target specific option mismatch" } */ +{ + result[0] = fmaxf (operand_a, operand_b); + result[1] = fminf (operand_a, operand_b); +} + +extern void +custom_fp (float operand_a, float operand_b, float *result); + +void +custom_fp (float operand_a, float operand_b, float *result) +{ + custom_fp1 (operand_a, operand_b, result); +} + diff --git a/gcc/testsuite/gcc.target/nios2/custom-fp-inline-3.c b/gcc/testsuite/gcc.target/nios2/custom-fp-inline-3.c new file mode 100644 index 0000000..86b1064 --- /dev/null +++ b/gcc/testsuite/gcc.target/nios2/custom-fp-inline-3.c @@ -0,0 +1,33 @@ +/* Test that you can inline a function without custom insn attributes into + one that does have custom insn attributes. */ + +/* { dg-do compile } */ +/* { dg-options "-O1 -ffinite-math-only" } */ + +/* -O1 in the options is significant. Without it FP operations may not be + optimized to custom instructions. */ + +#include + +static inline +__attribute__ ((always_inline)) +void +custom_fp1 (float operand_a, float operand_b, float *result) + +{ + result[0] = fmaxf (operand_a, operand_b); + result[1] = fminf (operand_a, operand_b); +} + +extern void +custom_fp (float operand_a, float operand_b, float *result) + __attribute__ ((target ("custom-fmaxs=246,custom-fmins=247"))); + +void +custom_fp (float operand_a, float operand_b, float *result) +{ + custom_fp1 (operand_a, operand_b, result); +} + +/* { dg-final { scan-assembler "custom\\t246, .* # fmaxs .*" } } */ +/* { dg-final { scan-assembler "custom\\t247, .* # fmins .*" } } */ diff --git a/gcc/testsuite/gcc.target/nios2/custom-fp-inline-4.c b/gcc/testsuite/gcc.target/nios2/custom-fp-inline-4.c new file mode 100644 index 0000000..5e2c1bc --- /dev/null +++ b/gcc/testsuite/gcc.target/nios2/custom-fp-inline-4.c @@ -0,0 +1,29 @@ +/* Test that you cannot inline a function with custom insn attributes into + one with incompatible attributes. */ + +/* { dg-do compile } */ +/* { dg-options "-O1 -ffinite-math-only" } */ + +/* -O1 in the options is significant. Without it FP operations may not be + optimized to custom instructions. */ + +#include + +static inline +__attribute__ ((always_inline, target ("custom-fmaxs=246,custom-fmins=247"))) +void +custom_fp1 (float operand_a, float operand_b, float *result) /* { dg-error "target specific option mismatch" } */ +{ + result[0] = fmaxf (operand_a, operand_b); + result[1] = fminf (operand_a, operand_b); +} + +extern void +custom_fp (float operand_a, float operand_b, float *result) + __attribute__ ((target ("custom-fmaxs=200,custom-fmins=201"))); + +void +custom_fp (float operand_a, float operand_b, float *result) +{ + custom_fp1 (operand_a, operand_b, result); +}