From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) by sourceware.org (Postfix) with ESMTPS id EABE03858D28 for ; Mon, 27 May 2024 01:08:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org EABE03858D28 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=intel.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org EABE03858D28 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716772092; cv=none; b=T7sZJGqmaT+B6J6prilP1sgV7M1gtmuxJTHw/tcFDGwxkBbI+z2G9QnSyUvlJf4D+rUmN/jJ20ZFu03HiRrLcCvayslnSdM4Bua1KHyRSxyaudTeunbIDt0O+9MgrTfGwBDei66QAEcP+4Z5nP0WIoTdPpCUVGYAWDzCA8h5jCE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716772092; c=relaxed/simple; bh=evkgpyZwg3g/vy9Q+EHguFdPBbFY/OP+AhLiK7zQBmg=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=bMKk7VYycMfhJzUe6Ih5KuRXgAUBIJgXtRkQ2Ws5wWHFlJwMwLEzZr0rEqj3HixQUe2Wv7QkNVzcTmxNWgsRfTHh53MO94TOEJ6RZeC6SDkvmeNVOQDW7VST5PkTg1ktIA2DohpP7I0ttlwub1sUXfNw3/5n0RnKZnkJaMrzvnc= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1716772090; x=1748308090; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=evkgpyZwg3g/vy9Q+EHguFdPBbFY/OP+AhLiK7zQBmg=; b=oJ6WjR2T9fzKK29uyUTQNUOofXKqFgDWrm1OY0vT8yJW8Ky8RnQWbKKi he1jWCDPxuyw/1BT6eqTeOhHVh/Hj8SZZOY5JQl0DqfzFcrFWJk5v9/VL Qp1fCeM7zFPRR+EiAsCvcCAe4Mp+mNhXT2+Ow63QGzrfnbHi8gRIWqSpn iLZ8J28oxnNKJcMOjwjKSQCbrqZu+AqeDvHDpNQ6UrQiZO584VYIsjrpU 7TPEOo0CACuZmAS8LJhl7DMwKqYpKSRp92G7plXCs/wyK5LLWYBYqP/r5 ON8zmLbQ49T5E7FemFl1JdJ0BLyr1BUVlTAUa0JIT1YPU+jB8QauxOljK w==; X-CSE-ConnectionGUID: oF3e6HfxTfWexAFPffIr9w== X-CSE-MsgGUID: 8hgda4s2RYapwr11Ayv+WQ== X-IronPort-AV: E=McAfee;i="6600,9927,11084"; a="12938612" X-IronPort-AV: E=Sophos;i="6.08,191,1712646000"; d="scan'208";a="12938612" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 May 2024 18:08:09 -0700 X-CSE-ConnectionGUID: xvG27ktVSJW2cYNaoOj1Yw== X-CSE-MsgGUID: SbmL73tKTSCsd+uhKzNAkQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,191,1712646000"; d="scan'208";a="34667100" Received: from shvmail03.sh.intel.com ([10.239.245.20]) by fmviesa010.fm.intel.com with ESMTP; 26 May 2024 18:08:04 -0700 Received: from shliclel4217.sh.intel.com (shliclel4217.sh.intel.com [10.239.240.127]) by shvmail03.sh.intel.com (Postfix) with ESMTP id BEBB71007363; Mon, 27 May 2024 09:08:03 +0800 (CST) From: liuhongt To: gcc-patches@gcc.gnu.org Cc: jakub@redhat.com Subject: [PATCH] Don't simplify NAN/INF or out-of-range constant for FIX/UNSIGNED_FIX. Date: Mon, 27 May 2024 09:08:03 +0800 Message-Id: <20240527010803.2851191-1-hongtao.liu@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Update in V2: Guard constant folding for overflow value in fold_convert_const_int_from_real with flag_trapping_math. Add -fno-trapping-math to related testcases which warn for overflow in conversion from floating point to integer. Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}. Ok for trunk? According to IEEE standard, for conversions from floating point to integer. When a NaN or infinite operand cannot be represented in the destination format and this cannot otherwise be indicated, the invalid operation exception shall be signaled. When a numeric operand would convert to an integer outside the range of the destination format, the invalid operation exception shall be signaled if this situation cannot otherwise be indicated. The patch prevent simplication of the conversion from floating point to integer for NAN/INF/out-of-range constant when flag_trapping_math. gcc/ChangeLog: PR rtl-optimization/100927 PR rtl-optimization/115161 PR rtl-optimization/115115 * simplify-rtx.cc (simplify_const_unary_operation): Prevent simplication of FIX/UNSIGNED_FIX for NAN/INF/out-of-range constant when flag_trapping_math. * fold-const.cc (fold_convert_const_int_from_real): Don't fold for overflow value when_trapping_math. gcc/testsuite/ChangeLog: * gcc.dg/pr100927.c: New test. * c-c++-common/Wconversion-1.c: Add -fno-trapping-math. * c-c++-common/dfp/convert-int-saturate.c: Ditto. * g++.dg/ubsan/pr63956.C: Ditto. * g++.dg/warn/Wconversion-real-integer.C: Ditto. * gcc.c-torture/execute/20031003-1.c: Ditto. * gcc.dg/Wconversion-complex-c99.c: Ditto. * gcc.dg/Wconversion-real-integer.c: Ditto. * gcc.dg/c90-const-expr-11.c: Ditto. * gcc.dg/overflow-warn-8.c: Ditto. --- gcc/fold-const.cc | 13 +++++++- gcc/simplify-rtx.cc | 23 +++++++++++--- gcc/testsuite/c-c++-common/Wconversion-1.c | 2 +- .../c-c++-common/dfp/convert-int-saturate.c | 1 + gcc/testsuite/g++.dg/ubsan/pr63956.C | 7 ++++- .../g++.dg/warn/Wconversion-real-integer.C | 2 +- .../gcc.c-torture/execute/20031003-1.c | 2 ++ .../gcc.dg/Wconversion-complex-c99.c | 2 +- .../gcc.dg/Wconversion-real-integer.c | 2 +- gcc/testsuite/gcc.dg/c90-const-expr-11.c | 2 +- gcc/testsuite/gcc.dg/overflow-warn-8.c | 1 + gcc/testsuite/gcc.dg/pr100927.c | 31 +++++++++++++++++++ 12 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr100927.c diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 7b268964acc..0ba01984630 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -2246,7 +2246,18 @@ fold_convert_const_int_from_real (enum tree_code code, tree type, const_tree arg if (! overflow) val = real_to_integer (&r, &overflow, TYPE_PRECISION (type)); - t = force_fit_type (type, val, -1, overflow | TREE_OVERFLOW (arg1)); + /* According to IEEE standard, for conversions from floating point to + integer. When a NaN or infinite operand cannot be represented in the + destination format and this cannot otherwise be indicated, the invalid + operation exception shall be signaled. When a numeric operand would + convert to an integer outside the range of the destination format, the + invalid operation exception shall be signaled if this situation cannot + otherwise be indicated. */ + if (!flag_trapping_math || !overflow) + t = force_fit_type (type, val, -1, overflow | TREE_OVERFLOW (arg1)); + else + t = NULL_TREE; + return t; } diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc index 53f54d1d392..b7a770dad60 100644 --- a/gcc/simplify-rtx.cc +++ b/gcc/simplify-rtx.cc @@ -2256,14 +2256,25 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode, switch (code) { case FIX: + /* According to IEEE standard, for conversions from floating point to + integer. When a NaN or infinite operand cannot be represented in + the destination format and this cannot otherwise be indicated, the + invalid operation exception shall be signaled. When a numeric + operand would convert to an integer outside the range of the + destination format, the invalid operation exception shall be + signaled if this situation cannot otherwise be indicated. */ if (REAL_VALUE_ISNAN (*x)) - return const0_rtx; + return flag_trapping_math ? NULL_RTX : const0_rtx; + + if (REAL_VALUE_ISINF (*x) && flag_trapping_math) + return NULL_RTX; /* Test against the signed upper bound. */ wmax = wi::max_value (width, SIGNED); real_from_integer (&t, VOIDmode, wmax, SIGNED); if (real_less (&t, x)) - return immed_wide_int_const (wmax, mode); + return (flag_trapping_math + ? NULL_RTX : immed_wide_int_const (wmax, mode)); /* Test against the signed lower bound. */ wmin = wi::min_value (width, SIGNED); @@ -2276,13 +2287,17 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode, case UNSIGNED_FIX: if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x)) - return const0_rtx; + return flag_trapping_math ? NULL_RTX : const0_rtx; + + if (REAL_VALUE_ISINF (*x) && flag_trapping_math) + return NULL_RTX; /* Test against the unsigned upper bound. */ wmax = wi::max_value (width, UNSIGNED); real_from_integer (&t, VOIDmode, wmax, UNSIGNED); if (real_less (&t, x)) - return immed_wide_int_const (wmax, mode); + return (flag_trapping_math + ? NULL_RTX : immed_wide_int_const (wmax, mode)); return immed_wide_int_const (real_to_integer (x, &fail, width), mode); diff --git a/gcc/testsuite/c-c++-common/Wconversion-1.c b/gcc/testsuite/c-c++-common/Wconversion-1.c index 81f9498d07c..9d874d19548 100644 --- a/gcc/testsuite/c-c++-common/Wconversion-1.c +++ b/gcc/testsuite/c-c++-common/Wconversion-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-Wconversion" } */ +/* { dg-options "-Wconversion -fno-trapping-math" } */ typedef char T; diff --git a/gcc/testsuite/c-c++-common/dfp/convert-int-saturate.c b/gcc/testsuite/c-c++-common/dfp/convert-int-saturate.c index 2d01f99468b..6b362c2aa95 100644 --- a/gcc/testsuite/c-c++-common/dfp/convert-int-saturate.c +++ b/gcc/testsuite/c-c++-common/dfp/convert-int-saturate.c @@ -2,6 +2,7 @@ C99 6.3.1.4(1a) New. Test integer saturation. */ +/* { dg-options "-fno-trapping-math" } */ #ifndef __STDC_WANT_DEC_FP__ #define __STDC_WANT_DEC_FP__ 1 #endif diff --git a/gcc/testsuite/g++.dg/ubsan/pr63956.C b/gcc/testsuite/g++.dg/ubsan/pr63956.C index 6fd0b4f893e..9c15dbd8d54 100644 --- a/gcc/testsuite/g++.dg/ubsan/pr63956.C +++ b/gcc/testsuite/g++.dg/ubsan/pr63956.C @@ -1,6 +1,6 @@ // PR sanitizer/63956 // { dg-do compile } -// { dg-options "-std=c++14 -fsanitize=undefined,float-divide-by-zero,float-cast-overflow" } +// { dg-options "-std=c++14 -fsanitize=undefined,float-divide-by-zero" } #define SA(X) static_assert((X),#X) #define INT_MIN (-__INT_MAX__ - 1) @@ -162,8 +162,13 @@ fn11 (double d) return i * 2; } +void +__attribute__((optimize("no-trapping-math"))) +foo () +{ constexpr int r1 = fn11 (3.4); constexpr int r2 = fn11 (__builtin_inf ()); // { dg-message "in .constexpr. expansion of " } +} constexpr int fn12 (int i) diff --git a/gcc/testsuite/g++.dg/warn/Wconversion-real-integer.C b/gcc/testsuite/g++.dg/warn/Wconversion-real-integer.C index 3b6d1f3c437..d6332140b14 100644 --- a/gcc/testsuite/g++.dg/warn/Wconversion-real-integer.C +++ b/gcc/testsuite/g++.dg/warn/Wconversion-real-integer.C @@ -3,7 +3,7 @@ gcc/testsuite/gcc.dg/Wconversion-real-integer.c */ /* { dg-do compile } -/* { dg-options "-Wconversion -ftrack-macro-expansion=0" } */ +/* { dg-options "-Wconversion -ftrack-macro-expansion=0 -fno-trapping-math" } */ /* { dg-require-effective-target int32plus } */ #include diff --git a/gcc/testsuite/gcc.c-torture/execute/20031003-1.c b/gcc/testsuite/gcc.c-torture/execute/20031003-1.c index 5d39d799e50..5e6f5089fc6 100644 --- a/gcc/testsuite/gcc.c-torture/execute/20031003-1.c +++ b/gcc/testsuite/gcc.c-torture/execute/20031003-1.c @@ -1,5 +1,7 @@ /* PR optimization/9325 */ +/* { dg-additional-options "-fno-trapping-math" } */ + #include extern void abort (void); diff --git a/gcc/testsuite/gcc.dg/Wconversion-complex-c99.c b/gcc/testsuite/gcc.dg/Wconversion-complex-c99.c index e8bc9db237d..69281c7d71e 100644 --- a/gcc/testsuite/gcc.dg/Wconversion-complex-c99.c +++ b/gcc/testsuite/gcc.dg/Wconversion-complex-c99.c @@ -6,7 +6,7 @@ /* { dg-do compile } */ /* { dg-skip-if "doubles are floats,ints are 16bits" { "avr-*-*" } } */ -/* { dg-options " -std=c99 -pedantic -Wconversion " } */ +/* { dg-options " -std=c99 -pedantic -Wconversion -fno-trapping-math" } */ /* { dg-require-effective-target int32plus } */ /* { dg-require-effective-target double64plus } */ diff --git a/gcc/testsuite/gcc.dg/Wconversion-real-integer.c b/gcc/testsuite/gcc.dg/Wconversion-real-integer.c index 92e6987d9ec..ca6007f4fe8 100644 --- a/gcc/testsuite/gcc.dg/Wconversion-real-integer.c +++ b/gcc/testsuite/gcc.dg/Wconversion-real-integer.c @@ -3,7 +3,7 @@ /* { dg-do compile } */ /* { dg-skip-if "doubles are floats,ints are 16bits" { "avr-*-*" } } */ -/* { dg-options "-std=c99 -Wconversion" } */ +/* { dg-options "-std=c99 -Wconversion -fno-trapping-math" } */ /* { dg-require-effective-target int32plus } */ /* { dg-require-effective-target double64plus } */ #include diff --git a/gcc/testsuite/gcc.dg/c90-const-expr-11.c b/gcc/testsuite/gcc.dg/c90-const-expr-11.c index a2720c47bf4..65aab10a129 100644 --- a/gcc/testsuite/gcc.dg/c90-const-expr-11.c +++ b/gcc/testsuite/gcc.dg/c90-const-expr-11.c @@ -2,7 +2,7 @@ constant expressions. */ /* Origin: Joseph Myers */ /* { dg-do compile } */ -/* { dg-options "-std=iso9899:1990 -pedantic-errors -O2" } */ +/* { dg-options "-std=iso9899:1990 -pedantic-errors -O2 -fno-trapping-math" } */ #include #include diff --git a/gcc/testsuite/gcc.dg/overflow-warn-8.c b/gcc/testsuite/gcc.dg/overflow-warn-8.c index e76bcac5e07..75bfa74f3dc 100644 --- a/gcc/testsuite/gcc.dg/overflow-warn-8.c +++ b/gcc/testsuite/gcc.dg/overflow-warn-8.c @@ -1,5 +1,6 @@ #include +/* { dg-options " -fno-trapping-math" } */ void foo (int j) { int i1 = (int)(double)1.0 + INT_MAX; /* { dg-warning "integer overflow" } */ diff --git a/gcc/testsuite/gcc.dg/pr100927.c b/gcc/testsuite/gcc.dg/pr100927.c new file mode 100644 index 00000000000..ea0e627befa --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100927.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftrapping-math -fdump-tree-optimized -fdump-rtl-final" } */ +/* { dg-final { scan-tree-dump-times {(?n)= \(int\)} 3 "optimized" } } */ +/* { dg-final { scan-rtl-dump-times {(?n)\(fix:SI} 3 "final" } } */ + +int +foo_ofr () +{ + union {float a; + int b;}c; + c.b = 0x4f000000; + return (int)c.a; +} + +int +foo_inf () +{ + union {float a; + int b;}c; + c.b = 0xff800000; + return (int)c.a; +} + +int +foo_nan () +{ + union {float a; + int b;}c; + c.b = 0xff800001; + return (int)c.a; +} -- 2.31.1