diff options
author | Stefan Schulze Frielinghaus <stefansf@gcc.gnu.org> | 2025-02-13 09:13:06 +0100 |
---|---|---|
committer | Stefan Schulze Frielinghaus <stefansf@gcc.gnu.org> | 2025-02-13 09:13:06 +0100 |
commit | ac9806dae30d07ab082ac341fe5646987753adcb (patch) | |
tree | 22e951b14f866308d6e7fc21373ad7dfb33365ff /gcc/config/s390 | |
parent | 77d01927bd7c989d431035251a5c196fe39bcec9 (diff) | |
download | gcc-ac9806dae30d07ab082ac341fe5646987753adcb.zip gcc-ac9806dae30d07ab082ac341fe5646987753adcb.tar.gz gcc-ac9806dae30d07ab082ac341fe5646987753adcb.tar.bz2 |
s390: Fix s390_valid_shift_count() for TI mode [PR118835]
During combine we may end up with
(set (reg:DI 66 [ _6 ])
(ashift:DI (reg:DI 72 [ x ])
(subreg:QI (and:TI (reg:TI 67 [ _1 ])
(const_wide_int 0x0aaaaaaaaaaaaaabf))
15)))
where the shift count operand does not trivially fit the scheme of
address operands. Reject those operands, especially since
strip_address_mutations() expects expressions of the form
(and ... (const_int ...)) and fails for (and ... (const_wide_int ...)).
Thus, be more strict here and accept only CONST_INT operands. Done by
replacing immediate_operand() with const_int_operand() which is enough
since the former only additionally checks for LEGITIMATE_PIC_OPERAND_P
and targetm.legitimate_constant_p which are always true for CONST_INT
operands.
While on it, fix indentation of the if block.
gcc/ChangeLog:
PR target/118835
* config/s390/s390.cc (s390_valid_shift_count): Reject shift
count operands which do not trivially fit the scheme of
address operands.
gcc/testsuite/ChangeLog:
* gcc.target/s390/pr118835.c: New test.
Diffstat (limited to 'gcc/config/s390')
-rw-r--r-- | gcc/config/s390/s390.cc | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc index 1d96df4..29aef50 100644 --- a/gcc/config/s390/s390.cc +++ b/gcc/config/s390/s390.cc @@ -3510,26 +3510,31 @@ s390_valid_shift_count (rtx op, HOST_WIDE_INT implicit_mask) /* Check for an and with proper constant. */ if (GET_CODE (op) == AND) - { - rtx op1 = XEXP (op, 0); - rtx imm = XEXP (op, 1); + { + rtx op1 = XEXP (op, 0); + rtx imm = XEXP (op, 1); - if (GET_CODE (op1) == SUBREG && subreg_lowpart_p (op1)) - op1 = XEXP (op1, 0); + if (GET_CODE (op1) == SUBREG && subreg_lowpart_p (op1)) + op1 = XEXP (op1, 0); - if (!(register_operand (op1, GET_MODE (op1)) || GET_CODE (op1) == PLUS)) - return false; + if (!(register_operand (op1, GET_MODE (op1)) || GET_CODE (op1) == PLUS)) + return false; - if (!immediate_operand (imm, GET_MODE (imm))) - return false; + /* Accept only CONST_INT as immediates, i.e., reject shift count operands + which do not trivially fit the scheme of address operands. Especially + since strip_address_mutations() expects expressions of the form + (and ... (const_int ...)) and fails for + (and ... (const_wide_int ...)). */ + if (!const_int_operand (imm, GET_MODE (imm))) + return false; - HOST_WIDE_INT val = INTVAL (imm); - if (implicit_mask > 0 - && (val & implicit_mask) != implicit_mask) - return false; + HOST_WIDE_INT val = INTVAL (imm); + if (implicit_mask > 0 + && (val & implicit_mask) != implicit_mask) + return false; - op = op1; - } + op = op1; + } /* Check the rest. */ return s390_decompose_addrstyle_without_index (op, NULL, NULL); |