This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix -(x > y) on ARM


This is somewhat embarrassing, since this bug has been there since about
1994 (ie circa gcc-2.5).  We were generating incorrect code for -(X >
Y).  We also had an incorrect test for -(X < 0) which meant that the
optimization was never applied.  Fixed with the patch below and new
testcase added.

R.

2007-06-23  Richard Earnshaw  <rearnsha@arm.com>

	PR target/31152
	* arm.md (negscc): Match the correct operand for optimized LT0 test.
	Remove optimization for GT.

	* gcc.c-torture/execute/20070623-1.c: New.


*** config/arm/arm.md	(revision 126009)
--- config/arm/arm.md	(local)
*************** (define_insn "*negscc"
*** 9423,9437 ****
     (clobber (reg:CC CC_REGNUM))]
    "TARGET_ARM"
    "*
!   if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
      return \"mov\\t%0, %1, asr #31\";
  
    if (GET_CODE (operands[3]) == NE)
      return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
  
-   if (GET_CODE (operands[3]) == GT)
-     return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
- 
    output_asm_insn (\"cmp\\t%1, %2\", operands);
    output_asm_insn (\"mov%D3\\t%0, #0\", operands);
    return \"mvn%d3\\t%0, #0\";
--- 9423,9434 ----
     (clobber (reg:CC CC_REGNUM))]
    "TARGET_ARM"
    "*
!   if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
      return \"mov\\t%0, %1, asr #31\";
  
    if (GET_CODE (operands[3]) == NE)
      return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
  
    output_asm_insn (\"cmp\\t%1, %2\", operands);
    output_asm_insn (\"mov%D3\\t%0, #0\", operands);
    return \"mvn%d3\\t%0, #0\";
*** testsuite/gcc.c-torture/execute/20070623-1.c	(revision 126009)
--- testsuite/gcc.c-torture/execute/20070623-1.c	(local)
***************
*** 0 ****
--- 1,41 ----
+ #include <limits.h>
+ 
+ int __attribute__((noinline)) nge(int a, int b) {return -(a >= b);}
+ int __attribute__((noinline)) ngt(int a, int b) {return -(a > b);}
+ int __attribute__((noinline)) nle(int a, int b) {return -(a <= b);}
+ int __attribute__((noinline)) nlt(int a, int b) {return -(a < b);}
+ int __attribute__((noinline)) neq(int a, int b) {return -(a == b);}
+ int __attribute__((noinline)) nne(int a, int b) {return -(a != b);}
+ int __attribute__((noinline)) ngeu(unsigned a, unsigned b) {return -(a >= b);}
+ int __attribute__((noinline)) ngtu(unsigned a, unsigned b) {return -(a > b);}
+ int __attribute__((noinline)) nleu(unsigned a, unsigned b) {return -(a <= b);}
+ int __attribute__((noinline)) nltu(unsigned a, unsigned b) {return -(a < b);}
+ 
+ 
+ int main()
+ {
+   if (nge(INT_MIN, INT_MAX) !=  0) abort();
+   if (nge(INT_MAX, INT_MIN) != -1) abort();
+   if (ngt(INT_MIN, INT_MAX) !=  0) abort();
+   if (ngt(INT_MAX, INT_MIN) != -1) abort();
+   if (nle(INT_MIN, INT_MAX) != -1) abort();
+   if (nle(INT_MAX, INT_MIN) !=  0) abort();
+   if (nlt(INT_MIN, INT_MAX) != -1) abort();
+   if (nlt(INT_MAX, INT_MIN) !=  0) abort();
+ 
+   if (neq(INT_MIN, INT_MAX) !=  0) abort();
+   if (neq(INT_MAX, INT_MIN) !=  0) abort();
+   if (nne(INT_MIN, INT_MAX) != -1) abort();
+   if (nne(INT_MAX, INT_MIN) != -1) abort();
+ 
+   if (ngeu(0, ~0U) !=  0) abort();
+   if (ngeu(~0U, 0) != -1) abort();
+   if (ngtu(0, ~0U) !=  0) abort();
+   if (ngtu(~0U, 0) != -1) abort();
+   if (nleu(0, ~0U) != -1) abort();
+   if (nleu(~0U, 0) !=  0) abort();
+   if (nltu(0, ~0U) != -1) abort();
+   if (nltu(~0U, 0) !=  0) abort();
+   
+   exit(0);
+ }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]