From 465c7c89e92a6d6d582173e505cb16dcb9873034 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Sun, 26 Jan 2020 13:01:48 +0000 Subject: [PATCH] simplify-rtx: Extend (truncate (*extract ...)) fold [PR87763] In the gcc.target/aarch64/lsl_asr_sbfiz.c part of this PR, we have: Failed to match this instruction: (set (reg:SI 95) (ashift:SI (subreg:SI (sign_extract:DI (subreg:DI (reg:SI 97) 0) (const_int 3 [0x3]) (const_int 0 [0])) 0) (const_int 19 [0x13]))) If we perform the natural simplification to: (set (reg:SI 95) (ashift:SI (sign_extract:SI (reg:SI 97) (const_int 3 [0x3]) (const_int 0 [0])) 0) (const_int 19 [0x13]))) then the pattern matches. And it turns out that we do have a simplification like that already, but it would only kick in for extractions from a reg, not a subreg. E.g.: (set (reg:SI 95) (ashift:SI (subreg:SI (sign_extract:DI (reg:DI X) (const_int 3 [0x3]) (const_int 0 [0])) 0) (const_int 19 [0x13]))) would simplify to: (set (reg:SI 95) (ashift:SI (sign_extract:SI (subreg:SI (reg:DI X) 0) (const_int 3 [0x3]) (const_int 0 [0])) 0) (const_int 19 [0x13]))) IMO the subreg case is even more obviously a simplification than the bare reg case, since the net effect is to remove either one or two subregs, rather than simply change the position of a subreg/truncation. However, doing that regressed gcc.dg/tree-ssa/pr64910-2.c for -m32 on x86_64-linux-gnu, because we could then simplify a :HI zero_extract to a :QI one. The associated *testqi_ext_3 pattern did already seem to want to handle QImode extractions: "ix86_match_ccmode (insn, CCNOmode) && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode) || GET_MODE (operands[2]) == SImode || GET_MODE (operands[2]) == HImode || GET_MODE (operands[2]) == QImode) but I'm not sure how often the QI case would trigger in practice, since the zero_extract mode was restricted to HI and above. I checked the other x86 patterns and couldn't see any other instances of this. 2020-01-28 Richard Sandiford gcc/ PR rtl-optimization/87763 * simplify-rtx.c (simplify_truncation): Extend sign/zero_extract simplification to handle subregs as well as bare regs. * config/i386/i386.md (*testqi_ext_3): Match QI extracts too. --- gcc/ChangeLog | 7 +++++++ gcc/config/i386/i386.md | 2 +- gcc/simplify-rtx.c | 4 +++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4d6ceb69258..9fc93c918f5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2020-01-28 Richard Sandiford + + PR rtl-optimization/87763 + * simplify-rtx.c (simplify_truncation): Extend sign/zero_extract + simplification to handle subregs as well as bare regs. + * config/i386/i386.md (*testqi_ext_3): Match QI extracts too. + 2020-01-28 Richard Sandiford * tree-vect-loop.c (vectorizable_reduction): Fail gracefully diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 6e9c9bd2fb6..a125ab350bb 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -8927,7 +8927,7 @@ (define_insn_and_split "*testqi_ext_3" [(set (match_operand 0 "flags_reg_operand") (match_operator 1 "compare_operator" - [(zero_extract:SWI248 + [(zero_extract:SWI (match_operand 2 "nonimmediate_operand" "rm") (match_operand 3 "const_int_operand" "n") (match_operand 4 "const_int_operand" "n")) diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index eff1d07a253..db4f9339c15 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -736,7 +736,9 @@ simplify_truncation (machine_mode mode, rtx op, (*_extract:M1 (truncate:M1 (reg:M2)) (len) (pos')) if possible without changing len. */ if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT) - && REG_P (XEXP (op, 0)) + && (REG_P (XEXP (op, 0)) + || (SUBREG_P (XEXP (op, 0)) + && REG_P (SUBREG_REG (XEXP (op, 0))))) && GET_MODE (XEXP (op, 0)) == GET_MODE (op) && CONST_INT_P (XEXP (op, 1)) && CONST_INT_P (XEXP (op, 2))) -- 2.30.2