[libclc] r184996 - libclc: implement rotate builtin

Tom Stellard thomas.stellard at amd.com
Wed Jun 26 11:21:13 PDT 2013


Author: tstellar
Date: Wed Jun 26 13:21:13 2013
New Revision: 184996

URL: http://llvm.org/viewvc/llvm-project?rev=184996&view=rev
Log:
libclc: implement rotate builtin

This implementation does a lot of bit shifting and masking. Suffice to say,
this is somewhat suboptimal... but it does look to produce correct results
(after the piglit tests were corrected for sign extension issues).

Someone who knows LLVM better than I could re-write this more efficiently.

Patch by: Aaron Watry

Added:
    libclc/trunk/generic/include/clc/integer/rotate.h
    libclc/trunk/generic/include/clc/integer/rotate.inc
    libclc/trunk/generic/lib/integer/rotate.cl
    libclc/trunk/generic/lib/integer/rotate.inc
Modified:
    libclc/trunk/generic/include/clc/clc.h
    libclc/trunk/generic/include/clc/integer/gentype.inc
    libclc/trunk/generic/lib/SOURCES

Modified: libclc/trunk/generic/include/clc/clc.h
URL: http://llvm.org/viewvc/llvm-project/libclc/trunk/generic/include/clc/clc.h?rev=184996&r1=184995&r2=184996&view=diff
==============================================================================
--- libclc/trunk/generic/include/clc/clc.h (original)
+++ libclc/trunk/generic/include/clc/clc.h Wed Jun 26 13:21:13 2013
@@ -63,6 +63,7 @@
 #include <clc/integer/abs.h>
 #include <clc/integer/abs_diff.h>
 #include <clc/integer/add_sat.h>
+#include <clc/integer/rotate.h>
 #include <clc/integer/sub_sat.h>
 
 /* 6.11.2 and 6.11.3 Shared Integer/Math Functions */

Modified: libclc/trunk/generic/include/clc/integer/gentype.inc
URL: http://llvm.org/viewvc/llvm-project/libclc/trunk/generic/include/clc/integer/gentype.inc?rev=184996&r1=184995&r2=184996&view=diff
==============================================================================
--- libclc/trunk/generic/include/clc/integer/gentype.inc (original)
+++ libclc/trunk/generic/include/clc/integer/gentype.inc Wed Jun 26 13:21:13 2013
@@ -1,3 +1,4 @@
+#define GENSIZE 8
 #define GENTYPE char
 #define UGENTYPE uchar
 #define SGENTYPE char
@@ -94,6 +95,9 @@
 #undef UGENTYPE
 #undef SGENTYPE
 
+#undef GENSIZE
+#define GENSIZE 16
+
 #define GENTYPE short
 #define UGENTYPE ushort
 #define SGENTYPE short
@@ -190,6 +194,9 @@
 #undef UGENTYPE
 #undef SGENTYPE
 
+#undef GENSIZE
+#define GENSIZE 32
+
 #define GENTYPE int
 #define UGENTYPE uint
 #define SGENTYPE int
@@ -286,6 +293,9 @@
 #undef UGENTYPE
 #undef SGENTYPE
 
+#undef GENSIZE
+#define GENSIZE 64
+
 #define GENTYPE long
 #define UGENTYPE ulong
 #define SGENTYPE long
@@ -382,4 +392,5 @@
 #undef UGENTYPE
 #undef SGENTYPE
 
+#undef GENSIZE
 #undef BODY

Added: libclc/trunk/generic/include/clc/integer/rotate.h
URL: http://llvm.org/viewvc/llvm-project/libclc/trunk/generic/include/clc/integer/rotate.h?rev=184996&view=auto
==============================================================================
--- libclc/trunk/generic/include/clc/integer/rotate.h (added)
+++ libclc/trunk/generic/include/clc/integer/rotate.h Wed Jun 26 13:21:13 2013
@@ -0,0 +1,2 @@
+#define BODY <clc/integer/rotate.inc>
+#include <clc/integer/gentype.inc>

