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]

PATCH: config/i386/i386.c(ix86_expand_int_movcc): Don't add when c{t,f} == 0


Apologies for the Lotus junk sent to the list from my last attempt.

Improve code generation from ix86_expand_int_movcc with a zero result value.
Bootstrapped on i586-pc-linux-gnu with no testsuite regressions.

2002-07-11  Rodney Brown  <rbrown64@csc.com.au>

      * config/i386/i386.c (ix86_expand_int_movcc): In the general case
      suppress addition when either ct or cf are zero.

--- config/i386/i386.c.bu     Sun Jun 23 20:00:09 2002
+++ config/i386/i386.c  Tue Jul  9 23:37:37 2002
@@ -8912,10 +8912,10 @@ ix86_expand_int_movcc (operands)

       if (!optimize_size && !TARGET_CMOVE)
      {
-       if (ct == 0)
+       if (cf == 0)
          {
-           ct = cf;
-           cf = 0;
+           cf = ct;
+           ct = 0;
            if (FLOAT_MODE_P (GET_MODE (ix86_compare_op0)))
            /* We may be reversing unordered compare to normal compare,
               that is not valid in general (we may convert non-trapping
@@ -8973,9 +8973,10 @@ ix86_expand_int_movcc (operands)
                             out,
                             gen_int_mode (cf - ct, mode),
                             out, 1, OPTAB_DIRECT);
-       out = expand_simple_binop (mode, PLUS,
-                            out, GEN_INT (ct),
-                            out, 1, OPTAB_DIRECT);
+       if (ct)
+         out = expand_simple_binop (mode, PLUS,
+                              out, GEN_INT (ct),
+                              out, 1, OPTAB_DIRECT);
        if (out != operands[0])
          emit_move_insn (operands[0], out);


Sizes of various binaries after the patch.

   text        data         bss         dec         hex     filename
3184287        2608      697888     3884783      3b46ef     expl/gcc/cc1
3184111        2608      697888     3884607      3b463f     exp3/gcc/cc1.bu   # 1st version of pch
3184031        2608      697888     3884527      3b45ef     exp3/gcc/cc1      # Current version
3956895        2680      705504     4665079      472ef7     expl/gcc/cc1plus
3956751        2680      705504     4664935      472e67     exp3/gcc/cc1plus
3438305        2720      717504     4158529      3f7441     expl/gcc/f771
3438033        2720      717504     4158257      3f7331     exp3/gcc/f771

Editted diff of -save-temp assembler from -O3 -fno-inlines of condexpr.c

--- ../gcc-3.2-experimental/condexpr.s    Thu Jul 11 08:58:00 2002
+++ ./condexpr.s  Thu Jul 11 00:47:38 2002
@@ -30,11 +30,9 @@ qc0_lt_9999_0:
      pushl %ebp
      movl  %esp, %ebp
      movsbl      8(%ebp),%eax
-     xorl  $-1, %eax
-     popl  %ebp
      sarl  $31, %eax
-     andl  $-9999, %eax
-     addl  $9999, %eax
+     popl  %ebp
+     andl  $9999, %eax
      ret
 .Lfe2:
      .size qc0_lt_9999_0,.Lfe2-qc0_lt_9999_0

...

@@ -4055,11 +3963,10 @@ qi_ne_0_9999:
      movl  12(%ebp), %eax
      cmpl  %eax, 8(%ebp)
      popl  %ebp
-     sete  %al
+     setne %al
      andl  $255, %eax
      decl  %eax
-     andl  $-9999, %eax
-     addl  $9999, %eax
+     andl  $9999, %eax
      ret
 .Lfe105:
      .size qi_ne_0_9999,.Lfe105-qi_ne_0_9999

...

@@ -11790,11 +11586,10 @@ quc_gt_0_n9999:
      movb  12(%ebp), %dl
      cmpb  %dl, 8(%ebp)
      popl  %ebp
-     setbe %al
+     seta  %al
      andl  $255, %eax
      decl  %eax
-     andl  $9999, %eax
-     subl  $9999, %eax
+     andl  $-9999, %eax
      ret
 .Lfe271:
      .size quc_gt_0_n9999,.Lfe271-quc_gt_0_n9999

...

@@ -15322,11 +15050,10 @@ qui_eq_0_n9999:
      movl  12(%ebp), %eax
      cmpl  %eax, 8(%ebp)
      popl  %ebp
-     setne %al
+     sete  %al
      andl  $255, %eax
      decl  %eax
-     andl  $9999, %eax
-     subl  $9999, %eax
+     andl  $-9999, %eax
      ret
 .Lfe351:
      .size qui_eq_0_n9999,.Lfe351-qui_eq_0_n9999
@@ -15340,11 +15067,10 @@ qui_eq_n9999_0:
      movl  12(%ebp), %eax
      cmpl  %eax, 8(%ebp)
      popl  %ebp
-     sete  %al
+     setne %al
      andl  $255, %eax
      decl  %eax
-     andl  $9999, %eax
-     subl  $9999, %eax
+     andl  $-9999, %eax
      ret
 .Lfe352:
      .size qui_eq_n9999_0,.Lfe352-qui_eq_n9999_0

...

@@ -21136,4 +20792,4 @@ main:
      call  exit
 .Lfe471:
      .size main,.Lfe471-main
-     .ident      "GCC: (GNU) 3.2 20020625 (experimental)"
+     .ident      "GCC: (GNU) 3.2 20020626 (experimental)"

condexpr.c source

--- Cut here
/* Attempt at testing conditional expressions, stepping through
  (value rel 0) and (value1 rel value2) for
  (signed char, unsigned char, short int, unsigned short int,
   int, unsigned int, long int, unsigned long int,
   long long int, unsigned long long int, double).
  For testing config/i386/i386.c (ix86_expand_int_movcc) optimizations
  needs to be compiled with -O3 -fno-inlines. For adequate coverage of
  the ix86_expand_int_movcc optimizations it needs more assert_q cases
  to cover the lea optimizations (constants differing by 1, 2, 3, 4, 5, 8, 9)
  etc.  It already is slow to compile.
  The choice of 9999 limits the usefulness for RISC machines with
  immediates of less than 14-15 bits.
 */
#define q(desc,a,b,rel,c,d)   \
int \
q##desc##_##b##_##c##_##d (a val) \
{ \
  return ((val rel 0) ? c : d); \
} \
\
int \
q##desc##_##b##_##d##_##c (a val) \
{ \
  return ((val rel 0) ? d : c); \
}

#define qq(desc,a,b,rel,c,d)  \
int \
q##desc##_##b##_##c##_##d (a val1, a val2) \
{ \
  return ((val1 rel val2) ? c : d); \
} \
\
int \
q##desc##_##b##_##d##_##c (a val1, a val2) \
{ \
  return ((val1 rel val2) ? d : c); \
}

#define q_u_typ(desc,typ,c,d) \
q (desc##0, typ, eq, ==, c, d) \
q (desc##0, typ, ne, !=, c, d) \
qq (desc, typ, lt, <, c, d) \
qq (desc, typ, eq, ==, c, d) \
qq (desc, typ, le, <=, c, d) \
qq (desc, typ, gt, >, c, d) \
qq (desc, typ, ne, !=, c, d) \
qq (desc, typ, ge, >=, c, d) \
\
void \
assert_q_u_##desc##_##c##_##d (void) \
{ \
  volatile typ q_zero = 0, q_one = 1; \
\
  if (q##desc##0_eq_##c##_##d (q_zero) != c \
      || q##desc##0_ne_##c##_##d (q_zero) != d \
      || q##desc##0_eq_##d##_##c (q_zero) != d \
      || q##desc##0_ne_##d##_##c (q_zero) != c \
      || q##desc##0_eq_##c##_##d (q_one) != d \
      || q##desc##0_ne_##c##_##d (q_one) != c \
      || q##desc##0_eq_##d##_##c (q_one) != c \
      || q##desc##0_ne_##d##_##c (q_one) != d \
\
      || q##desc##_lt_##c##_##d (q_zero, q_one) != c \
      || q##desc##_le_##c##_##d (q_zero, q_one) != c \
      || q##desc##_ne_##c##_##d (q_zero, q_one) != c \
      || q##desc##_lt_##d##_##c (q_zero, q_one) != d \
      || q##desc##_le_##d##_##c (q_zero, q_one) != d \
      || q##desc##_ne_##d##_##c (q_zero, q_one) != d \
      || q##desc##_eq_##c##_##d (q_zero, q_one) != d \
      || q##desc##_gt_##c##_##d (q_zero, q_one) != d \
      || q##desc##_ge_##c##_##d (q_zero, q_one) != d \
      || q##desc##_eq_##d##_##c (q_zero, q_one) != c \
      || q##desc##_gt_##d##_##c (q_zero, q_one) != c \
      || q##desc##_ge_##d##_##c (q_zero, q_one) != c \
\
      || q##desc##_gt_##c##_##d (q_one, q_zero) != c \
      || q##desc##_ne_##c##_##d (q_one, q_zero) != c \
      || q##desc##_ge_##c##_##d (q_one, q_zero) != c \
      || q##desc##_lt_##c##_##d (q_one, q_zero) != d \
      || q##desc##_eq_##c##_##d (q_one, q_zero) != d \
      || q##desc##_le_##c##_##d (q_one, q_zero) != d \
      || q##desc##_gt_##d##_##c (q_one, q_zero) != d \
      || q##desc##_ne_##d##_##c (q_one, q_zero) != d \
      || q##desc##_ge_##d##_##c (q_one, q_zero) != d \
      || q##desc##_lt_##d##_##c (q_one, q_zero) != c \
      || q##desc##_eq_##d##_##c (q_one, q_zero) != c \
      || q##desc##_le_##d##_##c (q_one, q_zero) != c \
\
      || q##desc##_eq_##c##_##d (q_one, q_one) != c \
      || q##desc##_le_##c##_##d (q_one, q_one) != c \
      || q##desc##_ge_##c##_##d (q_one, q_one) != c \
      || q##desc##_lt_##c##_##d (q_one, q_one) != d \
      || q##desc##_gt_##c##_##d (q_one, q_one) != d \
      || q##desc##_ne_##c##_##d (q_one, q_one) != d \
      || q##desc##_eq_##d##_##c (q_one, q_one) != d \
      || q##desc##_le_##d##_##c (q_one, q_one) != d \
      || q##desc##_ge_##d##_##c (q_one, q_one) != d \
      || q##desc##_lt_##d##_##c (q_one, q_one) != c \
      || q##desc##_gt_##d##_##c (q_one, q_one) != c \
      || q##desc##_ne_##d##_##c (q_one, q_one) != c) \
    abort (); \
}

#define q_s_typ(desc,typ,c,d) \
q (desc##0, typ, lt, <, c, d) \
q (desc##0, typ, eq, ==, c, d) \
q (desc##0, typ, le, <=, c, d) \
q (desc##0, typ, gt, >, c, d) \
q (desc##0, typ, ne, !=, c, d) \
q (desc##0, typ, ge, >=, c, d) \
qq (desc, typ, lt, <, c, d) \
qq (desc, typ, eq, ==, c, d) \
qq (desc, typ, le, <=, c, d) \
qq (desc, typ, gt, >, c, d) \
qq (desc, typ, ne, !=, c, d) \
qq (desc, typ, ge, >=, c, d) \
\
void \
assert_q_s_##desc##_##c##_##d (void) \
{ \
  volatile typ q_zero = 0, q_one = 1; \
\
  if (q##desc##0_eq_##c##_##d (q_zero) != c \
      || q##desc##0_le_##c##_##d (q_zero) != c \
      || q##desc##0_ge_##c##_##d (q_zero) != c \
      || q##desc##0_lt_##c##_##d (q_zero) != d \
      || q##desc##0_gt_##c##_##d (q_zero) != d \
      || q##desc##0_ne_##c##_##d (q_zero) != d \
      || q##desc##0_eq_##d##_##c (q_zero) != d \
      || q##desc##0_le_##d##_##c (q_zero) != d \
      || q##desc##0_ge_##d##_##c (q_zero) != d \
      || q##desc##0_lt_##d##_##c (q_zero) != c \
      || q##desc##0_gt_##d##_##c (q_zero) != c \
      || q##desc##0_ne_##d##_##c (q_zero) != c \
      || q##desc##0_lt_##c##_##d (q_one) != d \
      || q##desc##0_eq_##c##_##d (q_one) != d \
      || q##desc##0_le_##c##_##d (q_one) != d \
      || q##desc##0_gt_##c##_##d (q_one) != c \
      || q##desc##0_ne_##c##_##d (q_one) != c \
      || q##desc##0_ge_##c##_##d (q_one) != c \
      || q##desc##0_lt_##d##_##c (q_one) != c \
      || q##desc##0_eq_##d##_##c (q_one) != c \
      || q##desc##0_le_##d##_##c (q_one) != c \
      || q##desc##0_gt_##d##_##c (q_one) != d \
      || q##desc##0_ne_##d##_##c (q_one) != d \
      || q##desc##0_ge_##d##_##c (q_one) != d \
\
      || q##desc##_lt_##c##_##d (q_zero, q_one) != c \
      || q##desc##_le_##c##_##d (q_zero, q_one) != c \
      || q##desc##_ne_##c##_##d (q_zero, q_one) != c \
      || q##desc##_lt_##d##_##c (q_zero, q_one) != d \
      || q##desc##_le_##d##_##c (q_zero, q_one) != d \
      || q##desc##_ne_##d##_##c (q_zero, q_one) != d \
      || q##desc##_eq_##c##_##d (q_zero, q_one) != d \
      || q##desc##_gt_##c##_##d (q_zero, q_one) != d \
      || q##desc##_ge_##c##_##d (q_zero, q_one) != d \
      || q##desc##_eq_##d##_##c (q_zero, q_one) != c \
      || q##desc##_gt_##d##_##c (q_zero, q_one) != c \
      || q##desc##_ge_##d##_##c (q_zero, q_one) != c \
\
      || q##desc##_gt_##c##_##d (q_one, q_zero) != c \
      || q##desc##_ne_##c##_##d (q_one, q_zero) != c \
      || q##desc##_ge_##c##_##d (q_one, q_zero) != c \
      || q##desc##_lt_##c##_##d (q_one, q_zero) != d \
      || q##desc##_eq_##c##_##d (q_one, q_zero) != d \
      || q##desc##_le_##c##_##d (q_one, q_zero) != d \
      || q##desc##_gt_##d##_##c (q_one, q_zero) != d \
      || q##desc##_ne_##d##_##c (q_one, q_zero) != d \
      || q##desc##_ge_##d##_##c (q_one, q_zero) != d \
      || q##desc##_lt_##d##_##c (q_one, q_zero) != c \
      || q##desc##_eq_##d##_##c (q_one, q_zero) != c \
      || q##desc##_le_##d##_##c (q_one, q_zero) != c \
\
      || q##desc##_eq_##c##_##d (q_one, q_one) != c \
      || q##desc##_le_##c##_##d (q_one, q_one) != c \
      || q##desc##_ge_##c##_##d (q_one, q_one) != c \
      || q##desc##_lt_##c##_##d (q_one, q_one) != d \
      || q##desc##_gt_##c##_##d (q_one, q_one) != d \
      || q##desc##_ne_##c##_##d (q_one, q_one) != d \
      || q##desc##_eq_##d##_##c (q_one, q_one) != d \
      || q##desc##_le_##d##_##c (q_one, q_one) != d \
      || q##desc##_ge_##d##_##c (q_one, q_one) != d \
      || q##desc##_lt_##d##_##c (q_one, q_one) != c \
      || q##desc##_gt_##d##_##c (q_one, q_one) != c \
      || q##desc##_ne_##d##_##c (q_one, q_one) != c) \
      abort (); \
}

#define instantiate_q(a,b) \
q_s_typ (c, signed char, a, b) \
q_u_typ (uc, unsigned char, a, b) \
q_s_typ (s, short int, a, b) \
q_u_typ (us, unsigned short int, a, b) \
q_s_typ (i, int, a, b) \
q_u_typ (ui, unsigned int, a, b) \
q_s_typ (l, long int, a, b) \
q_u_typ (ul, unsigned long int, a, b) \
q_s_typ (ll, long long int, a, b) \
q_u_typ (ull, unsigned long long int, a, b) \
q_s_typ (d, double, a, b)


#define assert_q_u_typ(desc,typ,a,b)      assert_q_u_##desc##_##a##_##b ()
#define assert_q_s_typ(desc,typ,a,b)      assert_q_s_##desc##_##a##_##b ()

#define assert_q(a,b) \
  assert_q_s_typ (c, signed char, a, b); \
  assert_q_u_typ (uc, unsigned char, a, b); \
  assert_q_s_typ (s, short int, a, b); \
  assert_q_u_typ (us, unsigned short int, a, b); \
  assert_q_s_typ (i, int, a, b); \
  assert_q_u_typ (ui, unsigned int, a, b); \
  assert_q_s_typ (l, long int, a, b); \
  assert_q_u_typ (ul, unsigned long int, a, b); \
  assert_q_s_typ (ll, long long int, a, b); \
  assert_q_u_typ (ull, unsigned long long int, a, b); \
  assert_q_s_typ (d, double, a, b)

const int n9999 = -9999;

instantiate_q (0, 9999)
instantiate_q (0, n9999)

int
main (void)
{
  assert_q (0, 9999);
  assert_q (0, n9999);
  exit(0);
}



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