summaryrefslogtreecommitdiff
path: root/gcc/config/arm/arm.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/arm/arm.c')
-rw-r--r--gcc/config/arm/arm.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index d9763d23509..6e2b799fe57 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -3172,6 +3172,19 @@ arm_canonicalize_comparison (enum rtx_code code, rtx *op0, rtx *op1)
return code;
}
+ /* If *op0 is (zero_extend:SI (subreg:QI (reg:SI) 0)) and comparing
+ with const0_rtx, change it to (and:SI (reg:SI) (const_int 255)),
+ to facilitate possible combining with a cmp into 'ands'. */
+ if (mode == SImode
+ && GET_CODE (*op0) == ZERO_EXTEND
+ && GET_CODE (XEXP (*op0, 0)) == SUBREG
+ && GET_MODE (XEXP (*op0, 0)) == QImode
+ && GET_MODE (SUBREG_REG (XEXP (*op0, 0))) == SImode
+ && subreg_lowpart_p (XEXP (*op0, 0))
+ && *op1 == const0_rtx)
+ *op0 = gen_rtx_AND (SImode, SUBREG_REG (XEXP (*op0, 0)),
+ GEN_INT (255));
+
/* Comparisons smaller than DImode. Only adjust comparisons against
an out-of-range constant. */
if (GET_CODE (*op1) != CONST_INT
@@ -16713,7 +16726,7 @@ arm_print_operand (FILE *stream, rtx x, int code)
instruction (for some alignments) as an aid to the memory subsystem
of the target. */
align = MEM_ALIGN (x) >> 3;
- memsize = INTVAL (MEM_SIZE (x));
+ memsize = MEM_SIZE (x);
/* Only certain alignment specifiers are supported by the hardware. */
if (memsize == 16 && (align % 32) == 0)