+2017-04-27 Tamar Christina <tamar.christina@arm.com>
+
+ * simplify-rtx.c (simplify_binary_operation_1): Add LSHIFTRT case.
+
2017-05-02 Martin Liska <mliska@suse.cz>
PR lto/77954.
&& UINTVAL (trueop0) == GET_MODE_MASK (mode)
&& ! side_effects_p (op1))
return op0;
+
+ canonicalize_shift:
/* Given:
scalar modes M1, M2
scalar constants c1, c2
size (M2) > size (M1)
c1 == size (M2) - size (M1)
optimize:
- (ashiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
+ ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
<low_part>)
(const_int <c2>))
to:
- (subreg:M1 (ashiftrt:M2 (reg:M2) (const_int <c1 + c2>))
+ (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
<low_part>). */
- if (code == ASHIFTRT
+ if ((code == ASHIFTRT || code == LSHIFTRT)
&& !VECTOR_MODE_P (mode)
&& SUBREG_P (op0)
&& CONST_INT_P (op1)
rtx tmp = GEN_INT (INTVAL (XEXP (SUBREG_REG (op0), 1))
+ INTVAL (op1));
machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
- tmp = simplify_gen_binary (ASHIFTRT,
+ tmp = simplify_gen_binary (code,
GET_MODE (SUBREG_REG (op0)),
XEXP (SUBREG_REG (op0), 0),
tmp);
return lowpart_subreg (mode, tmp, inner_mode);
}
- canonicalize_shift:
+
if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
{
val = INTVAL (op1) & (GET_MODE_PRECISION (mode) - 1);
+2017-04-27 Tamar Christina <tamar.christina@arm.com>
+
+ * gcc.dg/lsr-div1.c: New testcase.
+
2017-05-02 Sebastian Peryt <sebastian.peryt@intel.com>
* gcc.target/i386/avx512f-vaddsd-1.c (_mm_mask_add_sd)
--- /dev/null
+/* Test division by const int generates only one shift. */
+/* { dg-do run } */
+/* { dg-options "-O2 -fdump-rtl-combine-all" } */
+/* { dg-options "-O2 -fdump-rtl-combine-all -mtune=cortex-a53" { target aarch64*-*-* } } */
+/* { dg-require-effective-target int32plus } */
+
+extern void abort (void);
+
+#define NOINLINE __attribute__((noinline))
+
+static NOINLINE int
+f1 (unsigned int n)
+{
+ return n % 0x33;
+}
+
+static NOINLINE int
+f2 (unsigned int n)
+{
+ return n % 0x12;
+}
+
+int
+main ()
+{
+ int a = 0xaaaaaaaa;
+ int b = 0x55555555;
+ int c;
+ c = f1 (a);
+ if (c != 0x11)
+ abort ();
+ c = f1 (b);
+ if (c != 0x22)
+ abort ();
+ c = f2 (a);
+ if (c != 0xE)
+ abort ();
+ c = f2 (b);
+ if (c != 0x7)
+ abort ();
+ return 0;
+}
+
+/* Following replacement pattern of intger division by constant, GCC is expected
+ to generate UMULL and (x)SHIFTRT. This test checks that considering division
+ by const 0x33, gcc generates a single LSHIFTRT by 37, instead of
+ two - LSHIFTRT by 32 and LSHIFTRT by 5. */
+
+/* { dg-final { scan-rtl-dump "\\(set \\(subreg:DI \\(reg:SI" "combine" { target aarch64*-*-* } } } */
+/* { dg-final { scan-rtl-dump "\\(lshiftrt:DI \\(reg:DI" "combine" { target aarch64*-*-* } } } */
+/* { dg-final { scan-rtl-dump "\\(const_int 37 " "combine" { target aarch64*-*-* } } } */
+
+/* Similarly, considering division by const 0x12, gcc generates a
+ single LSHIFTRT by 34, instead of two - LSHIFTRT by 32 and LSHIFTRT by 2. */
+
+/* { dg-final { scan-rtl-dump "\\(const_int 34 " "combine" { target aarch64*-*-* } } } */
+