public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug middle-end/11264] New: LROTATE_EXPR/RROTATE_EXPR misexpanded by middle-end/back-end
@ 2003-06-20 13:43 mtodorov at alu dot hr
  2003-06-20 14:11 ` [Bug middle-end/11264] " pinskia at physics dot uc dot edu
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: mtodorov at alu dot hr @ 2003-06-20 13:43 UTC (permalink / raw)
  To: gcc-bugs

PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11264

           Summary: LROTATE_EXPR/RROTATE_EXPR misexpanded by middle-
                    end/back-end
           Product: gcc
           Version: 3.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: middle-end
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: mtodorov@alu.hr
                CC: frank@g-n-u.de,gcc-bugs@gcc.gnu.org
  GCC host triplet: i686-pc-linux-gnu

In a function RotateLeft/RotateRight of GNU Pascal
LROTATE_EXPR/RROTATE_EXPR is emitted as
tree node. Backend does wrong things when TYPE_PRECISION(op0) mod 8 <> 0
It rotates the bitfield on next power of 2 bits ... and some output
bits are lost. The size of rotation result is defined as the size of 1st
operand, when operation is RotateLeft(op, cnt);

I've spoken to Frank Heckenbach of GNU Pascal team, and he expressed
opinion the bug is back-end-related, and I should file a report.

Thank you for your help, so the GCC would be even better.

Mirsad Todorovac

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

The problem is I don't know of any gcc's function or operator using
LROTATE_EXPR or RROTATE_EXPR, so I think there will be a little problem
with explaining the bug, as direct example is hard to produce here so
you could reproduce it there (the bug is GCC-backed related, and the
example is in Pascal language, sorry)!

The simple program rotates left $801 for various rotate counts.
The output is, however, flawed:

-----------------------------------------------------------------------------
program testrl(output);
uses String;

const bitsize = 12;

type c12 = Cardinal attribute(Size = bitsize);
type c10 = Cardinal attribute(Size = 10);

var rec: packed record
           i, k: c12;
           j : c10;
         end;
begin
  with rec do
    begin
      i := (1 shl (bitsize - 1)) or 1;
      j := 0;
      repeat
        k := RotateLeft (i, j);
        WriteLn (Integer2StringBaseExt (i, 2, 16, False, False),
                 ' rol ', j:2, ' = ',
                 Integer2StringBaseExt (k, 2, 16, False, False));
        j := j + 1;
      until j = 32
    end
end.

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

OUTPUT:
---------------------------------------------------------------------------
magrf:~/pascal/gcc-3.2.1/gcc/p/test> a.out
0000100000000001 rol  0 = 0000100000000001
0000100000000001 rol  1 = 0000000000000010 (!)
0000100000000001 rol  2 = 0000000000000100 (!)
0000100000000001 rol  3 = 0000000000001000 (!)
0000100000000001 rol  4 = 0000000000010000 (!)
0000100000000001 rol  5 = 0000000000100001
0000100000000001 rol  6 = 0000000001000010
0000100000000001 rol  7 = 0000000010000100
0000100000000001 rol  8 = 0000000100001000
0000100000000001 rol  9 = 0000001000010000
0000100000000001 rol 10 = 0000010000100000
0000100000000001 rol 11 = 0000100001000000
0000100000000001 rol 12 = 0000100000000001
0000100000000001 rol 13 = 0000000000000010
0000100000000001 rol 14 = 0000000000000100
0000100000000001 rol 15 = 0000000000001000
0000100000000001 rol 16 = 0000000000010000
0000100000000001 rol 17 = 0000000000100001
0000100000000001 rol 18 = 0000000001000010
0000100000000001 rol 19 = 0000000010000100
0000100000000001 rol 20 = 0000000100001000
0000100000000001 rol 21 = 0000001000010000
0000100000000001 rol 22 = 0000010000100000
0000100000000001 rol 23 = 0000100001000000
0000100000000001 rol 24 = 0000100000000001
0000100000000001 rol 25 = 0000000000000010
0000100000000001 rol 26 = 0000000000000100
0000100000000001 rol 27 = 0000000000001000
0000100000000001 rol 28 = 0000000000010000
0000100000000001 rol 29 = 0000000000100001
0000100000000001 rol 30 = 0000000001000010
0000100000000001 rol 31 = 0000000010000100
magrf:~/pascal/gcc-3.2.1/gcc/p/test>

Notably 1000 0000 0001 rol 1 is 0000 0000 0011, but
back-end returned 2 (0000 0000 0010).

What we do to back-end is:
--------------------------------------------------------------------------
diff -x rts -x test -x doc -u p.20030507/predef.c p/predef.c
--- p.20030507/predef.c Fri May  2 13:40:33 2003
+++ p/predef.c  Tue Jun 17 18:19:29 2003
@@ -1693,6 +1693,39 @@
       }
     break;

+  case p_RotateLeft:
+  case p_RotateRight:
+  {
+    tree tmpval = NULL_TREE;
+    unsigned rotate_and_mask;
+
+    if (code == REAL_TYPE)
+      error ("argument 2 of `%s' must be of integer type", r_name);
+    else if (code2 == REAL_TYPE)
+      error ("argument 2 of `%s' must be of integer type", r_name);
+    if (length == 1)
+      val2 = integer_one_node;
+
+#if 0
+    switch (TYPE_PRECISION (type)) {
+        case 2: rotate_and_mask = 0x01; break;
+        case 4: rotate_and_mask = 0x03; break;
+        case 8: rotate_and_mask = 0x07; break;
+       case 16: rotate_and_mask = 0x0f; break;
+       case 32: rotate_and_mask = 0x1f; break;
+       case 64: rotate_and_mask = 0x3f; break;
+       default:
+          rotate_and_mask = 0;
+    }
+    if (rotate_and_mask)
+      tmpval = build_binary_op (BIT_AND_EXPR, val2, build_int_2
((unsigned)rotate_and_mask, 0), 0);
+    else
+#endif
+      tmpval = build_binary_op (TRUNC_MOD_EXPR, val2, build_int_2
((unsigned)TYPE_PRECISION (type), 0), 0);
+    retval = convert (type, build_binary_op ((r_num == p_RotateLeft) ?
LROTATE_EXPR : RROTATE_EXPR, val, tmpval, 0));
+  }
+    break;
+
   case p_FillChar:
     if (code3 != CHAR_TYPE)
       chk_dialect_1 ("non-`Char' values for argument 3 to `%s' are",
B_D_PASCAL, r_name);
diff -x rts -x test -x doc -u p.20030507/predef.h p/predef.h
--- p.20030507/predef.h Fri May  2 13:32:49 2003
+++ p/predef.h  Tue Jun 17 17:02:08 2003
@@ -292,6 +292,8 @@
 PREDEF_ROUTINE (Dec,                "-V,r|",         0,             B_D_M_PASCAL)
 PREDEF_ROUTINE (Succ,               "xv,r|",         ER_CONST,      ANY_PASCAL)
 PREDEF_ROUTINE (Pred,               "xv,r|",         ER_CONST,      ANY_PASCAL)
