summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2016-07-07 21:49:58 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2016-07-07 21:49:58 +0000
commit67ca8af543700260c6f7ea04c22d1e0e584eb700 (patch)
treed637065e70d88d46c5213b031947a426f5d05163
parentfc339cdd0cd922812454d38605b6240c825c6855 (diff)
downloadgcc-67ca8af543700260c6f7ea04c22d1e0e584eb700.tar.gz
Backported from mainline
2016-03-15 Jakub Jelinek <jakub@redhat.com> PR rtl-optimization/70222 * combine.c (simplify_shift_const_1): For A >> B >> C LSHIFTRT optimization if mode is different from result_mode, queue up masking of the result in outer_op. Formatting fix. * gcc.c-torture/execute/pr70222-1.c: New test. * gcc.c-torture/execute/pr70222-2.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch@238140 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/combine.c14
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr70222-1.c30
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr70222-2.c20
5 files changed, 75 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1abaf860f55..52b69c8f3ea 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,13 @@
2016-07-07 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
+ 2016-03-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/70222
+ * combine.c (simplify_shift_const_1): For A >> B >> C LSHIFTRT
+ optimization if mode is different from result_mode, queue up masking
+ of the result in outer_op. Formatting fix.
+
2016-03-11 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/70169
diff --git a/gcc/combine.c b/gcc/combine.c
index a22aba7d48e..c48d9b11e47 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -10173,9 +10173,19 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode,
&& CONST_INT_P (XEXP (varop, 0))
&& !CONST_INT_P (XEXP (varop, 1)))
{
+ /* For ((unsigned) (cstULL >> count)) >> cst2 we have to make
+ sure the result will be masked. See PR70222. */
+ if (code == LSHIFTRT
+ && mode != result_mode
+ && !merge_outer_ops (&outer_op, &outer_const, AND,
+ GET_MODE_MASK (result_mode)
+ >> orig_count, result_mode,
+ &complement_p))
+ break;
+
rtx new_rtx = simplify_const_binary_operation (code, mode,
- XEXP (varop, 0),
- GEN_INT (count));
+ XEXP (varop, 0),
+ GEN_INT (count));
varop = gen_rtx_fmt_ee (code, mode, new_rtx, XEXP (varop, 1));
count = 0;
continue;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9a70102ba3e..dac1b34b1b3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,6 +1,12 @@
2016-07-07 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
+ 2016-03-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/70222
+ * gcc.c-torture/execute/pr70222-1.c: New test.
+ * gcc.c-torture/execute/pr70222-2.c: New test.
+
2016-03-11 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/70169
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr70222-1.c b/gcc/testsuite/gcc.c-torture/execute/pr70222-1.c
new file mode 100644
index 00000000000..d79672e7fb4
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr70222-1.c
@@ -0,0 +1,30 @@
+/* PR rtl-optimization/70222 */
+
+int a = 1;
+unsigned int b = 2;
+int c = 0;
+int d = 0;
+
+void
+foo ()
+{
+ int e = ((-(c >= c)) < b) > ((int) (-1ULL >> ((a / a) * 15)));
+ d = -e;
+}
+
+__attribute__((noinline, noclone)) void
+bar (int x)
+{
+ if (x != -1)
+ __builtin_abort ();
+}
+
+int
+main ()
+{
+#if __CHAR_BIT__ == 8 && __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8
+ foo ();
+ bar (d);
+#endif
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr70222-2.c b/gcc/testsuite/gcc.c-torture/execute/pr70222-2.c
new file mode 100644
index 00000000000..7611c986a9b
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr70222-2.c
@@ -0,0 +1,20 @@
+/* PR rtl-optimization/70222 */
+
+#if __CHAR_BIT__ == 8 && __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8
+__attribute__((noinline, noclone)) unsigned int
+foo (int x)
+{
+ unsigned long long y = -1ULL >> x;
+ return (unsigned int) y >> 31;
+}
+#endif
+
+int
+main ()
+{
+#if __CHAR_BIT__ == 8 && __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8
+ if (foo (15) != 1 || foo (32) != 1 || foo (33) != 0)
+ __builtin_abort ();
+#endif
+ return 0;
+}