fold-const.c (fold_truthop): Build a type for both the lhs and rhs and use it appropr...
authorCharles M. Hannum <root@ihack.net>
Fri, 26 Mar 1999 22:23:02 +0000 (15:23 -0700)
committerJeff Law <law@gcc.gnu.org>
Fri, 26 Mar 1999 22:23:02 +0000 (15:23 -0700)
        * fold-const.c (fold_truthop): Build a type for both the lhs and
        rhs and use it appropriately.

From-SVN: r26005

gcc/ChangeLog
gcc/fold-const.c

index 0e9486c7e2966f65fc9056524bf844497fbd120e..8822a94d096420d50270358a889e3f4681546c41 100644 (file)
@@ -65,6 +65,9 @@ Fri Mar 26 10:43:47 1999  Nick Clifton  <nickc@cygnus.com>
 
 Fri Mar 26 01:59:15 1999  "Charles M. Hannum" <root@ihack.net>
 
+       * fold-const.c (fold_truthop): Build a type for both the lhs and
+       rhs and use it appropriately.
+
        * fold-const.c (fold_truthop): Mask the lhs and rhs after merging
        adjacent bitfield references. 
 
index 93a0ae06ba97c383149e99cf0ab7785cb639fc3b..d96aa3c8279b62920e6a59c8b0c4d899198b4b69 100644 (file)
@@ -3710,7 +3710,7 @@ fold_truthop (code, truth_type, lhs, rhs)
   tree ll_mask, lr_mask, rl_mask, rr_mask;
   tree ll_and_mask, lr_and_mask, rl_and_mask, rr_and_mask;
   tree l_const, r_const;
-  tree type, result;
+  tree lntype, rntype, result;
   int first_bit, end_bit;
   int volatilep;
 
@@ -3848,7 +3848,7 @@ fold_truthop (code, truth_type, lhs, rhs)
 
   lnbitsize = GET_MODE_BITSIZE (lnmode);
   lnbitpos = first_bit & ~ (lnbitsize - 1);
-  type = type_for_size (lnbitsize, 1);
+  lntype = type_for_size (lnbitsize, 1);
   xll_bitpos = ll_bitpos - lnbitpos, xrl_bitpos = rl_bitpos - lnbitpos;
 
   if (BYTES_BIG_ENDIAN)
@@ -3857,19 +3857,19 @@ fold_truthop (code, truth_type, lhs, rhs)
       xrl_bitpos = lnbitsize - xrl_bitpos - rl_bitsize;
     }
 
-  ll_mask = const_binop (LSHIFT_EXPR, convert (type, ll_mask),
+  ll_mask = const_binop (LSHIFT_EXPR, convert (lntype, ll_mask),
                         size_int (xll_bitpos), 0);
-  rl_mask = const_binop (LSHIFT_EXPR, convert (type, rl_mask),
+  rl_mask = const_binop (LSHIFT_EXPR, convert (lntype, rl_mask),
                         size_int (xrl_bitpos), 0);
 
   if (l_const)
     {
-      l_const = convert (type, l_const);
+      l_const = convert (lntype, l_const);
       l_const = unextend (l_const,  ll_bitsize, ll_unsignedp, ll_and_mask);
       l_const = const_binop (LSHIFT_EXPR, l_const, size_int (xll_bitpos), 0);
       if (! integer_zerop (const_binop (BIT_AND_EXPR, l_const,
                                        fold (build1 (BIT_NOT_EXPR,
-                                                     type, ll_mask)),
+                                                     lntype, ll_mask)),
                                        0)))
        {
          warning ("comparison is always %d", wanted_code == NE_EXPR);
@@ -3881,12 +3881,12 @@ fold_truthop (code, truth_type, lhs, rhs)
     }
   if (r_const)
     {
-      r_const = convert (type, r_const);
+      r_const = convert (lntype, r_const);
       r_const = unextend (r_const, rl_bitsize, rl_unsignedp, rl_and_mask);
       r_const = const_binop (LSHIFT_EXPR, r_const, size_int (xrl_bitpos), 0);
       if (! integer_zerop (const_binop (BIT_AND_EXPR, r_const,
                                        fold (build1 (BIT_NOT_EXPR,
-                                                     type, rl_mask)),
+                                                     lntype, rl_mask)),
                                        0)))
        {
          warning ("comparison is always %d", wanted_code == NE_EXPR);
@@ -3919,6 +3919,7 @@ fold_truthop (code, truth_type, lhs, rhs)
 
       rnbitsize = GET_MODE_BITSIZE (rnmode);
       rnbitpos = first_bit & ~ (rnbitsize - 1);
+      rntype = type_for_size (rnbitsize, 1);
       xlr_bitpos = lr_bitpos - rnbitpos, xrr_bitpos = rr_bitpos - rnbitpos;
 
       if (BYTES_BIG_ENDIAN)
@@ -3927,29 +3928,30 @@ fold_truthop (code, truth_type, lhs, rhs)
          xrr_bitpos = rnbitsize - xrr_bitpos - rr_bitsize;
        }
 
