diff mbox

[avr,committed] : Remove flag_strict_overflow from avr.md

Message ID 87o9v677gr.fsf@linaro.org
State New
Headers show

Commit Message

Richard Sandiford May 6, 2017, 7:47 a.m. UTC
Richard Biener <rguenther@suse.de> writes:
> On Fri, 5 May 2017, Richard Sandiford wrote:
>> Richard Biener <rguenther@suse.de> writes:
>> > On Fri, 5 May 2017, Georg-Johann Lay wrote:
>> >> On 05.05.2017 13:04, Richard Biener wrote:
>> >> > On Fri, 5 May 2017, Georg-Johann Lay wrote:
>> >> > 
>> >> > > Applied this addendum to r247495 which removed
>> >> > > flag_strict_overflow. There
>> >> > > were remains of the flag in avr.md which broke the avr build.
>> >> > > 
>> >> > > Committed as r247632.
>> >> > 
>> >> > Whoops - sorry for not grepping besides .[ch] files...
>> >> > 
>> >> > But... these patterns very much look like premature optimization
>> >> > and/or bugs.  combine is supposed to handle this via simplify_rtx.
>> >> 
>> >> Well, for now the patch just restores avr BE to be able to be build.
>> >
>> > Sure.
>> >
>> >> > Also note that on RTL we generally assume overflow wraps as we lose
>> >> > signedness of operands.  Not sure what 'compare' in your patterns
>> >> > will end up with.
>> >> > 
>> >> > The only flag_wrapv checks in RTL otherwise are in simplify-rtx.c
>> >> > for ABS which seems to be a singed RTL op.
>> >> 
>> >> Which is a bug, IMO.  Letting undefined overflow propagate to RTL
>> >> renders some RTL as if it has undefined behaviour.  Consequence is
>> >> that testing the MSB must no more use signed comparisons on
>> >> less-zero resp. greater-or-equal-to-zero.
>> >> 
>> >> Cf. https://gcc.gnu.org/PR75964 for an example:
>> >> 
>> >> 
>> >> typedef __UINT8_TYPE__ uint8_t;
>> >> 
>> >> uint8_t abs8 (uint8_t x)
>> >> {
>> >>     if (x & 0x80)
>> >>         x = -x;
>> >> 
>> >>     if (x & 0x80)
>> >>         x = 0x7f;
>> >> 
>> >>     return x;
>> >> }
>> >> 
>> >> The first comparison is performed by a signed test against 0 (which
>> >> is reasonable and the best code in that case) but then we conclude
>> >> that the second test is always false, which is BUG.
>> >> 
>> >> IMO the culprit is to let slip undefined overflow to RTL.
>> >
>> > Yes.  I thought in RTL overflow is always well-defined (but then
>> > as I said your patterns are equally bogus).
>> 
>> Yeah, me too.  I don't see how the simplify-rtx.c code can be right.
>> 
>> Is the following OK, if it passes testing?
>
> Yes.  Can you add the testcase?

OK, here's what I installed after testing on aarch64-linux-gnu and
x86_64-linux-gnu.

Thanks,
Richard


2017-05-06  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
	PR rtl-optimization/75964
	* simplify-rtx.c (simplify_const_relational_operation): Remove
	invalid handling of comparisons of integer ABS.

gcc/testsuite/
	PR rtl-optimization/75964
	* gcc.dg/torture/pr75964.c: New test.
diff mbox

Patch

Index: gcc/simplify-rtx.c
===================================================================
--- gcc/simplify-rtx.c	2017-05-05 13:44:27.364724260 +0100
+++ gcc/simplify-rtx.c	2017-05-05 13:44:36.580195277 +0100
@@ -5316,34 +5316,14 @@  simplify_const_relational_operation (enu
 	{
 	case LT:
 	  /* Optimize abs(x) < 0.0.  */
-	  if (!HONOR_SNANS (mode)
-	      && (!INTEGRAL_MODE_P (mode)
-		  || (!flag_wrapv && !flag_trapv)))
-	    {
-	      if (INTEGRAL_MODE_P (mode)
-		  && (issue_strict_overflow_warning
-		      (WARN_STRICT_OVERFLOW_CONDITIONAL)))
-		warning (OPT_Wstrict_overflow,
-			 ("assuming signed overflow does not occur when "
-			  "assuming abs (x) < 0 is false"));
-	       return const0_rtx;
-	    }
+	  if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
+	    return const0_rtx;
 	  break;
 
 	case GE:
 	  /* Optimize abs(x) >= 0.0.  */
-	  if (!HONOR_NANS (mode)
-	      && (!INTEGRAL_MODE_P (mode)
-		  || (!flag_wrapv && !flag_trapv)))
-	    {
-	      if (INTEGRAL_MODE_P (mode)
-	          && (issue_strict_overflow_warning
-	    	  (WARN_STRICT_OVERFLOW_CONDITIONAL)))
-	        warning (OPT_Wstrict_overflow,
-			 ("assuming signed overflow does not occur when "
-			  "assuming abs (x) >= 0 is true"));
-	      return const_true_rtx;
-	    }
+	  if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
+	    return const_true_rtx;
 	  break;
 
 	case UNGE:
Index: gcc/testsuite/gcc.dg/torture/pr75964.c
===================================================================
--- /dev/null	2017-05-05 17:46:05.071578834 +0100
+++ gcc/testsuite/gcc.dg/torture/pr75964.c	2017-05-06 08:35:54.794072285 +0100
@@ -0,0 +1,28 @@ 
+/* { dg-do run } */
+
+typedef __UINT8_TYPE__ uint8_t;
+
+uint8_t __attribute__ ((noinline, noclone))
+abs8 (uint8_t x)
+{
+  if (x & 0x80)
+    x = -x;
+
+  if (x & 0x80)
+    x = 0x7f;
+
+  return x;
+}
+
+int
+main (void)
+{
+  if (abs8 (0) != 0
+      || abs8 (1) != 1
+      || abs8 (127) != 127
+      || abs8 (128) != 127
+      || abs8 (129) != 127
+      || abs8 (255) != 1)
+    __builtin_abort ();
+  return 0;
+}