From patchwork Sun Jul 30 07:25:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Gribov X-Patchwork-Id: 795311 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-459311-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="su2sACgi"; 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 3xKvJr0fmxz9sMN for ; Sun, 30 Jul 2017 17:26:17 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=l2nEDT9mszGr01Am2xhhRYsGuribuL0Wk6GqPO3cjyxuwEAQIW jmBNKNLXxG1ukgo5tYQQ5k89CPf8aykmlLc1VWlnGbpphNAY2gTkyx+Zgi48sI28 /8Gf0C9tWmYWH8yZa0dKHBrpmfiU8J9kky8OqcIplE11b87v7aLIJPp3I= 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:to:cc :from:subject:message-id:date:mime-version:content-type; s= default; bh=8yOWfPX4Lg04FjZry1gbsF0TvBc=; b=su2sACgioVod7md5HXUO hLBj146TZojV/KQ08KenTujcoZ5uBPdU+QFSeF6hpUdREFTsJCzN9VsJdA9fDGAD 8SHMhnM9mz3t8o/e6mLJWXYYsrwkx6mv1BKHnte82pgPmSgozSDyk8Ny9dd7ogDk edKcNJ7tkxlgoLFzux5fvBA= Received: (qmail 67867 invoked by alias); 30 Jul 2017 07:25:57 -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 67771 invoked by uid 89); 30 Jul 2017 07:25:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.2 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-wm0-f66.google.com Received: from mail-wm0-f66.google.com (HELO mail-wm0-f66.google.com) (74.125.82.66) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 30 Jul 2017 07:25:44 +0000 Received: by mail-wm0-f66.google.com with SMTP id y206so9010485wmd.5 for ; Sun, 30 Jul 2017 00:25:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:to:cc:from:subject:message-id:date:user-agent :mime-version:content-language; bh=iiHExf/AqfArBf+Yskhl6qYMSiF7Ba9prFSyk377MBY=; b=D/UFvqSuurtsjsWDHziPhmuwshiqasfPR0OxoxnL0cIB/28mPGc4i1MzlnmjN+9oPr YWrsMVSoJOWv58TS0XfZZoupyoEw5zHtqeEqMeEuECTHLfoPQA+eWZF+BSEyclTEfdoh 5pxC+3xhxOlZmKqHU7EgLIiauTWh+mOF7cXRTUxKQvuRx0bRQ6t/SZErmij02ACqhFkI C+uI3MuwFlDOwCnsey5JoUzCXxWqKlg1wlclcLbmGLsRqQVZdUWH1lYAQSEbDun7Vslw yLUYl0ly8+xvZqopsSfzfhJkCZFu56oMsN8oJ659EPQsYmbaNF6qG1LgoCOpxFHQFTAV uVHw== X-Gm-Message-State: AIVw1120oWqAupm9oJVtQjTLcwwF20K5vjku6+yyzMLQaN6hjySk7JEO 9sIwnBoKWB+WSQ== X-Received: by 10.28.223.85 with SMTP id w82mr8684327wmg.110.1501399542347; Sun, 30 Jul 2017 00:25:42 -0700 (PDT) Received: from [192.168.1.158] (host86-162-252-79.range86-162.btcentralplus.com. [86.162.252.79]) by smtp.gmail.com with ESMTPSA id 90sm9753640wrs.18.2017.07.30.00.25.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 30 Jul 2017 00:25:41 -0700 (PDT) To: gcc-patches@gcc.gnu.org Cc: Richard Biener , Marc Glisse , Joseph Myers From: Yury Gribov Subject: [PATCHv5][PR 57371] Remove useless floating point casts in comparisons Message-ID: Date: Sun, 30 Jul 2017 08:25:29 +0100 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.2.1 MIME-Version: 1.0 X-IsSubscribed: yes Hi all, This is an updated version of patch in https://gcc.gnu.org/ml/gcc-patches/2017-07/msg00924.html . It prevents optimization in presense of sNaNs (and qNaNs when comparison operator is > >= < <=) to preserve FP exceptions. I've fixed some stylistic issues mentioned in previous review. Rebased, bootstrapped and regtested on x64. Ok for trunk? -Y 2017-07-30 Yury Gribov PR tree-optimization/57371 gcc/ * match.pd: New pattern. gcc/testsuite/ * testsuite/c-c++-common/pr57371-1.c: New test. * testsuite/c-c++-common/pr57371-2.c: New test. * testsuite/c-c++-common/pr57371-3.c: New test. * testsuite/c-c++-common/pr57371-4.c: New test. * testsuite/gcc.dg/pr57371-5.c: New test. diff -rupN gcc/gcc/match.pd gcc-57371/gcc/match.pd --- gcc/gcc/match.pd 2017-07-18 22:21:16.000000000 +0200 +++ gcc-57371/gcc/match.pd 2017-07-28 05:00:05.000000000 +0200 @@ -2805,6 +2805,80 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (! HONOR_NANS (@0)) (cmp @0 @1)))))) +/* Optimize various special cases of (FTYPE) N CMP CST. */ +(for cmp (lt le eq ne ge gt) + icmp (le le eq ne ge ge) + (simplify + (cmp (float @0) REAL_CST@1) + (if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (@1)) + && ! DECIMAL_FLOAT_TYPE_P (TREE_TYPE (@1))) + (with + { + tree itype = TREE_TYPE (@0); + signop isign = TYPE_SIGN (itype); + format_helper fmt (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (@1)))); + const REAL_VALUE_TYPE *cst = TREE_REAL_CST_PTR (@1); + /* Be careful to preserve any potential exceptions due to + NaNs. qNaNs are ok in == or != context. + TODO: relax under -fno-trapping-math or + -fno-signaling-nans. */ + bool exception_p + = real_isnan (cst) && (cst->signalling + || (cmp != EQ_EXPR || cmp != NE_EXPR)); + /* INT?_MIN is power-of-two so it takes + only one mantissa bit. */ + bool signed_p = isign == SIGNED; + bool itype_fits_ftype_p + = TYPE_PRECISION (itype) - signed_p <= significand_size (fmt); + } + /* TODO: allow non-fitting itype and SNaNs when + -fno-trapping-math. */ + (if (itype_fits_ftype_p && ! exception_p) + (with + { + REAL_VALUE_TYPE imin, imax; + real_from_integer (&imin, fmt, wi::min_value (itype), isign); + real_from_integer (&imax, fmt, wi::max_value (itype), isign); + + REAL_VALUE_TYPE icst; + if (cmp == GT_EXPR || cmp == GE_EXPR) + real_ceil (&icst, fmt, cst); + else if (cmp == LT_EXPR || cmp == LE_EXPR) + real_floor (&icst, fmt, cst); + else + real_trunc (&icst, fmt, cst); + + bool cst_int_p = real_identical (&icst, cst); + + bool overflow_p = false; + wide_int icst_val + = real_to_integer (&icst, &overflow_p, TYPE_PRECISION (itype)); + } + (switch + /* Optimize cases when CST is outside of ITYPE's range. */ + (if (real_compare (LT_EXPR, cst, &imin)) + { constant_boolean_node (cmp == GT_EXPR || cmp == GE_EXPR || cmp == NE_EXPR, + type); }) + (if (real_compare (GT_EXPR, cst, &imax)) + { constant_boolean_node (cmp == LT_EXPR || cmp == LE_EXPR || cmp == NE_EXPR, + type); }) + /* Remove cast if CST is an integer representable by ITYPE. */ + (if (cst_int_p) + (cmp @0 { gcc_assert (!overflow_p); + wide_int_to_tree (itype, icst_val); }) + ) + /* When CST is fractional, optimize + (FTYPE) N == CST -> 0 + (FTYPE) N != CST -> 1. */ + (if (cmp == EQ_EXPR || cmp == NE_EXPR) + { constant_boolean_node (cmp == NE_EXPR, type); }) + /* Otherwise replace with sensible integer constant. */ + (with + { + gcc_checking_assert (!overflow_p); + } + (icmp @0 { wide_int_to_tree (itype, icst_val); }))))))))) + /* Fold A /[ex] B CMP C to A CMP B * C. */ (for cmp (eq ne) (simplify diff -rupN gcc/gcc/testsuite/c-c++-common/pr57371-1.c gcc-57371/gcc/testsuite/c-c++-common/pr57371-1.c --- gcc/gcc/testsuite/c-c++-common/pr57371-1.c 1970-01-01 01:00:00.000000000 +0100 +++ gcc-57371/gcc/testsuite/c-c++-common/pr57371-1.c 2017-07-28 05:00:05.000000000 +0200 @@ -0,0 +1,341 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-original" } */ + +#include + +/* Original testcase from PR. */ + +int foo1 (short x) { + return (double) x != 0; + /* { dg-final { scan-tree-dump "return ( = )?x != 0" "original" } } */ +} + +int foo2 (short x) { + return (float) x != 0; + /* { dg-final { scan-tree-dump "return ( = )?x != 0" "original" } } */ +} + +int foo3 (int x) { + return (double) x != 0; + /* { dg-final { scan-tree-dump "return ( = )?x != 0" "original" } } */ +} + +/* Tests when RHS is within range of integer type. */ + +void in_range (unsigned short x) +{ + { + volatile int in_range_1; + in_range_1 = (float) x > 100.0f; + /* { dg-final { scan-tree-dump "in_range_1 = x > 100" "original" } } */ + } + + { + volatile int in_range_2; + in_range_2 = (float) x < 100.0f; + /* { dg-final { scan-tree-dump "in_range_2 = x <= 99" "original" } } */ + } + + { + volatile int in_range_3; + in_range_3 = (float) x > 100.5f; + /* { dg-final { scan-tree-dump "in_range_3 = x (>= 101|> 100)" "original" } } */ + } + + { + volatile int in_range_4; + in_range_4 = (float) x < 100.5f; + /* { dg-final { scan-tree-dump "in_range_4 = x <= 100" "original" } } */ + } + + { + volatile int in_range_5; + in_range_5 = (float) x == 100.0f; + /* { dg-final { scan-tree-dump "in_range_5 = x == 100" "original" } } */ + } + + { + volatile int in_range_6; + in_range_6 = (float) x != 100.0f; + /* { dg-final { scan-tree-dump "in_range_6 = x != 100" "original" } } */ + } + + { + volatile int in_range_7; + in_range_7 = (float) x == 100.5f; + /* { dg-final { scan-tree-dump "in_range_7 = 0" "original" } } */ + } + + { + volatile int in_range_8; + in_range_8 = (float) x != 100.5f; + /* { dg-final { scan-tree-dump "in_range_8 = 1" "original" } } */ + } +} + +/* Tests for cases where RHS is out of range of integer type. */ + +void out_range (unsigned short x) +{ + { + volatile int out_range_1; + out_range_1 = (float) x > -100.5f; + /* { dg-final { scan-tree-dump "out_range_1 = 1" "original" } } */ + } + + { + volatile int out_range_2; + out_range_2 = (float) x >= -100.5f; + /* { dg-final { scan-tree-dump "out_range_2 = 1" "original" } } */ + } + + { + volatile int out_range_3; + out_range_3 = (float) x < -100.5f; + /* { dg-final { scan-tree-dump "out_range_3 = 0" "original" } } */ + } + + { + volatile int out_range_4; + out_range_4 = (float) x <= -100.5f; + /* { dg-final { scan-tree-dump "out_range_4 = 0" "original" } } */ + } + + { + volatile int out_range_5; + out_range_5 = (float) x == -100.5f; + /* { dg-final { scan-tree-dump "out_range_5 = 0" "original" } } */ + } + + { + volatile int out_range_6; + out_range_6 = (float) x != -100.5f; + /* { dg-final { scan-tree-dump "out_range_6 = 1" "original" } } */ + } +} + +/* Tests when RHS is at boundary of integer type. */ + +void lo_bounds (unsigned short x) +{ + { + volatile int lo_bounds_1; + lo_bounds_1 = (float) x > 0x0; + /* { dg-final { scan-tree-dump "lo_bounds_1 = x (>|!=) 0" "original" } } */ + } + + { + volatile int lo_bounds_2; + lo_bounds_2 = (float) x >= 0x0; + /* { dg-final { scan-tree-dump "lo_bounds_2 = 1" "original" } } */ + } + + { + volatile int lo_bounds_3; + lo_bounds_3 = (float) x < 0x0; + /* { dg-final { scan-tree-dump "lo_bounds_3 = 0" "original" } } */ + } + + { + volatile int lo_bounds_4; + lo_bounds_4 = (float) x <= 0x0; + /* { dg-final { scan-tree-dump "lo_bounds_4 = x (<=|==) 0" "original" } } */ + } + + { + volatile int lo_bounds_5; + lo_bounds_5 = (float) x > 0x0 - 0.5f; + /* { dg-final { scan-tree-dump "lo_bounds_5 = 1" "original" } } */ + } + + { + volatile int lo_bounds_6; + lo_bounds_6 = (float) x >= 0x0 - 0.5f; + /* { dg-final { scan-tree-dump "lo_bounds_6 = 1" "original" } } */ + } + + { + volatile int lo_bounds_7; + lo_bounds_7 = (float) x < 0x0 - 0.5f; + /* { dg-final { scan-tree-dump "lo_bounds_7 = 0" "original" } } */ + } + + { + volatile int lo_bounds_8; + lo_bounds_8 = (float) x <= 0x0 - 0.5f; + /* { dg-final { scan-tree-dump "lo_bounds_8 = 0" "original" } } */ + } + + { + volatile int lo_bounds_9; + lo_bounds_9 = (float) x > 0x0 + 0.5f; + /* { dg-final { scan-tree-dump "lo_bounds_9 = x (>= 1|!= 0)" "original" } } */ + } + + { + volatile int lo_bounds_10; + lo_bounds_10 = (float) x >= 0x0 + 0.5f; + /* { dg-final { scan-tree-dump "lo_bounds_10 = x (>= 1|!= 0)" "original" } } */ + } + + { + volatile int lo_bounds_11; + lo_bounds_11 = (float) x < 0x0 + 0.5f; + /* { dg-final { scan-tree-dump "lo_bounds_11 = x (<=|==) 0" "original" } } */ + } + + { + volatile int lo_bounds_12; + lo_bounds_12 = (float) x <= 0x0 + 0.5f; + /* { dg-final { scan-tree-dump "lo_bounds_12 = x (<=|==) 0" "original" } } */ + } +} + +void hi_bounds (unsigned short x) +{ + { + volatile int hi_bounds_1; + hi_bounds_1 = (float) x > USHRT_MAX; + /* { dg-final { scan-tree-dump "hi_bounds_1 = 0" "original" } } */ + } + + { + volatile int hi_bounds_2; + hi_bounds_2 = (float) x >= USHRT_MAX; + /* { dg-final { scan-tree-dump "hi_bounds_2 = x (>=|==) 65535" "original" } } */ + } + + { + volatile int hi_bounds_3; + hi_bounds_3 = (float) x < USHRT_MAX; + /* { dg-final { scan-tree-dump "hi_bounds_3 = x (<|!=) 65535" "original" } } */ + } + + { + volatile int hi_bounds_4; + hi_bounds_4 = (float) x <= USHRT_MAX; + /* { dg-final { scan-tree-dump "hi_bounds_4 = 1" "original" } } */ + } + + { + volatile int hi_bounds_5; + hi_bounds_5 = (float) x > USHRT_MAX - 0.5f; + /* { dg-final { scan-tree-dump "hi_bounds_5 = x (>=|==) 65535" "original" } } */ + } + + { + volatile int hi_bounds_6; + hi_bounds_6 = (float) x >= USHRT_MAX - 0.5f; + /* { dg-final { scan-tree-dump "hi_bounds_6 = x (>=|==) 65535" "original" } } */ + } + + { + volatile int hi_bounds_7; + hi_bounds_7 = (float) x < USHRT_MAX - 0.5f; + /* { dg-final { scan-tree-dump "hi_bounds_7 = x (<= 65534|!= 65535)" "original" } } */ + } + + { + volatile int hi_bounds_8; + hi_bounds_8 = (float) x <= USHRT_MAX - 0.5f; + /* { dg-final { scan-tree-dump "hi_bounds_8 = x (<= 65534|!= 65535)" "original" } } */ + } + + { + volatile int hi_bounds_9; + hi_bounds_9 = (float) x > USHRT_MAX + 0.5f; + /* { dg-final { scan-tree-dump "hi_bounds_9 = 0" "original" } } */ + } + + { + volatile int hi_bounds_10; + hi_bounds_10 = (float) x >= USHRT_MAX + 0.5f; + /* { dg-final { scan-tree-dump "hi_bounds_10 = 0" "original" } } */ + } + + { + volatile int hi_bounds_11; + hi_bounds_11 = (float) x < USHRT_MAX + 0.5f; + /* { dg-final { scan-tree-dump "hi_bounds_11 = 1" "original" } } */ + } + + { + volatile int hi_bounds_12; + hi_bounds_12 = (float) x <= USHRT_MAX + 0.5f; + /* { dg-final { scan-tree-dump "hi_bounds_12 = 1" "original" } } */ + } +} + +/* Tests with non-finite float consts. */ + +void nonfinite (unsigned short x) +{ +#define INFINITY __builtin_inff () + + { + volatile int nonfinite_1; + nonfinite_1 = (float) x > INFINITY; + /* { dg-final { scan-tree-dump "nonfinite_1 = 0" "original" } } */ + } + + { + volatile int nonfinite_2; + nonfinite_2 = (float) x >= INFINITY; + /* { dg-final { scan-tree-dump "nonfinite_2 = 0" "original" } } */ + } + + { + volatile int nonfinite_3; + nonfinite_3 = (float) x < INFINITY; + /* { dg-final { scan-tree-dump "nonfinite_3 = 1" "original" } } */ + } + + { + volatile int nonfinite_4; + nonfinite_4 = (float) x <= INFINITY; + /* { dg-final { scan-tree-dump "nonfinite_4 = 1" "original" } } */ + } + + { + volatile int nonfinite_5; + nonfinite_5 = (float) x > -INFINITY; + /* { dg-final { scan-tree-dump "nonfinite_5 = 1" "original" } } */ + } + + { + volatile int nonfinite_6; + nonfinite_6 = (float) x >= -INFINITY; + /* { dg-final { scan-tree-dump "nonfinite_6 = 1" "original" } } */ + } + + { + volatile int nonfinite_7; + nonfinite_7 = (float) x < -INFINITY; + /* { dg-final { scan-tree-dump "nonfinite_7 = 0" "original" } } */ + } + + { + volatile int nonfinite_8; + nonfinite_8 = (float) x <= -INFINITY; + /* { dg-final { scan-tree-dump "nonfinite_8 = 0" "original" } } */ + } + +#define QNAN __builtin_nanf ("0") + + /* Even for qNaNs, only == and != are quiet. */ + + { + volatile int nonfinite_9; + nonfinite_9 = (float) x == QNAN; + /* { dg-final { scan-tree-dump "nonfinite_9 = 0" "original" } } */ + } + + { + volatile int nonfinite_10; + nonfinite_10 = (float) x != QNAN; + /* { dg-final { scan-tree-dump "nonfinite_10 = 1" "original" } } */ + } +} + +/* { dg-final { scan-tree-dump-not "\\(float\\)" "original" } } */ +/* { dg-final { scan-tree-dump-not "\\(double\\)" "original" } } */ diff -rupN gcc/gcc/testsuite/c-c++-common/pr57371-2.c gcc-57371/gcc/testsuite/c-c++-common/pr57371-2.c --- gcc/gcc/testsuite/c-c++-common/pr57371-2.c 1970-01-01 01:00:00.000000000 +0100 +++ gcc-57371/gcc/testsuite/c-c++-common/pr57371-2.c 2017-07-28 05:00:05.000000000 +0200 @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +/* We can not get rid of comparison in tests below because of + potential inexact exception. + + TODO: enable when -fno-trapping-math. */ + +int foo1(int x) { + return (float) x != 0; + /* { dg-final { scan-tree-dump "\\(float\\)" "optimized" } } */ +} + +int foo2(long long x) { + /* { dg-final { scan-tree-dump "\\(double\\)" "optimized" } } */ + return (double) x != 0; +} diff -rupN gcc/gcc/testsuite/c-c++-common/pr57371-3.c gcc-57371/gcc/testsuite/c-c++-common/pr57371-3.c --- gcc/gcc/testsuite/c-c++-common/pr57371-3.c 1970-01-01 01:00:00.000000000 +0100 +++ gcc-57371/gcc/testsuite/c-c++-common/pr57371-3.c 2017-07-28 05:00:05.000000000 +0200 @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ +/* { dg-require-effective-target int128 } */ + +/* We can not get rid of comparison in tests below because of + potential overflow exception. + + TODO: enable when -fno-trapping-math. */ + +int foo(__int128_t x) { + /* { dg-final { scan-tree-dump "\\(float\\)" "optimized" } } */ + return (float) x != 0; +} diff -rupN gcc/gcc/testsuite/c-c++-common/pr57371-4.c gcc-57371/gcc/testsuite/c-c++-common/pr57371-4.c --- gcc/gcc/testsuite/c-c++-common/pr57371-4.c 1970-01-01 01:00:00.000000000 +0100 +++ gcc-57371/gcc/testsuite/c-c++-common/pr57371-4.c 2017-07-28 05:00:05.000000000 +0200 @@ -0,0 +1,72 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fsignaling-nans -fdump-tree-original" } */ + +/* We can not get rid of comparison in tests below because of + pending NaN exceptions. + + TODO: avoid under -fno-trapping-math. */ + +#define QNAN __builtin_nanf ("0") +#define SNAN __builtin_nansf ("0") + +void nonfinite(unsigned short x) { + { + volatile int nonfinite_1; + nonfinite_1 = (float) x > QNAN; + /* { dg-final { scan-tree-dump "nonfinite_1 = \\(float\\)" "original" } } */ + } + + { + volatile int nonfinite_2; + nonfinite_2 = (float) x >= QNAN; + /* { dg-final { scan-tree-dump "nonfinite_2 = \\(float\\)" "original" } } */ + } + + { + volatile int nonfinite_3; + nonfinite_3 = (float) x < QNAN; + /* { dg-final { scan-tree-dump "nonfinite_3 = \\(float\\)" "original" } } */ + } + + { + volatile int nonfinite_4; + nonfinite_4 = (float) x <= QNAN; + /* { dg-final { scan-tree-dump "nonfinite_4 = \\(float\\)" "original" } } */ + } + + { + volatile int nonfinite_5; + nonfinite_5 = (float) x > SNAN; + /* { dg-final { scan-tree-dump "nonfinite_5 = \\(float\\)" "original" } } */ + } + + { + volatile int nonfinite_6; + nonfinite_6 = (float) x >= SNAN; + /* { dg-final { scan-tree-dump "nonfinite_6 = \\(float\\)" "original" } } */ + } + + { + volatile int nonfinite_7; + nonfinite_7 = (float) x < SNAN; + /* { dg-final { scan-tree-dump "nonfinite_7 = \\(float\\)" "original" } } */ + } + + { + volatile int nonfinite_8; + nonfinite_8 = (float) x <= SNAN; + /* { dg-final { scan-tree-dump "nonfinite_8 = \\(float\\)" "original" } } */ + } + + { + volatile int nonfinite_9; + nonfinite_9 = (float) x == SNAN; + /* { dg-final { scan-tree-dump "nonfinite_9 = \\(float\\)" "original" } } */ + } + + { + volatile int nonfinite_10; + nonfinite_10 = (float) x != SNAN; + /* { dg-final { scan-tree-dump "nonfinite_10 = \\(float\\)" "original" } } */ + } +} diff -rupN gcc/gcc/testsuite/gcc.dg/pr57371-5.c gcc-57371/gcc/testsuite/gcc.dg/pr57371-5.c --- gcc/gcc/testsuite/gcc.dg/pr57371-5.c 1970-01-01 01:00:00.000000000 +0100 +++ gcc-57371/gcc/testsuite/gcc.dg/pr57371-5.c 2017-07-28 05:00:05.000000000 +0200 @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ +/* { dg-require-effective-target dfp } */ + +/* We do not support DFPs. */ + +int foo(short x) { + /* { dg-final { scan-tree-dump "\\(_Decimal32\\)" "optimized" } } */ + return (_Decimal32) x != 0; +}