Added: libclc/trunk/generic/include/clc/integer/rotate.inc
URL: http://llvm.org/viewvc/llvm-project/libclc/trunk/generic/include/clc/integer/rotate.inc?rev=184996&view=auto
==============================================================================
--- libclc/trunk/generic/include/clc/integer/rotate.inc (added)
+++ libclc/trunk/generic/include/clc/integer/rotate.inc Wed Jun 26 13:21:13 2013
@@ -0,0 +1 @@
+_CLC_OVERLOAD _CLC_DECL GENTYPE rotate(GENTYPE x, GENTYPE y);

Modified: libclc/trunk/generic/lib/SOURCES
URL: http://llvm.org/viewvc/llvm-project/libclc/trunk/generic/lib/SOURCES?rev=184996&r1=184995&r2=184996&view=diff
==============================================================================
--- libclc/trunk/generic/lib/SOURCES (original)
+++ libclc/trunk/generic/lib/SOURCES Wed Jun 26 13:21:13 2013
@@ -8,6 +8,7 @@ integer/abs_diff.cl
 integer/add_sat.cl
 integer/add_sat.ll
 integer/add_sat_impl.ll
+integer/rotate.cl
 integer/sub_sat.cl
 integer/sub_sat.ll
 integer/sub_sat_impl.ll

Added: libclc/trunk/generic/lib/integer/rotate.cl
URL: http://llvm.org/viewvc/llvm-project/libclc/trunk/generic/lib/integer/rotate.cl?rev=184996&view=auto
==============================================================================
--- libclc/trunk/generic/lib/integer/rotate.cl (added)
+++ libclc/trunk/generic/lib/integer/rotate.cl Wed Jun 26 13:21:13 2013
@@ -0,0 +1,4 @@
+#include <clc/clc.h>
+
+#define BODY <rotate.inc>
+#include <clc/integer/gentype.inc>

Added: libclc/trunk/generic/lib/integer/rotate.inc
URL: http://llvm.org/viewvc/llvm-project/libclc/trunk/generic/lib/integer/rotate.inc?rev=184996&view=auto
==============================================================================
--- libclc/trunk/generic/lib/integer/rotate.inc (added)
+++ libclc/trunk/generic/lib/integer/rotate.inc Wed Jun 26 13:21:13 2013
@@ -0,0 +1,35 @@
+/**
+ * Not necessarily optimal... but it produces correct results (at least for int)
+ * If we're lucky, LLVM will recognize the pattern and produce rotate
+ * instructions:
+ * http://llvm.1065342.n5.nabble.com/rotate-td47679.html
+ * 
+ * Eventually, someone should feel free to implement an llvm-specific version
+ */
+
+_CLC_OVERLOAD _CLC_DEF GENTYPE rotate(GENTYPE x, GENTYPE n){
+    //Try to avoid extra work if someone's spinning the value through multiple
+    //full rotations
+    n = n % (GENTYPE)GENSIZE;
+    
+    //Determine if we're doing a right or left shift on each component
+    //The actual shift algorithm is based on a rotate right
+    //e.g. a rotate of int by 5 bits becomes rotate right by 26 bits
+    //     and a rotate of int by -4 bits becomes rotate right by 4
+    GENTYPE amt = (n > (GENTYPE)0 ? (GENTYPE)GENSIZE - n : (GENTYPE)0 - n );
+    
+    //Calculate the bits that will wrap
+    GENTYPE mask = ( (GENTYPE)1 << amt ) - (GENTYPE)1;
+    GENTYPE wrapped_bits = x & mask;
+    
+    //Shift the input value right and then AND a mask that eliminates
+    //sign-extension interference
+    //if the rotate amount is 0, just use ~0 for a mask
+    GENTYPE se_mask = !amt ? ~((GENTYPE)0) : 
+        ( ( (GENTYPE)1 << ((GENTYPE)GENSIZE - amt) ) - (GENTYPE)1 );
+    GENTYPE unwrapped_bits = x >> amt;
+    unwrapped_bits &= se_mask;
+    
+    //Finally shift the input right after moving the wrapped bits into position
+    return unwrapped_bits | (wrapped_bits << ( (GENTYPE)GENSIZE - amt ) );
+}
\ No newline at end of file





More information about the cfe-commits mailing list