aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2017-04-25 07:29:21 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2017-04-25 07:29:21 +0000
commit10d35ddf946b0d4dc4d6c9b53f472328f0e7d469 (patch)
tree1847ff1449ca2fa7cb6514c9cc289386ba7452b2
parente848f4f0a69ed1838f34069f837fe5b5e4122524 (diff)
PR rtl-optimization/80501
* combine.c (make_compound_operation_int): Set subreg_code to SET even for AND with mask of the sign bit of mode. * gcc.c-torture/execute/pr80501.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@247129 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/combine.c7
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr80501.c23
4 files changed, 35 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7a4ed78e3bc..e25da6a1a94 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,9 @@
2017-04-25 Jakub Jelinek <jakub@redhat.com>
+ PR rtl-optimization/80501
+ * combine.c (make_compound_operation_int): Set subreg_code to SET
+ even for AND with mask of the sign bit of mode.
+
PR rtl-optimization/80500
* loop-unroll.c (combine_var_copies_in_loop_exit): Call copy_rtx on
sum's initial value.
diff --git a/gcc/combine.c b/gcc/combine.c
index 87daa28bc8e..39ef3c6ecb8 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -8170,12 +8170,15 @@ make_compound_operation_int (machine_mode mode, rtx *x_ptr,
|| GET_CODE (inner) == SUBREG
/* (subreg:SI (and:DI (reg:DI) (const_int 0x800000000)) 0)
is (const_int 0), rather than
- (subreg:SI (lshiftrt:DI (reg:DI) (const_int 35)) 0). */
+ (subreg:SI (lshiftrt:DI (reg:DI) (const_int 35)) 0).
+ Similarly (subreg:QI (and:SI (reg:SI) (const_int 0x80)) 0)
+ for non-equality comparisons against 0 is not equivalent
+ to (subreg:QI (lshiftrt:SI (reg:SI) (const_int 7)) 0). */
|| (GET_CODE (inner) == AND
&& CONST_INT_P (XEXP (inner, 1))
&& GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (inner))
&& exact_log2 (UINTVAL (XEXP (inner, 1)))
- >= GET_MODE_BITSIZE (mode))))
+ >= GET_MODE_BITSIZE (mode) - 1)))
subreg_code = SET;
tem = make_compound_operation (inner, subreg_code);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index dbdb98ebcac..1dd7ddaca56 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2017-04-25 Jakub Jelinek <jakub@redhat.com>
+ PR rtl-optimization/80501
+ * gcc.c-torture/execute/pr80501.c: New test.
+
PR rtl-optimization/80500
* gcc.dg/pr80500.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr80501.c b/gcc/testsuite/gcc.c-torture/execute/pr80501.c
new file mode 100644
index 00000000000..0a33e1fbd34
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr80501.c
@@ -0,0 +1,23 @@
+/* PR rtl-optimization/80501 */
+
+signed char v = 0;
+
+static signed char
+foo (int x, int y)
+{
+ return x << y;
+}
+
+__attribute__((noinline, noclone)) int
+bar (void)
+{
+ return foo (v >= 0, __CHAR_BIT__ - 1) >= 1;
+}
+
+int
+main ()
+{
+ if (sizeof (int) > sizeof (char) && bar () != 0)
+ __builtin_abort ();
+ return 0;
+}