+PREDEF_ROUTINE (RotateLeft,         "xv,r|",          ER_CONST,     GNU_PASCAL)
+PREDEF_ROUTINE (RotateRight,        "xv,r|",          ER_CONST,     GNU_PASCAL)
 PREDEF_ROUTINE (Max,                "xww|",          ER_CONST,      GNU_PASCAL)
 PREDEF_ROUTINE (Min,                "xww|",          ER_CONST,      GNU_PASCAL)
 PREDEF_ROUTINE (Odd,                "bi|",           ER_CONST,      ANY_PASCAL)
-------------------------------------------------------------------------------


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug middle-end/11264] LROTATE_EXPR/RROTATE_EXPR misexpanded by middle-end/back-end
  2003-06-20 13:43 [Bug middle-end/11264] New: LROTATE_EXPR/RROTATE_EXPR misexpanded by middle-end/back-end mtodorov at alu dot hr
@ 2003-06-20 14:11 ` pinskia at physics dot uc dot edu
  2003-06-24 14:53 ` [Bug middle-end/11264] LROTATE_EXPR/RROTATE_EXPR misexpanded by middle-end/back-end for bitfields pinskia at physics dot uc dot edu
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: pinskia at physics dot uc dot edu @ 2003-06-20 14:11 UTC (permalink / raw)
  To: gcc-bugs

PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11264



------- Additional Comments From pinskia at physics dot uc dot edu  2003-06-20 14:10 -------
likely related to bug 7018, bug 6515, bug 6346, and bug 3325.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug middle-end/11264] LROTATE_EXPR/RROTATE_EXPR misexpanded by middle-end/back-end for bitfields
  2003-06-20 13:43 [Bug middle-end/11264] New: LROTATE_EXPR/RROTATE_EXPR misexpanded by middle-end/back-end mtodorov at alu dot hr
  2003-06-20 14:11 ` [Bug middle-end/11264] " pinskia at physics dot uc dot edu
@ 2003-06-24 14:53 ` pinskia at physics dot uc dot edu
  2003-07-05  2:16 ` pinskia at physics dot uc dot edu
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: pinskia at physics dot uc dot edu @ 2003-06-24 14:53 UTC (permalink / raw)
  To: gcc-bugs

PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11264


pinskia at physics dot uc dot edu changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|LROTATE_EXPR/RROTATE_EXPR   |LROTATE_EXPR/RROTATE_EXPR
                   |misexpanded by middle-      |misexpanded by middle-
                   |end/back-end                |end/back-end for bitfields


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug middle-end/11264] LROTATE_EXPR/RROTATE_EXPR misexpanded by middle-end/back-end for bitfields
  2003-06-20 13:43 [Bug middle-end/11264] New: LROTATE_EXPR/RROTATE_EXPR misexpanded by middle-end/back-end mtodorov at alu dot hr
  2003-06-20 14:11 ` [Bug middle-end/11264] " pinskia at physics dot uc dot edu
  2003-06-24 14:53 ` [Bug middle-end/11264] LROTATE_EXPR/RROTATE_EXPR misexpanded by middle-end/back-end for bitfields pinskia at physics dot uc dot edu
@ 2003-07-05  2:16 ` pinskia at physics dot uc dot edu
  2003-07-12 11:36 ` mtodorov at alu dot hr
  2003-11-02 22:34 ` pinskia at gcc dot gnu dot org
  4 siblings, 0 replies; 6+ messages in thread
From: pinskia at physics dot uc dot edu @ 2003-07-05  2:16 UTC (permalink / raw)
  To: gcc-bugs

PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11264


pinskia at physics dot uc dot edu changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|3.4                         |---


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug middle-end/11264] LROTATE_EXPR/RROTATE_EXPR misexpanded by middle-end/back-end for bitfields
  2003-06-20 13:43 [Bug middle-end/11264] New: LROTATE_EXPR/RROTATE_EXPR misexpanded by middle-end/back-end mtodorov at alu dot hr
                   ` (2 preceding siblings ...)
  2003-07-05  2:16 ` pinskia at physics dot uc dot edu
@ 2003-07-12 11:36 ` mtodorov at alu dot hr
  2003-11-02 22:34 ` pinskia at gcc dot gnu dot org
  4 siblings, 0 replies; 6+ messages in thread
From: mtodorov at alu dot hr @ 2003-07-12 11:36 UTC (permalink / raw)
  To: gcc-bugs

PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11264



------- Additional Comments From mtodorov at alu dot hr  2003-07-12 11:36 -------

Little progress:
================

We've traced it down to this code, gcc/expmed.c, that's unchanges until
gcc-20030709 snapshot (please see bellow):

NOTE that GET_MODE_BITSIZE (mode) when calculating suplementary shift count
for rotation emulation can get only information about the size of the
"container" of the variable.

