/* Given X an unsigned of 32 bits, and Y a bool. Try to translate optimizing
*
* Y = X >  2147483647;   to   Y = ((signed)X) < 0;
* Y = X >= 2147483648;   to   Y = ((signed)X) < 0;
*
* [ Another optimization is to Y = (X >> 31) ]
*
* The opposite (ELSE):
*
* Y = X <= 2147483647;   to   Y = ((signed)X) >= 0;
* Y = X <  2147483648;   to   Y = ((signed)X) >= 0;
*
* [ Another optimization is to Y = ((~X) >> 31) ]
*
* 2147483647=0x7FFFFFFF   2147483648=0x80000000
*
* The unsigned comparison is become to signed comparison.
*
* by J.C. Pizarro */

#include <stdio.h>

/* isnegative means greaterthan2millions */

int isnegative_1(unsigned int X) {
  int result; // Y is the conditional expression of if-else.
  if (X > 2147483647) result = 1;
  else                result = 0;
  return result;
}

int isnegative_2(unsigned int X) {
  int result; // Y is the conditional expression of if-else.
  if (X >= 2147483648U) result = 1;
  else                  result = 0;
  return result;
}

int isnegative_3(unsigned int X) {
  int result; // Y is the conditional expression of if-else.
  if (X <= 2147483647) result = 0;
  else                 result = 1;
  return result;
}

int isnegative_4(unsigned int X) {
  int result; // Y is the conditional expression of if-else.
  if (X < 2147483648U) result = 0;
  else                 result = 1;
  return result;
}

int isnegative_optimized_1(unsigned int X) {
  int result; // Y is the conditional expression of if-else.
  if (((signed)X) < 0) result = 1;
  else                 result = 0;
  return result;
}

int isnegative_optimized_2(unsigned int X) {
  int result; // Y is the conditional expression of if-else.
  if (((signed)X) >= 0) result = 0;
  else                  result = 1;
  return result;
}

int isnegative_optimized_3(unsigned int X) {
  int result; // Y is the conditional expression of if-else.
  if (X >> 31) result = 1;
  else         result = 0;
  return result;
}

int isnegative_optimized_4(unsigned int X) {
  int result; // Y is the conditional expression of if-else.
  if ((~X) >> 31) result = 0;
  else            result = 1;
  return result;
}

int are_equivalent_isnegative(unsigned int X) {
  int equiv=1,isneg;
  isneg = isnegative_1(X);
  equiv = equiv && (isnegative_2(X) == isneg);
  equiv = equiv && (isnegative_3(X) == isneg);
  equiv = equiv && (isnegative_4(X) == isneg);
  equiv = equiv && (isnegative_optimized_1(X) == isneg);
  equiv = equiv && (isnegative_optimized_2(X) == isneg);
  equiv = equiv && (isnegative_optimized_3(X) == isneg);
  equiv = equiv && (isnegative_optimized_4(X) == isneg);
  return equiv;
}

int main(int argc,char *argv[]) {
  long long X;
  int testOK=1;
  for (X=0LL;(X<=0x0FFFFFFFFLL)&&testOK;X++) {
     testOK = are_equivalent_isnegative((unsigned int)(X&0xFFFFFFFF));
  }
  if (testOK) printf("Full test of isnegative is PASSED.\n");
  else        printf("Full test of isnegative is FAILED.\n");
  return 0;
}

------------------------------------------------------------------------------
# gcc version 4.1.3 20070326 (prerelease)
Full test of isnegative is PASSED.

                     notl    %eax
                     shrl    $31, %eax
                     xorl    $1, %eax

                     IS WORSE THAN

                     shrl    $31, %eax

---------------------

                     xorl    %eax, %eax
                     cmpl    $0, 4(%esp)
                     sets    %al

                     IS WORSE THAN

                     movl    4(%esp), %eax
                     shrl    $31, %eax

------------------------------------------------------------------------------

J.C. Pizarro

Attachment: isnegative_20070410-1.tar.gz
Description: GNU Zip compressed data

Reply via email to