-      lr_mask = const_binop (LSHIFT_EXPR, convert (type, lr_mask),
+      lr_mask = const_binop (LSHIFT_EXPR, convert (rntype, lr_mask),
                             size_int (xlr_bitpos), 0);
-      rr_mask = const_binop (LSHIFT_EXPR, convert (type, rr_mask),
+      rr_mask = const_binop (LSHIFT_EXPR, convert (rntype, rr_mask),
                             size_int (xrr_bitpos), 0);
 
       /* Make a mask that corresponds to both fields being compared.
         Do this for both items being compared.  If the masks agree,
-        and the bits being compared are in the same position, then
-        we can do this by masking both and comparing the masked
-        results.  */
+        and the bits being compared are in the same position, and the
+        types agree, then we can do this by masking both and comparing
+        the masked results.  */
       ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask, 0);
       lr_mask = const_binop (BIT_IOR_EXPR, lr_mask, rr_mask, 0);
       if (operand_equal_p (ll_mask, lr_mask, 0)
-         && lnbitsize == rnbitsize && xll_bitpos == xlr_bitpos)
+         && lnbitsize == rnbitsize && xll_bitpos == xlr_bitpos
+         && lntype == rntype)
        {
-         lhs = make_bit_field_ref (ll_inner, type, lnbitsize, lnbitpos,
+         lhs = make_bit_field_ref (ll_inner, lntype, lnbitsize, lnbitpos,
                                    ll_unsignedp || rl_unsignedp);
-         rhs = make_bit_field_ref (lr_inner, type, rnbitsize, rnbitpos,
+         rhs = make_bit_field_ref (lr_inner, rntype, rnbitsize, rnbitpos,
                                    lr_unsignedp || rr_unsignedp);
          if (! all_ones_mask_p (ll_mask, lnbitsize))
            {
-             lhs = build (BIT_AND_EXPR, type, lhs, ll_mask);
-             rhs = build (BIT_AND_EXPR, type, rhs, ll_mask);
+             lhs = build (BIT_AND_EXPR, lntype, lhs, ll_mask);
+             rhs = build (BIT_AND_EXPR, rntype, rhs, ll_mask);
            }
          return build (wanted_code, truth_type, lhs, rhs);
        }
@@ -3966,17 +3968,39 @@ fold_truthop (code, truth_type, lhs, rhs)
          || (ll_bitpos == rl_bitpos + rl_bitsize
              && lr_bitpos == rr_bitpos + rr_bitsize))
        {
-         lhs = make_bit_field_ref (ll_inner, type, ll_bitsize + rl_bitsize,
+         tree type;
+
+         lhs = make_bit_field_ref (ll_inner, lntype, ll_bitsize + rl_bitsize,
                                    MIN (ll_bitpos, rl_bitpos), ll_unsignedp);
+         rhs = make_bit_field_ref (lr_inner, rntype, lr_bitsize + rr_bitsize,
+                                   MIN (lr_bitpos, rr_bitpos), lr_unsignedp);
+
          ll_mask = const_binop (RSHIFT_EXPR, ll_mask,
                                 size_int (MIN (xll_bitpos, xrl_bitpos)), 0);
+         lr_mask = const_binop (RSHIFT_EXPR, lr_mask,
+                                size_int (MIN (xlr_bitpos, xrr_bitpos)), 0);
+
+         /* Convert to the smaller type before masking out unwanted bits.  */
+         type = lntype;
+         if (lntype != rntype)
+           {
+             if (lnbitsize > rnbitsize)
+               {
+                 lhs = convert (rntype, lhs);
+                 ll_mask = convert (rntype, ll_mask);
+                 type = rntype;
+               }
+             else if (lnbitsize < rnbitsize)
+               {
+                 rhs = convert (lntype, rhs);
+                 lr_mask = convert (lntype, lr_mask);
+                 type = lntype;
+               }
+           }
+
          if (! all_ones_mask_p (ll_mask, ll_bitsize + rl_bitsize))
            lhs = build (BIT_AND_EXPR, type, lhs, ll_mask);
 
-         rhs = make_bit_field_ref (lr_inner, type, lr_bitsize + rr_bitsize,
-                                   MIN (lr_bitpos, rr_bitpos), lr_unsignedp);
-         lr_mask = const_binop (RSHIFT_EXPR, lr_mask,
-                                size_int (MIN (xlr_bitpos, xrr_bitpos)), 0);
          if (! all_ones_mask_p (lr_mask, lr_bitsize + rr_bitsize))
            rhs = build (BIT_AND_EXPR, type, rhs, lr_mask);
 
@@ -4011,12 +4035,12 @@ fold_truthop (code, truth_type, lhs, rhs)
      reference we will make.  Unless the mask is all ones the width of
      that field, perform the mask operation.  Then compare with the
      merged constant.  */
-  result = make_bit_field_ref (ll_inner, type, lnbitsize, lnbitpos,
+  result = make_bit_field_ref (ll_inner, lntype, lnbitsize, lnbitpos,
                               ll_unsignedp || rl_unsignedp);
 
   ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask, 0);
   if (! all_ones_mask_p (ll_mask, lnbitsize))
-    result = build (BIT_AND_EXPR, type, result, ll_mask);
+    result = build (BIT_AND_EXPR, lntype, result, ll_mask);
 
   return build (wanted_code, truth_type, result,
                const_binop (BIT_IOR_EXPR, l_const, r_const, 0));