[compiler-rt] r204193 - Don't take short cuts trying to avoid conditionals. This leads to

Joerg Sonnenberger joerg at bec.de
Tue Mar 18 15:10:36 PDT 2014


Author: joerg
Date: Tue Mar 18 17:10:36 2014
New Revision: 204193

URL: http://llvm.org/viewvc/llvm-project?rev=204193&view=rev
Log:
Don't take short cuts trying to avoid conditionals. This leads to
negative shift amounts and/or shifts wider than the type. VAX traps on
the former, X86 and other platforms produce incorrect results on the
latter.

Modified:
    compiler-rt/trunk/lib/builtins/udivmoddi4.c
    compiler-rt/trunk/lib/builtins/udivmodti4.c

Modified: compiler-rt/trunk/lib/builtins/udivmoddi4.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/udivmoddi4.c?rev=204193&r1=204192&r2=204193&view=diff
==============================================================================
--- compiler-rt/trunk/lib/builtins/udivmoddi4.c (original)
+++ compiler-rt/trunk/lib/builtins/udivmoddi4.c Tue Mar 18 17:10:36 2014
@@ -143,43 +143,29 @@ __udivmoddi4(du_int a, du_int b, du_int*
             /* 2 <= sr <= n_udword_bits - 1
              * q.all = n.all << (n_udword_bits - sr);
              * r.all = n.all >> sr;
-             * if (sr == n_uword_bits)
-             * {
-             *     q.s.low = 0;
-             *     q.s.high = n.s.low;
-             *     r.s.high = 0;
-             *     r.s.low = n.s.high;
-             * }
-             * else if (sr < n_uword_bits)  // 2 <= sr <= n_uword_bits - 1
-             * {
-             *     q.s.low = 0;
-             *     q.s.high = n.s.low << (n_uword_bits - sr);
-             *     r.s.high = n.s.high >> sr;
-             *     r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
-             * }
-             * else              // n_uword_bits + 1 <= sr <= n_udword_bits - 1
-             * {
-             *     q.s.low = n.s.low << (n_udword_bits - sr);
-             *     q.s.high = (n.s.high << (n_udword_bits - sr)) |
-             *              (n.s.low >> (sr - n_uword_bits));
-             *     r.s.high = 0;
-             *     r.s.low = n.s.high >> (sr - n_uword_bits);
-             * }
              */
-            q.s.low =  (n.s.low << (n_udword_bits - sr)) &
-                     ((si_int)(n_uword_bits - sr) >> (n_uword_bits-1));
-            q.s.high = ((n.s.low << ( n_uword_bits - sr))                       &
-                     ((si_int)(sr - n_uword_bits - 1) >> (n_uword_bits-1))) |
-                     (((n.s.high << (n_udword_bits - sr))                     |
-                     (n.s.low >> (sr - n_uword_bits)))                        &
-                     ((si_int)(n_uword_bits - sr) >> (n_uword_bits-1)));
-            r.s.high = (n.s.high >> sr) &
-                     ((si_int)(sr - n_uword_bits) >> (n_uword_bits-1));
-            r.s.low =  ((n.s.high >> (sr - n_uword_bits))                       &
-                     ((si_int)(n_uword_bits - sr - 1) >> (n_uword_bits-1))) |
-                     (((n.s.high << (n_uword_bits - sr))                      |
-                     (n.s.low >> sr))                                         &
-                     ((si_int)(sr - n_uword_bits) >> (n_uword_bits-1)));
+            if (sr == n_uword_bits)
+            {
+                q.s.low = 0;
+                q.s.high = n.s.low;
+                r.s.high = 0;
+                r.s.low = n.s.high;
+            }
+            else if (sr < n_uword_bits)  // 2 <= sr <= n_uword_bits - 1
+            {
+                q.s.low = 0;
+                q.s.high = n.s.low << (n_uword_bits - sr);
+                r.s.high = n.s.high >> sr;
+                r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
+            }
+            else              // n_uword_bits + 1 <= sr <= n_udword_bits - 1
+            {
+                q.s.low = n.s.low << (n_udword_bits - sr);
+                q.s.high = (n.s.high << (n_udword_bits - sr)) |
+                           (n.s.low >> (sr - n_uword_bits));
+                r.s.high = 0;
+                r.s.low = n.s.high >> (sr - n_uword_bits);
+            }
         }
         else
         {
@@ -191,7 +177,7 @@ __udivmoddi4(du_int a, du_int b, du_int*
             /* 0 <= sr <= n_uword_bits - 1 or sr large */
             if (sr > n_uword_bits - 1)
             {
-               if (rem)
+                if (rem)
                     *rem = n.all;
                 return 0;
             }
@@ -199,24 +185,18 @@ __udivmoddi4(du_int a, du_int b, du_int*
             /* 1 <= sr <= n_uword_bits */
             /*  q.all = n.all << (n_udword_bits - sr); */
             q.s.low = 0;
-            q.s.high = n.s.low << (n_uword_bits - sr);
-            /* r.all = n.all >> sr;
-             * if (sr < n_uword_bits)
-             * {
-             *     r.s.high = n.s.high >> sr;
-             *     r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
-             * }
-             * else
-             * {
-             *     r.s.high = 0;
-             *     r.s.low = n.s.high;
-             * }
-             */
-            r.s.high = (n.s.high >> sr) &
-                     ((si_int)(sr - n_uword_bits) >> (n_uword_bits-1));
-            r.s.low = (n.s.high << (n_uword_bits - sr)) |
-                    ((n.s.low >> sr)                  &
-                    ((si_int)(sr - n_uword_bits) >> (n_uword_bits-1)));
+            if (sr == n_uword_bits)
+            {
+                q.s.high = n.s.low;
+                r.s.high = 0;
+                r.s.low = n.s.high;
+            }
+            else
+            {
+                q.s.high = n.s.low << (n_uword_bits - sr);
+                r.s.high = n.s.high >> sr;
+                r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
+            }
         }
     }
     /* Not a special case

Modified: compiler-rt/trunk/lib/builtins/udivmodti4.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/udivmodti4.c?rev=204193&r1=204192&r2=204193&view=diff
==============================================================================
--- compiler-rt/trunk/lib/builtins/udivmodti4.c (original)
+++ compiler-rt/trunk/lib/builtins/udivmodti4.c Tue Mar 18 17:10:36 2014
@@ -146,43 +146,29 @@ __udivmodti4(tu_int a, tu_int b, tu_int*
             /* 2 <= sr <= n_utword_bits - 1
              * q.all = n.all << (n_utword_bits - sr);
              * r.all = n.all >> sr;
-             * if (sr == n_udword_bits)
-             * {
-             *     q.s.low = 0;
-             *     q.s.high = n.s.low;
-             *     r.s.high = 0;
-             *     r.s.low = n.s.high;
-             * }
-             * else if (sr < n_udword_bits)  // 2 <= sr <= n_udword_bits - 1
-             * {
-             *     q.s.low = 0;
-             *     q.s.high = n.s.low << (n_udword_bits - sr);
-             *     r.s.high = n.s.high >> sr;
-             *     r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
-             * }
-             * else              // n_udword_bits + 1 <= sr <= n_utword_bits - 1
-             * {
-             *     q.s.low = n.s.low << (n_utword_bits - sr);
-             *     q.s.high = (n.s.high << (n_utword_bits - sr)) |
-             *              (n.s.low >> (sr - n_udword_bits));
-             *     r.s.high = 0;
-             *     r.s.low = n.s.high >> (sr - n_udword_bits);
-             * }
              */
-            q.s.low =  (n.s.low << (n_utword_bits - sr)) &
-                     ((di_int)(int)(n_udword_bits - sr) >> (n_udword_bits-1));
-            q.s.high = ((n.s.low << ( n_udword_bits - sr))                        &
-                     ((di_int)(int)(sr - n_udword_bits - 1) >> (n_udword_bits-1))) |
-                     (((n.s.high << (n_utword_bits - sr))                       |
-                     (n.s.low >> (sr - n_udword_bits)))                         &
-                     ((di_int)(int)(n_udword_bits - sr) >> (n_udword_bits-1)));
-            r.s.high = (n.s.high >> sr) &
-                     ((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1));
-            r.s.low =  ((n.s.high >> (sr - n_udword_bits))                        &
-                     ((di_int)(int)(n_udword_bits - sr - 1) >> (n_udword_bits-1))) |
-                     (((n.s.high << (n_udword_bits - sr))                       |
-                     (n.s.low >> sr))                                           &
-                     ((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1)));
+            if (sr == n_udword_bits)
+            {
+                q.s.low = 0;
+                q.s.high = n.s.low;
+                r.s.high = 0;
+                r.s.low = n.s.high;
+            }
+            else if (sr < n_udword_bits)  // 2 <= sr <= n_udword_bits - 1
+            {
+                q.s.low = 0;
+                q.s.high = n.s.low << (n_udword_bits - sr);
+                r.s.high = n.s.high >> sr;
+                r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
+            }
+            else              // n_udword_bits + 1 <= sr <= n_utword_bits - 1
+            {
+                q.s.low = n.s.low << (n_utword_bits - sr);
+                q.s.high = (n.s.high << (n_utword_bits - sr)) |
+                           (n.s.low >> (sr - n_udword_bits));
+                r.s.high = 0;
+                r.s.low = n.s.high >> (sr - n_udword_bits);
+            }
         }
         else
         {
@@ -199,27 +185,23 @@ __udivmodti4(tu_int a, tu_int b, tu_int*
                 return 0;
             }
             ++sr;
-            /* 1 <= sr <= n_udword_bits */
-            /* q.all = n.all << (n_utword_bits - sr); */
-            q.s.low = 0;
-            q.s.high = n.s.low << (n_udword_bits - sr);
-            /* r.all = n.all >> sr;
-             * if (sr < n_udword_bits)
-             * {
-             *     r.s.high = n.s.high >> sr;
-             *     r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
-             * }
-             * else
-             * {
-             *     r.s.high = 0;
-             *     r.s.low = n.s.high;
-             * }
+            /* 1 <= sr <= n_udword_bits
+             * q.all = n.all << (n_utword_bits - sr);
+             * r.all = n.all >> sr;
              */
-            r.s.high = (n.s.high >> sr) &
-                     ((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1));
-            r.s.low = (n.s.high << (n_udword_bits - sr)) |
-                    ((n.s.low >> sr)                   &
-                    ((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1)));
+            q.s.low = 0;
+            if (sr == n_udword_bits)
+            {
+                q.s.high = n.s.low;
+                r.s.high = 0;
+                r.s.low = n.s.high;
+            }
+            else
+            {
+                r.s.high = n.s.high >> sr;
+                r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
+                q.s.high = n.s.low << (n_udword_bits - sr);
+            }
         }
     }
     /* Not a special case





More information about the llvm-commits mailing list