[Beignet] [PATCH V2] GBE: fix a corner case when allocate registers for local buffer.

Zhigang Gong zhigang.gong at intel.com
Tue Dec 17 22:36:32 PST 2013


We use a simple way to find a instruction which refer to the local
data. Then we can identify the parent function. We found there is
a corner case that the instruction may be modified at the optimization
pass, for example the GVN pass. When all of the instruction's operand
are modified to constant, then the whole instruction seens to be a
constant either.

If that is the case, we fail to get a valid instruction and may trigger
an assert. This patch change to check another use of the local data to
avoid this assert.

Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
---
 backend/src/llvm/llvm_gen_backend.cpp |   17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index 1316d4b..5755ac4 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -1387,15 +1387,18 @@ namespace gbe
         uint32_t padding = getPadding(oldSlm*8, align);
 
         f.setSLMSize(oldSlm + padding/8 + getTypeByteSize(unit, ty));
-        const Value * parent = cast<Value>(&v);
+        const Value * val = cast<Value>(&v);
         // local variable can only be used in one kernel function. so, don't need to check its all uses.
         // loop through the Constant to find the instruction that use the global variable
-        do {
-          Value::const_use_iterator it = parent->use_begin();
-          parent = cast<Value>(*it);
-        } while(isa<Constant>(parent));
-
-        const Instruction * insn = cast<Instruction>(parent);
+        const Instruction * insn = NULL;
+        for( Value::const_use_iterator innerIt = val->use_begin(), prev = val->use_begin();
+             innerIt != prev->use_end() && insn == NULL;
+             prev = innerIt, innerIt = innerIt->use_begin() )
+          for( Value::const_use_iterator it = innerIt;
+               it != val->use_end() && insn == NULL;
+               it++)
+            insn = dyn_cast<Instruction>(*it);
+        GBE_ASSERT(insn && "Can't find a valid reference instruction for local variable.");
         const BasicBlock * bb = insn->getParent();
         const Function * func = bb->getParent();
         if(func != &F) continue;
-- 
1.7.9.5



More information about the Beignet mailing list