[Mesa-dev] [PATCH 4/4] clover: Sign-extend and zero-extend kernel arguments when required

Tom Stellard tom at stellard.net
Tue Jun 25 14:45:38 PDT 2013


From: Tom Stellard <thomas.stellard at amd.com>

---
 src/gallium/state_trackers/clover/core/kernel.cpp  | 23 +++++++++++++++++++---
 src/gallium/state_trackers/clover/core/kernel.hpp  |  4 +++-
 src/gallium/state_trackers/clover/core/module.hpp  | 10 +++++++++-
 .../state_trackers/clover/llvm/invocation.cpp      | 14 ++++++++++++-
 4 files changed, 45 insertions(+), 6 deletions(-)

diff --git a/src/gallium/state_trackers/clover/core/kernel.cpp b/src/gallium/state_trackers/clover/core/kernel.cpp
index d5b256b..3bee3d6 100644
--- a/src/gallium/state_trackers/clover/core/kernel.cpp
+++ b/src/gallium/state_trackers/clover/core/kernel.cpp
@@ -33,7 +33,7 @@ _cl_kernel::_cl_kernel(clover::program &prog,
    prog(prog), __name(name), exec(*this) {
    for (auto arg : args) {
       if (arg.type == module::argument::scalar)
-         this->args.emplace_back(new scalar_argument(arg.size));
+         this->args.emplace_back(new scalar_argument(arg.size, arg.ext_type));
       else if (arg.type == module::argument::global)
          this->args.emplace_back(new global_argument(arg.size));
       else if (arg.type == module::argument::local)
@@ -199,8 +199,9 @@ _cl_kernel::argument::allocate_input_space(exec_context &ctx) const {
    return offset;
 }
 
-_cl_kernel::scalar_argument::scalar_argument(size_t size) :
-   argument(size) {
+_cl_kernel::scalar_argument::scalar_argument(size_t size,
+                                            enum module::argument::ext_type ext_type) :
+   argument(size),  __ext_type(ext_type) {
 }
 
 void
@@ -216,6 +217,22 @@ void
 _cl_kernel::scalar_argument::bind(exec_context &ctx) {
    size_t offset = allocate_input_space(ctx);
    memcpy(ctx.input.data() + offset, v.data(), __size);
+
+   // Extend the value
+   bool has_sign = (ctx.input.data()[offset + __size - 1] & 0x80);
+   uint8_t ext_value;
+   if (__ext_type == module::argument::sext && has_sign) {
+      ext_value = 0xff;
+   } else {
+      ext_value = 0;
+   }
+
+   // XXX: I'm not sure the best way to decided what size to extend the value
+   // to.  For now we are extending everything to the the specified alignment
+   // size.
+   for (offset = offset + __size; offset < ctx.input.size(); ++offset) {
+      ctx.input.data()[offset] = ext_value;
+   }
 }
 
 void
diff --git a/src/gallium/state_trackers/clover/core/kernel.hpp b/src/gallium/state_trackers/clover/core/kernel.hpp
index 5f19657..0801ead 100644
--- a/src/gallium/state_trackers/clover/core/kernel.hpp
+++ b/src/gallium/state_trackers/clover/core/kernel.hpp
@@ -124,13 +124,15 @@ private:
 
    class scalar_argument : public argument {
    public:
-      scalar_argument(size_t size);
+      scalar_argument(size_t size,
+                      enum clover::module::argument::ext_type ext_type);
 
       virtual void set(size_t size, const void *value);
       virtual void bind(exec_context &ctx);
       virtual void unbind(exec_context &ctx);
 
    private:
+      enum clover::module::argument::ext_type __ext_type;
       std::vector<uint8_t> v;
    };
 
diff --git a/src/gallium/state_trackers/clover/core/module.hpp b/src/gallium/state_trackers/clover/core/module.hpp
index 88dfc9f..2d5186f 100644
--- a/src/gallium/state_trackers/clover/core/module.hpp
+++ b/src/gallium/state_trackers/clover/core/module.hpp
@@ -68,11 +68,19 @@ namespace clover {
             sampler
          };
 
-         argument(enum type type, size_t size) : type(type), size(size) { }
+         enum ext_type {
+            zext,
+            sext,
+            noext,
+         };
+
+         argument(enum type type, size_t size, enum ext_type ext_type = noext) :
+            type(type), size(size), ext_type(ext_type) { }
          argument() : type(scalar), size(0) { }
 
          type type;
          size_t size;
+         ext_type ext_type;
       };
 
       struct symbol {
diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp
index 2d115ed..362f02f 100644
--- a/src/gallium/state_trackers/clover/llvm/invocation.cpp
+++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp
@@ -321,7 +321,19 @@ namespace {
                      break;
                }
             } else {
-               args.push_back(module::argument(module::argument::scalar, arg_size));
+               unsigned attr_index = arg.getArgNo() + 1;
+               // Determine the argument's alignment.  When the SExt or ZExt
+               // attribute is set on a function, it means that the caller must
+               // extend the value to the appropriate size.  We will extend the
+               // value when binding it to a kernel.
+               // See _cl_kernel::scalar_argument::bind()
+               enum module::argument::ext_type ext_type = module::argument::noext;
+               if (kernel_func->getAttributes().hasAttribute(attr_index, llvm::Attribute::SExt)) {
+                  ext_type = module::argument::sext;
+               } else if (kernel_func->getAttributes().hasAttribute(attr_index, llvm::Attribute::ZExt)) {
+                  ext_type = module::argument::zext;
+               }
+               args.push_back(module::argument(module::argument::scalar, arg_size, ext_type));
             }
          }
 
-- 
1.7.11.4



More information about the mesa-dev mailing list