Hi Richard,
On 08/02/18 20:29, Richard Sandiford wrote:
Thanks for doing this.
Kyrill Tkachov <kyrylo.tkac...@foss.arm.com> writes:
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index
2e7aa5c12952ab1a9b49b5adaf23710327e577d3..af06d7502cebac03cefc689b2646874b8397e767
100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -6474,6 +6474,18 @@ simplify_subreg (machine_mode outermode, rtx op,
return NULL_RTX;
}
+ /* Simplify (subreg:QI (and:SI (reg:SI) (const_int 0xffff)) 0)
+ into (subreg:QI (reg:SI) 0). */
+ scalar_int_mode int_outermode, int_innermode;
+ if (!paradoxical_subreg_p (outermode, innermode)
+ && is_a <scalar_int_mode> (outermode, &int_outermode)
+ && is_a <scalar_int_mode> (innermode, &int_innermode)
+ && GET_CODE (op) == AND && CONST_INT_P (XEXP (op, 1))
+ && known_eq (subreg_lowpart_offset (outermode, innermode), byte)
+ && (~INTVAL (XEXP (op, 1)) & GET_MODE_MASK (int_outermode)) == 0
+ && validate_subreg (outermode, innermode, XEXP (op, 0), byte))
+ return gen_rtx_SUBREG (outermode, XEXP (op, 0), byte);
+
/* A SUBREG resulting from a zero extension may fold to zero if
it extracts higher bits that the ZERO_EXTEND's source bits. */
if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
I think it'd be better to do this in simplify_truncation (shared
by the subreg code and the TRUNCATE code). The return would then
be simplify_gen_unary (TRUNCATE, ...), which will become a subreg
if TRULY_NOOP_TRUNCATION.
Thanks, that does look cleaner.
Bootstrapped and tested on arm-none-linux-gnueabihf, aarch64-none-linux-gnu and
x86_64-unknown-linux-gnu.
The other two patches are still needed to address the fallout.
Is this ok?
Thanks,
Kyrill
2018-02-12 Kyrylo Tkachov <kyrylo.tkac...@arm.com>
PR target/84164
* simplify-rtx.c (simplify_truncation): Simplify truncation of masking
operation.
* config/aarch64/aarch64.md (*aarch64_reg_<mode>3_neg_mask2):
Use simplify_gen_unary creating a SUBREG.
(*aarch64_reg_<mode>3_minus_mask): Likewise.
(*aarch64_<optab>_reg_di3_mask2): Use const_int_operand predicate
for operand 3.
2018-02-12 Kyrylo Tkachov <kyrylo.tkac...@arm.com>
PR target/84164
* gcc.c-torture/compile/pr84164.c: New test.
commit 3bc951e94bec9395a732b35038dc0abf8785ba7d
Author: Kyrylo Tkachov <kyrylo.tkac...@arm.com>
Date: Thu Feb 1 13:57:46 2018 +0000
[AArch64] PR target/84164: Simplify subreg + redundant AND-immediate
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 0d13c35..69ff5ca 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -4278,8 +4278,10 @@ (define_insn_and_split "*aarch64_reg_<mode>3_neg_mask2"
emit_insn (gen_negsi2 (tmp, operands[2]));
rtx and_op = gen_rtx_AND (SImode, tmp, operands[3]);
- rtx subreg_tmp = gen_rtx_SUBREG (GET_MODE (operands[4]), and_op,
- SUBREG_BYTE (operands[4]));
+ rtx subreg_tmp = simplify_gen_unary (TRUNCATE, GET_MODE (operands[4]),
+ and_op, SImode);
+
+ gcc_assert (subreg_tmp);
emit_insn (gen_<optab><mode>3 (operands[0], operands[1], subreg_tmp));
DONE;
}
@@ -4305,9 +4307,10 @@ (define_insn_and_split "*aarch64_reg_<mode>3_minus_mask"
emit_insn (gen_negsi2 (tmp, operands[3]));
rtx and_op = gen_rtx_AND (SImode, tmp, operands[4]);
- rtx subreg_tmp = gen_rtx_SUBREG (GET_MODE (operands[5]), and_op,
- SUBREG_BYTE (operands[5]));
+ rtx subreg_tmp = simplify_gen_unary (TRUNCATE, GET_MODE (operands[5]),
+ and_op, SImode);
+ gcc_assert (subreg_tmp);
emit_insn (gen_ashl<mode>3 (operands[0], operands[1], subreg_tmp));
DONE;
}
@@ -4318,9 +4321,9 @@ (define_insn "*aarch64_<optab>_reg_di3_mask2"
(SHIFT:DI
(match_operand:DI 1 "register_operand" "r")
(match_operator 4 "subreg_lowpart_operator"
- [(and:SI (match_operand:SI 2 "register_operand" "r")
- (match_operand 3 "aarch64_shift_imm_di" "Usd"))])))]
- "((~INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1)) == 0)"
+ [(and:SI (match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "const_int_operand" "n"))])))]
+ "((~INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode) - 1)) == 0)"
{
rtx xop[3];
xop[0] = operands[0];
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 2e7aa5c..1ccfce8 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -848,6 +848,16 @@ simplify_truncation (machine_mode mode, rtx op,
return simplify_gen_subreg (int_mode, SUBREG_REG (op), subreg_mode, 0);
}
+ /* Simplify (truncate:QI (and:SI (reg:SI) (const_int 0xffff)) 0)
+ into (truncate:QI (reg:SI) 0). */
+
+ scalar_int_mode int_outermode, int_innermode;
+ if (is_a <scalar_int_mode> (mode, &int_outermode)
+ && is_a <scalar_int_mode> (op_mode, &int_innermode)
+ && GET_CODE (op) == AND && CONST_INT_P (XEXP (op, 1))
+ && (~INTVAL (XEXP (op, 1)) & GET_MODE_MASK (int_outermode)) == 0)
+ return simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
+
/* (truncate:A (truncate:B X)) is (truncate:A X). */
if (GET_CODE (op) == TRUNCATE)
return simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0),
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr84164.c b/gcc/testsuite/gcc.c-torture/compile/pr84164.c
new file mode 100644
index 0000000..d663fe5
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr84164.c
@@ -0,0 +1,17 @@
+/* PR target/84164. */
+
+int b, d;
+unsigned long c;
+
+static inline __attribute__ ((always_inline)) void
+bar (int e)
+{
+ e += __builtin_sub_overflow_p (b, d, c);
+ c = c << ((short) ~e & 3) | c >> (-((short) ~e & 3) & 63);
+}
+
+int
+foo (void)
+{
+ bar (~1);
+}