NBAE, it appears to me that information about the number of bits of bitfield
is by now lost, and that the next power of two (8, 32, 64) is used
when calculating i.e.

      ROR (A, N) = A >> N | A << (C - N)

where C equals 8, 16, 32 or 64.

This is of course incorrect for bitfields of size i.e. 11, or 42, when
*they* need to be rotated.

/* If you might think rotations aren't useful, they appear to be. Having
   the ability that back-end generates a single rotate instruction instead
   of emulating the above is a great advantage.

   However NOTE that the above EMULATION isn't correct by definition for
   N >= bitsize, where we'd naturally expect things to go circular.

   This prevents front-end from emitting efficient rotation code for GPC,
   since we have to double the amount of work by adding another N MOD P
   (P = precision), which can expand in something less useful.

   Ideally, back-end should do this N MOD P for us, then we'd have it only
   when it's really needed, and ROR (A, N) for 8-bit, 16-bit or 32-bit
   A would truly be expanded into a single ror (or vice versa rol).

   Sorry if this was lenghty */ 

-------------------------------------------------------------------------------
          else if (methods == OPTAB_LIB_WIDEN)
            {
              /* If we have been unable to open-code this by a rotation,
                 do it as the IOR of two shifts.  I.e., to rotate A
                 by N bits, compute (A << N) | ((unsigned) A >> (C - N))
                 where C is the bitsize of A.

                 It is theoretically possible that the target machine might
                 not be able to perform either shift and hence we would
                 be making two libcalls rather than just the one for the
                 shift (similarly if IOR could not be done).  We will allow
                 this extremely unlikely lossage to avoid complicating the
                 code below.  */

              rtx subtarget = target == shifted ? 0 : target;
              rtx temp1;
              tree type = TREE_TYPE (amount);
              tree new_amount = make_tree (type, op1);
              tree other_amount
                = fold (build (MINUS_EXPR, type,
                               convert (type,
                                        build_int_2 (GET_MODE_BITSIZE (mode),
                                                     0)),
                               amount));

              shifted = force_reg (mode, shifted);

              temp = expand_shift (left ? LSHIFT_EXPR : RSHIFT_EXPR,
                                   mode, shifted, new_amount, subtarget, 1);
              temp1 = expand_shift (left ? RSHIFT_EXPR : LSHIFT_EXPR,
                                    mode, shifted, other_amount, 0, 1);
              return expand_binop (mode, ior_optab, temp, temp1, target,
                                   unsignedp, methods);
            }


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug middle-end/11264] LROTATE_EXPR/RROTATE_EXPR misexpanded by middle-end/back-end for bitfields
  2003-06-20 13:43 [Bug middle-end/11264] New: LROTATE_EXPR/RROTATE_EXPR misexpanded by middle-end/back-end mtodorov at alu dot hr
                   ` (3 preceding siblings ...)
  2003-07-12 11:36 ` mtodorov at alu dot hr
@ 2003-11-02 22:34 ` pinskia at gcc dot gnu dot org
  4 siblings, 0 replies; 6+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2003-11-02 22:34 UTC (permalink / raw)
  To: gcc-bugs

PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11264


pinskia at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
     Ever Confirmed|                            |1
           Keywords|                            |wrong-code
   Last reconfirmed|0000-00-00 00:00:00         |2003-11-02 22:34:11
               date|                            |


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2003-11-02 22:34 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-06-20 13:43 [Bug middle-end/11264] New: LROTATE_EXPR/RROTATE_EXPR misexpanded by middle-end/back-end mtodorov at alu dot hr
2003-06-20 14:11 ` [Bug middle-end/11264] " pinskia at physics dot uc dot edu
2003-06-24 14:53 ` [Bug middle-end/11264] LROTATE_EXPR/RROTATE_EXPR misexpanded by middle-end/back-end for bitfields pinskia at physics dot uc dot edu
2003-07-05  2:16 ` pinskia at physics dot uc dot edu
2003-07-12 11:36 ` mtodorov at alu dot hr
2003-11-02 22:34 ` pinskia at gcc dot gnu dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).