mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
Match: Only allow single use of MIN_EXPR for SAT_TRUNC form 2 [PR115863]
The SAT_TRUNC form 2 has below pattern matching. From: _18 = MIN_EXPR <left_8, 4294967295>; iftmp.0_11 = (unsigned int) _18; To: _18 = MIN_EXPR <left_8, 4294967295>; iftmp.0_11 = .SAT_TRUNC (left_8); But if there is another use of _18 like below, the transform to the .SAT_TRUNC may have no earnings. For example: From: _18 = MIN_EXPR <left_8, 4294967295>; // op_0 def iftmp.0_11 = (unsigned int) _18; // op_0 stream.avail_out = iftmp.0_11; left_37 = left_8 - _18; // op_0 use To: _18 = MIN_EXPR <left_8, 4294967295>; // op_0 def iftmp.0_11 = .SAT_TRUNC (left_8); stream.avail_out = iftmp.0_11; left_37 = left_8 - _18; // op_0 use Pattern recog to .SAT_TRUNC cannot eliminate MIN_EXPR as above. Then the backend (for example x86/riscv) will have additional 2-3 more insns after pattern recog besides the MIN_EXPR. Thus, keep the normal truncation as is should be the better choose. The below testsuites are passed for this patch: 1. The rv64gcv fully regression tests. 2. The x86 bootstrap tests. 3. The x86 fully regression tests. PR target/115863 gcc/ChangeLog: * match.pd: Add single_use check for .SAT_TRUNC form 2. gcc/testsuite/ChangeLog: * gcc.target/i386/pr115863-1.c: New test. Signed-off-by: Pan Li <pan2.li@intel.com>
This commit is contained in:
parent
e20ea6bcf8
commit
02cc849474
15
gcc/match.pd
15
gcc/match.pd
@ -3252,10 +3252,21 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|
||||
|
||||
/* Unsigned saturation truncate, case 2, sizeof (WT) > sizeof (NT).
|
||||
SAT_U_TRUNC = (NT)(MIN_EXPR (X, 255)). */
|
||||
/* If Op_0 def is MIN_EXPR and not single_use. Aka below pattern:
|
||||
|
||||
_18 = MIN_EXPR <left_8, 4294967295>; // op_0 def
|
||||
iftmp.0_11 = (unsigned int) _18; // op_0
|
||||
stream.avail_out = iftmp.0_11;
|
||||
left_37 = left_8 - _18; // op_0 use
|
||||
|
||||
Transfer to .SAT_TRUNC will have MIN_EXPR still live. Then the backend
|
||||
(for example x86/riscv) will have 2-3 more insns generation for .SAT_TRUNC
|
||||
besides the MIN_EXPR. Thus, keep the normal truncation as is should be
|
||||
the better choose. */
|
||||
(match (unsigned_integer_sat_trunc @0)
|
||||
(convert (min @0 INTEGER_CST@1))
|
||||
(convert (min@2 @0 INTEGER_CST@1))
|
||||
(if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
|
||||
&& TYPE_UNSIGNED (TREE_TYPE (@0)))
|
||||
&& TYPE_UNSIGNED (TREE_TYPE (@0)) && single_use (@2))
|
||||
(with
|
||||
{
|
||||
unsigned itype_precision = TYPE_PRECISION (TREE_TYPE (@0));
|
||||
|
37
gcc/testsuite/gcc.target/i386/pr115863-1.c
Normal file
37
gcc/testsuite/gcc.target/i386/pr115863-1.c
Normal file
@ -0,0 +1,37 @@
|
||||
/* PR target/115863 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O3 -fdump-rtl-expand-details" } */
|
||||
|
||||
#include <stdint-gcc.h>
|
||||
|
||||
typedef struct z_stream_s {
|
||||
uint32_t avail_out;
|
||||
} z_stream;
|
||||
|
||||
typedef z_stream *z_streamp;
|
||||
|
||||
extern int deflate (z_streamp strmp);
|
||||
|
||||
int compress2 (uint64_t *destLen)
|
||||
{
|
||||
z_stream stream;
|
||||
int err;
|
||||
const uint32_t max = (uint32_t)(-1);
|
||||
uint64_t left;
|
||||
|
||||
left = *destLen;
|
||||
|
||||
stream.avail_out = 0;
|
||||
|
||||
do {
|
||||
if (stream.avail_out == 0) {
|
||||
stream.avail_out = left > (uint64_t)max ? max : (uint32_t)left;
|
||||
left -= stream.avail_out;
|
||||
}
|
||||
err = deflate(&stream);
|
||||
} while (err == 0);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-rtl-dump-not ".SAT_TRUNC " "expand" } } */
|
Loading…
Reference in New Issue
Block a user