[Issue 3115] >>> and >>>= generate wrong code

d-bugmail at puremagic.com d-bugmail at puremagic.com
Thu Nov 19 01:36:14 PST 2009


http://d.puremagic.com/issues/show_bug.cgi?id=3115


Don <clugdbug at yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch
            Summary|Illegal optimization to     |>>> and >>>= generate wrong
                   |unsigned right shift (only  |code
                   |array)                      |


--- Comment #2 from Don <clugdbug at yahoo.com.au> 2009-11-19 01:36:12 PST ---
This is happening because the backend doesn't constant-fold >>> correctly.
Consequently, there's incorrect code in a few places because of this.
Sometimes OPshr means >>, sometimes it means >>>. The patch below changes it so
that OPshr always means >>>. OPashr means >> in the case where the value is
signed. The code in evalu8.c is the most important.

This patch may cause problems for DMC. Some of these changes might need to be
inside #if MARS/#endif blocks.

Some test cases: (test with both dmd bug.d and dmd -O bug.d).

long bar() {
    return -1L;
}

void main()
{
   long[1] b = void;
   b[0]= bar();

   assert((b[0]>>>2) == 0x3FFFFFFFFFFFFFFFL);
   assert((b[0]>>2) == 0xFFFFFFFFFFFFFFFFL);

   b[0] = -1L;
   assert((b[0]>>>2) == 0x3FFFFFFFFFFFFFFFL);
   assert((b[0]>>2) == 0xFFFFFFFFFFFFFFFFL);

   b[0] = -1L;
   b[0] >>>= 2;
   assert( (b[0]) == 0x3FFFFFFFFFFFFFFFL);
   b[0] = -1L;
   b[0] >>= 2;
   assert( (b[0]) == 0xFFFFFFFFFFFFFFFFL);
}

----


PATCH:

Index: backend/cod2.c
===================================================================
--- backend/cod2.c    (revision 252)
+++ backend/cod2.c    (working copy)
@@ -1847,8 +1847,8 @@
   oper = e->Eoper;

   // Do this until the rest of the compiler does OPshr/OPashr correctly
-  if (oper == OPshr)
-    oper = (uns) ? OPshr : OPashr;
+//  if (oper == OPshr)
+//    oper = (uns) ? OPshr : OPashr;

   switch (oper)
   {    case OPshl:
Index: backend/cod4.c
===================================================================
--- backend/cod4.c    (revision 252)
+++ backend/cod4.c    (working copy)
@@ -1367,10 +1367,9 @@
     *pretregs |= ALLREGS;

   // Do this until the rest of the compiler does OPshr/OPashr correctly
-  if (oper == OPshrass)
-    oper = (uns) ? OPshrass : OPashrass;
+//  if (oper == OPshrass)
+//    oper = (uns) ? OPshrass : OPashrass;

-
   // Select opcodes. op2 is used for msw for long shifts.

   switch (oper)
Index: backend/evalu8.c
===================================================================
--- backend/evalu8.c    (revision 252)
+++ backend/evalu8.c    (working copy)
@@ -1533,10 +1533,22 @@
     }
     else
     {   //printf("signed\n");
+        e->EV.Vllong = ((targ_ullong)l1) >> i2;
+    }
+    break;
+    
+    case OPashr:
+    if ((targ_ullong) i2 > sizeof(targ_ullong) * 8)
+        i2 = sizeof(targ_ullong) * 8;
+    if (tyuns(tym))
+    {   //printf("unsigned\n");
+        e->EV.Vullong = ((targ_ullong) l1) >> i2;
+    }
+    else
+    {   //printf("signed\n");
         e->EV.Vllong = l1 >> i2;
     }
     break;
-
     case OPpair:
     switch (tysize[tym])
     {
Index: e2ir.c
===================================================================
--- e2ir.c    (revision 252)
+++ e2ir.c    (working copy)
@@ -3007,7 +3007,7 @@

 elem *ShrAssignExp::toElem(IRState *irs)
 {
-    return toElemBin(irs,OPshrass);
+    return toElemBin(irs, tyuns(type->ty) ? OPshrass : OPashrass);
 }


@@ -3117,7 +3117,7 @@

 elem *ShrExp::toElem(IRState *irs)
 {
-    return toElemBin(irs,OPshr);
+    return toElemBin(irs, tyuns(type->ty) ? OPshr : OPashr);
 }

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list